Powered by CodeIgniter

Уроки

(19)
9
11 голосов
Учиться, учиться и еще раз учиться — развитие личности идет таким путем.
Новая тема оформления системы управления сайтами cogearКаждый день теплого лета дарит все новые радости. Стоит сказать, что разработка второй версии cogear вступила в активную фазу, и то что получается несказанно радует вашего скромного слугу. Тем временем работа с первой версией cogear тоже приносит много положительных эмоций, в силу легкости создания своих шестеренок и тем оформления. Как раз о последнем мы с вами сейчас и поговорим, а заодно позвольте представить вам новую тему оформления движка по-умолчанию.

Цель

Как всегда, прежде чем за что-то браться, просто необходимо поставить задачу.
Нам нужна современная тема оформления, которую можно будет легко настроить под себя, поменяв несколько изображений (фон, логотип и т.д.) на собственные.

Ресурсы

Откровенно скажу, что не являюсь ярым поклонником резиновой верстки, ибо иногда она вызывает чувство неуверенности в сайте, поэтому в данном случае мы выберем фиксированную ширину, а вместе с ней и замечательный CSS-фреймворк 960.gs.

Структура папок

Она идентична исходной. Старая тема просто переименована в simple.
/templates/default/
css/ — стили
js/ — скрипты
header.tpl — шапка
footer.tpl — подвал
images/ — изображения
...
gears/ — переопределение скриптов и стилей шестеренок
form/
... — см. структуру реальной папки
global/
...
search/
...
sidebar/
css/
widget.css — переопределение стилей
templates/
sidebar.tpl — переопределение шаблона
Все как обычно. Определяем глобальные части шаблона, меняем стили, доводим до ума настройкой переопределенных стилей и шаблонов шестеренок.

Обратите внимание

Хотелось бы обратить особое внимание на некоторые вещи.

960.gs

Кидаете три файла (960.css, text.css, reset.css) в папку со стилями темы, и они подхватываются движком автоматически.
В другом движке пришлось бы прописывать пути к файлам вручную. Мелочь, но как приятно…
Если кто не в курсе — все стили и скрипты автоматически склеиваются в нужном порядке в два отдельных файла. Таким образом пользователь расходует под одному запросу на стили и скрипты. Также стоит отметить, что при внесении изменений с любые скрипты и стили, выходные скомпилированные файлы обновляются автоматически.
960.gs позволяет легко и просто создать модульную сетку при помощи div-ов c нужными классами.
Визуально в ширину страница делится на 12 (16, 24 —при желании) секторов, и вы просто создаете div-ы, отмечая их нужными классами(по количеству занимаемых блоков в ширину — «grid_3»,«grid_12», например), а фреймворк автоматически делает за вас кросс-браузерную разметку.
Рекомендую посетить официальный сайт фреймворка, если кто с ним еще не знаком, и приобщиться к этому чуду. Также есть резиновая версия, на ее тему можно погуглить, добавив к называнию фреймворка суффикс «fluid».

В общем виде, верстка страницы блога под 960.gs выглядит так:
... <!-- Класс обертка идет сверху --> <div class="container_12"> <div class="grid_12" id="header">...</div> <!-- Линейка закончилась, новая "строка" берется автоматически --> <div class="grid_8" id="content">...</div> <div class="grid_4" id="sidebar">...</div> <!-- Линейка закончилась, новая "строка" берется автоматически --> <div class="grid_12"></div> </div> ...

Переменная шаблона в стилях

Вы можете установить переменную, которая при парсинге стиля будет заменена на путь к шаблону двумя способами, кому как удобнее:
body{ background: url({$tpl}image/background.jpg) repeat-x top left; background: url(../image/background.jpg) repeat-x top left; }

Листинги файлов

header.tpl

{* You can use {include file="global header"} to include default site header *} {* header *} <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ru"> <head> <title>{$meta.title}</title> <meta content="text/html; charset={$CI->site->encoding|default:'utf-8'}" http-equiv="Content-Type"> <link rel="shortcut icon" href="http://{$CI->site->url}/favicon.ico" /> {$meta.info} {$css} {$scripts} {$extra} <script type="text/javascript"> url = 'http://{$CI->uri->url}{if $CI->uri->subdir}/{$CI->uri->subdir}/{/if}'; </script> </head> {* /header *} <body> <div id="cpanel-holder">{$cpanel}</div> <div class="container_12"> <div id="header" class="grid_12"> <div class="grid_4 alpha"> <a href="http://{$meta.url}/"><img src="{$tpl}/images/logo.png" border="0" align="left" alt="{$meta.title}" width="300" height="95" id="logo"/></a> </div> <div class="grid_8 omega"> </div> </div> [<div class="grid_12 alpha omega">{$menu.main}</div>] <div id="wrapper" class="grid_12"> {if $twitter} <div id="twitter"> <div id="birdy"><a href="http://twitter.com/{$CI->gears->twitter->login}"><img src="{$tpl}images/twitter.png" alt="Twitter" width="48" height="48"/></a></div> <div id="tweet"> <div id="tweet-open"> </div> <div id="tweet-body">{$twitter}</div> <div id="tweet-close"> </div> </div> </div> {/if} <div id="content" class="grid_{if $sidebar}8{else}12 omega{/if} alpha">

footer.tpl

</div> {$sidebar} <div id="statistics" class="centered grid_8 alpha"> <span class="counter"> </span> </div> <div id="footer" class="grid_4 omega"> <p><a href="http://cogear.ru"><img src="http://cogear.ru/uploads/cogear-powered.gif" alt="Работает на cogear" width="70" height="19" align="absmiddle"></a> © {?date('Y')} <small>Использование памяти: {$mem_usage} {if !empty($CI->db)}Запросов к базе данных: {? count($CI->db->queries)} {/if}Запросов в кеш: {? $CI->cache->counter} Время работы: {? $CI->benchmark->elapsed_time()}</small></p> </div> </div> </div> {* You can use {include file="global footer"} to include default site header *} {* footer *} </body> </html> {* /footer *}

gears/global/templates/cpanel.tpl

{if !$CI->user->is_logged} <div class="hidden"> <div id="login-form"> <form method="post" id="quick-login" action="/user/login/"> <div class="field"> <label for="login"> Электропочта или логин * </label> <input type="text" class="text validate['required']" name="login" id="login"> </div> <div class="field"> <label for="password"> Пароль * </label> <input type="password" size="25" class="password validate['required']" name="password" id="password"> </div> <div class="field"> <label for="save_cookies" class="small"> Запомнить? </label> <input type="checkbox" class="checkbox " name="save_cookies" id="save_cookies">     <a href="/user/lostpassword/">Забыли пароль?</a>     <a href="/user/register/">Регистрация</a>     <a href="/user/openid/"><img height="32" width="32" align="absmiddle" alt="OpenID" src="/gears/user/img/openid_small.png"></a> </div> <span class="button"> <input type="submit" onclick="$('quick-login').getElement('input[name=action]').set('value',this.name);" value="Войти" name="submit" id="submit"> </span> </form> </div> </div> {/if} <ul id="cpanel"{if $CI->user->is_logged} class="authorized"{/if}> {if $CI->user->is_logged} {foreach $elements as $elem} <li [id="{$elem.id}" ][class="{$elem.class}"] width="{! if(isset($elem.width)) $elem.width = str_replace('%','',$elem.width)}{$elem.width|default:'10'|}%" {if $elem.align}align="{$elem.align}"{/if}> {if $elem.link}<a href="{$elem.link}" class="no-decoration">{/if} {if $elem.type == 'icon'} <img src="{$elem.data}" {if $elem.data_class}class="{$elem.data_class}"{/if}/> {else} <span class="cpanel-number">{$elem.data}</span> {/if} {if $elem.link}</a>{/if} {if $elem.link}<a href="{$elem.link}">{/if} {$elem.text} {if $elem.link}</a>{/if} </li> {/foreach} {else} <li><a href="/user/login/" onclick="loader.elem('login-form',640,480);return false;">войти</a></li> <li><a href="/user/register/">зарегистрироваться</a></li> {/if} </ul>

gears/global/css/cpanel.css

div#cpanel-holder{ height: 25px; background: url({$tpl}images/cpanel.png) repeat-x top left; position: fixed; top: 0px; left: 0px; width: 100%; -moz-box-shadow: 0px 1px 3px #2CCAFF; -webkit-box-shadow: 0px 1px 3px #2CCAFF; box-shadow: 0px 1px 3px #2CCAFF; z-index: 1000; opacity: 0.85; } ul#cpanel{ height: 25px; color: #fff; padding: 0; margin: 0; } ul#cpanel li.no-image{ list-style: none; } ul#cpanel.authorized li:first-child{ background: none; padding-left: 4px; } ul#cpanel li{ padding: 1px 8px 0px 16px; margin: 0; height: 35px; float: left; vertical-align: top; list-style: none; background: url({$tpl}images/cpanel-li.png) no-repeat top left; text-shadow: 1px 1px 2px #000; } ul#cpanel li span{ text-shadow: 1px 0px 2px #000; } #cpanel-charge .cpanel-number{ text-shadow: 1px 1px 2px #FFF; } ul#cpanel li a, ul#cpanel li div, ul#cpanel li span{ color: #fff; text-decoration: none; vertical-align: top; position: static; top: 3px; border-bottom: 1px solid transparent; } ul#cpanel li a:hover{ border-bottom: 1px dotted #fff; } ul#cpanel li a.no-decoration, ul#cpanel li a.no-decoration:hover{ border: none; } ul#cpanel li img{ margin: 4px 0 0 0; } ul#cpanel li img.avatar{ margin: 1px 0 0 0; } ul#cpanel li span.cpanel-number{ font-size: 1.2em; }

gears/sidebar/templates/sidebar.tpl

{if empty($disabled)} <div id="sidebar" class="grid_4 omega"> {foreach $widgets as $widget} <div {if $widget.config.nobg}style="background:none;"{/if} class="widget{if $widget.config.class} {$widget.config.class}{/if}" {if $widget.config.id}id="{$widget.config.id}"{/if}> {if !isset($widget.config.notitle)}<div class="widget-header"><h3>{if !empty($widget.config.title)}{$widget.config.title}{else}{$widget.title}{/if}</h3></div>{/if} <div class="widget-content">{$widget.content}</div> </div> {/foreach} </div> {/if}

gears/sidebar/css/widget.css

#sidebar{ padding-top: 30px; } #sidebar .widget{ width: 290px; } #sidebar .widget .widget-header{ background: #636363 url({$tpl}images/grayscale-bg.png) repeat-x top left; border: 1px solid #636363 ; -moz-border-radius-topleft: 8px; -moz-border-radius-topright: 8px; -webkit-border-top-right-radius: 8px; -webkit-border-top-left-radius: 8px; border-radius-top-left: 8px; border-radius-top-right: 8px; } #sidebar .widget .widget-header h3{ text-shadow: 0 -1px 0 #3F3F3F; font-size: 1em; font-family: "Lucida Grande",Verdana,Arial,sans-serif; padding: 5px 10px; margin: 0; color: #FFF; } #sidebar .widget .widget-content{ padding: 10px 10px; margin: 0 0 10px; font-size: 1.123em; border-left: 1px solid #DFDFDF ; border-right: 1px solid #DFDFDF ; border-bottom: 1px solid #DFDFDF ; -moz-border-radius-bottomleft: 8px; -moz-border-radius-bottomright: 8px; -webkit-border-bottom-right-radius: 8px; -webkit-border-bottom-left-radius: 8px; border-radius-bottomleft: 8px; border-radius-bottomright: 8px; } #sidebar .white{ background: #FFFFFF; width: 290px; padding: 0; border: none; box-shadow: none; -moz-box-shadow: none; } #sidebar .white .widget-header, #sidebar .white .widget-content{ padding: 0; border: none; } #sidebar .noborder, #sidebar .no-border{ border: none; } #sidebar .widget h1{ margin: 0 0 5px 0; font-size: 1.4em; font-weight: normal; } #sidebar .no-padding{ padding: 0; }

gears/search/css/search_widget.css

#search_widget input#query{ border: none; background: url({$tpl}/images/search.png) no-repeat top left; width: 200px; min-width: 200px; max-width: 210px; height: 34px; padding: 0 0 2px 32px; font-size: 1em; } #search_widget input#search-submit{ border: none; background: url({$tpl}/images/search.png) no-repeat right -34px; cursor: pointer; text-indent: -9999px; height: 34px; width: 54px; line-height: 36px; } #search_widget input#search-submit:hover{ background: url({$tpl}/images/search.png) no-repeat right -68px; } #search_widget div.field{ margin: 0; padding: 0; }

gears/form/css/grid.css

table.grid { -moz-border-radius-topleft: 15px; -moz-border-radius-topright: 15px; } table.grid td{ padding: 5px 3px; } table.grid{ position: relative; border: 1px solid #7E7E7E; } table.grid thead tr td, table.grid-fixed-thead thead tr td{ background: url({$tpl}images/grayscale-bg.png) repeat-x top left; font-size: 0.95em; text-shadow: 0 -1px 0 #3F3F3F; color: #FFF; } table.grid tbody tr{ } table.grid tr.even td{ background: #EBEBEB; } table.grid-fixed-thead{ position: fixed; z-index: 1000; } table.grid h1{ text-align: center; font-size: 1.1em; }

css/styles.css

body { background: #000 url({$tpl}images/background.jpg) repeat-x center top; font-family: 'Trebuchet MS',Arial,Verdana,sans-serif; padding: 40px 0; } #wrapper{ font-size: 105%; background-color: #fff; -moz-border-radius:5px 5px 5px 5px; -webkit-border-radius:5px 5px 5px 5px; -moz-box-shadow: 0 1px 20px #BBBBBB; -webkit-box-shadow: 0 1px 20px #BBBBBB; position: relative; } .container_12{ padding-bottom: 20px; } #twitter{ position: absolute; top: -35px; left: 360px; width: 600px; } #twitter #birdy{ display: inline; } #twitter #birdy a{ color: transparent; } #twitter #tweet{ position: absolute; left: 42px; top: 0px; } #twitter #tweet div{ float: left; } #twitter #tweet #tweet-open{ background-color: white; background: url(../images/twitter/box-left.png) no-repeat left top; width: 16px; height: 31px; } #twitter #tweet #tweet-body a{ text-decoration: none; color: #2CCAFF; } #twitter #tweet #tweet-body a:hover{ text-decoration: underline; } #twitter #tweet #tweet-body{ background: url(../images/twitter/box-background.gif) repeat-x left top; height: 31px; line-height: 2.6em; font-size: 0.9em; padding: 0 2px; white-space: nowrap; } #twitter #tweet #tweet-close{ background: url(../images/twitter/box-right.png) no-repeat left top; width: 8px; height: 31px; } #content{ padding: 10px; } #content.grid_12{ width: 920px; } #content.grid_8{ width: 600px; } #footer{ text-align: right; width: 280px; font-size: 0.85em; color: #292929; padding-right: 5px; padding-bottom: 5px; } #footer small{ font-size: 0.779em; color: #CCC; } #statistics{ padding: 40px 0 0 0; } #footer img{ vertical-align: middle; } a { color: #031B27; text-decoration: underline; } a:hover { text-decoration: none; } fieldset#info{ width: 100%; } p.centered{ padding: 10px; background: #BFBFBF; border: 1px solid #9B9B9B; color: #FFF; text-shadow: 0px 1px 2px #000; -moz-border-radius: 5px; -webkit-border-radius: 5px; border-radius: 5px; } blockquote{ background: #F3F9FF; border: 1px solid #80D3FD; border-left: 4px solid #80D3FD; padding: 10px; margin: 15px; } img { border: none; }

Результат

В результате мы получили отличную тему оформления, которую можно легко кастомизировать, поменяв фоновое изображение, логотип, картинки и цвета в файлах стилей.
Также пришлось заменить некоторые иконки в шестеренках для того, чтобы они вписывались в уменьшенную панель пользователя.
Дистрибутив обновлен, теперь в нем две темы.
Успехов в работе с cogear!

Новый дизайн cogear

18:58 ← 26 июля 2010 Отправить в Твиттер adminadmin  RSS comments 39

Комментарии (39) ↓

dezmax dezmax time 19:00 ← 26 июля 2010 #
А в демо можно увидеть результат?
Автор
admin admin time 19:02 ← 26 июля 2010 #
Минутку =)
Автор
admin admin time 19:08 ← 26 июля 2010 #
Можно.
dezmax dezmax time 20:03 ← 26 июля 2010 #
Клево. Мне нравится!!!
Автор
admin admin time 20:04 ← 26 июля 2010 #
Рад стараться. Мне тоже нравится и даже более чем.
dezmax dezmax time 20:04 ← 26 июля 2010 #
Только замечанье одно, кнопки (Отправить, Предпросмотр) в Opera выглядят не так как в других браузерах.
dezmax dezmax time 20:05 ← 26 июля 2010 #
как то бледно… и стрелки рейтинга криво отображаются
Автор
admin admin time 20:10 ← 26 июля 2010 #
Опера не поддерживает пока некоторые современные стандарты CSS3, но разработчики сделают все, чтобы догнать другие популярные браузеры в скором времени.
Wave Wave time 20:22 ← 26 июля 2010 #
Небольшая критика. Листинги всех этих файлов можно посмотреть и в скачаном архиве. Это даже удобней — не нужно прокручивать всю простыню на одной странице. Действительно интересного в этом посте — ну, грубо говоря, всё до листингов. Объяснение (очередное) про то, что стили и js движок подхватывает автоматически (действительно, приятно). Объяснение про 960.gs (я только после знакомства с ним понял, почему говорят CSS-фреймворки, до того не понимал). Ну и вообще, на полноценный урок топик тянет мало. Я ожидал какого-никакого step by step, пояснения, что мы делаем и почему именно так.
Хотя объективности ради, урок свёлся бы к уроку вёрстки. Потому что в отличии от многих других движков, здесь кроме вёрстки ну почти совсем ничего в шаблоне делать не приходится.
Автор
admin admin time 20:29 ← 26 июля 2010 #
Не все поймут, в каких шаблонах и что смотреть.
Если есть вопросы а-ля step by step, спрашивайте. Очевидные вещи и ходы решил не озвучивать.
Верстка целиком и полностью по 960.gs — по коду шаблонов все понятно, ничего сложного нет.
Wave Wave time 20:40 ← 26 июля 2010 #
Лично мне понятно всё. Сейчас пытаюсь сообразить, что бы этакого спросить, чтобы критика действительно была конструктивной, и не придумаю ничего.
Зато есть багрепорт. Попытался ответить в соседней вкладке файрфокса (3.5.11) на комментарий в каталоге. Форма не под комментарием выскочила. Не знаю, то ли там древовидных комментариев и нет, то ли просто так… В общем, отправил комментарий и выскочил нотайс
A PHP Error was encountered Severity: Notice Message: Undefined variable: item Filename: mail/_hooks.php Line Number: 196
Переключился на текущую вкладку и увидел ответ на мой коммент. Нажал в свою очередь «ответить» и получил какую-то кашу из html-я. Пришлось жать back & refresh. После этого отправил.
Автор
admin admin time 20:42 ← 26 июля 2010 #
Да, поскольку комменты в каталог пересаживались, там могут быть такие баги.
Постараюсь решить.

P.S. Разрываюсь в работе между первой и второй версией движка :-)
Wave Wave time 20:52 ← 26 июля 2010 #
Вот, опять получил по нажатию на «ответить».
С точки зрения пользователя, даже не знаю, что предпочесть, «дайошь новую» или «дайошь поддержку». Хотя полагаю, что рано или поздно старую версию придётся забросить ради более перспективной.
А мне честность не позволяет просить доступ ко второй версии. Потому что в ближайший месяц я не внесу никакого вклада даже по мелочам. Ну разве что как тестировщик.

Только и думаю, что если выйдет в августе, то сайт журнала буду делать сразу на ней.
Автор
admin admin time 20:54 ← 26 июля 2010 #
Релиз намечен на сентябрь. В августе, возможно, пригласим всех своих на бета-тестирование.
Wave Wave time 21:11 ← 26 июля 2010 #
Напрашиваюсь :)

Смотрю последние изменения в SVN.

Add method to simply clear cache by url.

Сразу некоторый ворнинг. Все деструктивные действия следует делать по POST-запросу, а не по урлу. Даже если у злоумышленника нет доступа в админку, он может подсунуть ссылку на деструктивное действие тому, у кого права есть. А вот подсунуть кнопку гораздо сложнее, особенно если к каждой форме приписывать session_id и при получении POST проверять на наличие оного.
Ну, так, небольшой трюк, чуть-чуть повышающий безопасность.
Автор
admin admin time 21:15 ← 26 июля 2010 #
Согласен, но очистка кеша — это дело неразрушающее надежд :-)
Varhal Varhal time 16:08 ← 27 июля 2010 #
От урока конечно ожидал большого. Подскажите как изменить цвет nodes? например вот так:
Автор
admin admin time 16:18 ← 27 июля 2010 #
Поставить FireFox+FireBug, посмотреть CSS-класс заголовка ноды, заменить стиль на свой в файле стилей шаблона.
dqpb dqpb time 16:25 ← 27 июля 2010 #
или chrom+developer
Varhal Varhal time 16:40 ← 27 июля 2010 #
спс… для хрома давно искал)
Varhal Varhal time 16:47 ← 27 июля 2010 #
нашел класс отвечающий за ссылки, добавляю (color: #336633;) в CSS:
.node .title a{ text-decoration: underline; color: #336633; Все ссылки становятся зелеными, как отдельно прописать класс например для:
dezmax dezmax time 17:38 ← 27 июля 2010 #
Можно спросить, откуда скрин? LiveStreet?
Varhal Varhal time 17:39 ← 27 июля 2010 #
валялся старый псдешник темы LiveStreet… вот и решил интересные фишки с него взять)
Varhal Varhal time 17:40 ← 27 июля 2010 #
он самый)
dezmax dezmax time 17:41 ← 27 июля 2010 #
Я тоже с него взял кое что — вот
Varhal Varhal time 17:51 ← 27 июля 2010 #
это твоя CMS???
Varhal Varhal time 17:54 ← 27 июля 2010 #
на основе Explay?
dezmax dezmax time 18:19 ← 27 июля 2010 #
да! не на основе, а вместо эксплея
dqpb dqpb time 17:19 ← 27 июля 2010 #
.node .title { бла бла бла }
Varhal Varhal time 18:08 ← 27 июля 2010 #
.node .title { color: #336633; } меняется цвет стрелочки, а где отдельно поменять цвет названия темы и цвет названия сообщества или личного блога??
Автор
admin admin time 22:53 ← 27 июля 2010 #
.node .title a :-)
Varhal Varhal time 18:36 ← 27 июля 2010 #
Еще вопросик: как перенести панель пользователя с темы default в simple???
Автор
admin admin time 22:53 ← 27 июля 2010 #
Скопировать в simple папку gears/cpanel/* из папки default, а также пересадить стили и картинки + обернуть cpanel в div с id=«cpanel-wrapper». По аналогии с самим шаблоном — загляни вовнутрь, посмотри, как там это делается.
Varhal Varhal time 17:01 ← 28 июля 2010 #
подскажи в каком файле обернуть cpanel в div?
Автор
admin admin time 17:07 ← 28 июля 2010 #
Там, где вы указываете {$cpanel}.
ath1ete ath1ete time 12:34 ← 22 августа 2010 #
Что отвечает за вывод постов? Переношу тему из WP сюда, но не понял как мне дизайн постов вывести. футер, хэдэр и сайдбар .tpl я сделал, но пока без макросов. А посты где?
Автор
admin admin time 13:06 ← 22 августа 2010 #
Смотрите в /gears/nodes/templates/node.tpl.
В своей теме вы можете создать шаблон /templates/ваша_тема/gears/nodes/templates/node.tpl, который переопределит исходный.
ath1ete ath1ete time 14:00 ← 22 августа 2010 #
Merci