Внимание! Данная запись отмечена как устаревшая и/или потерявшая актуальность! Возможно автор уже передумал и теперь придерживается другой точки зрения, нежели изложенная в тексте ниже.

Шаблон «Twenty Ten» для MaxSite CMS

MaxSite CMS / Создание шаблонов MaxSite CMSПросмотров: 20801 (278)

Долго думал какой же взять дизайн за основу для обучения и неожиданно решил, что дефолтный WordPres-шаблон отлично для этого подходит. Во-первых он достаточно простой по дизайну и следовательно html-разметка и css-стили будут несложными. Во-вторых - у него есть некоторые опции, в частности смена картинки шапки из админки. И хотя в одной из статей я уже приводил код, как сделать аналог на MaxSite CMS, будет уместным сделать это еще раз с полным описанием в боевых, так сказать, условиях. И в третьих - многим будет интересно посмотреть и сравнить полученный результат с работой «WordPress team». grin

Если у вас нет интереса читать объяснения, то готовый шаблон вы можете скачать в конце статьи.

Перед началом работы оговорим несколько моментов.

Львинная доля дизайна - это css-стили. Насколько это возможно, я буду упрощать их описания, но обучать CSS с нуля, к сожалению не получится. Поэтому сразу определяемся, что вы в курсе хотя бы базовых знаний CSS и HTML и мне не придётся рассказывать, что означает например такая запись:

h1 {font-size: 1.8em; margin: 10px 0 5px 0; font-weight: normal;}

Если вы не можете понять что здесь написано, то скорее всего по тексту ниже у вас будут трудности. В этом разрезе я могу порекомендовать обратиться к какому-либо онлайн-учебнику.

Еще момент. Делать шаблон я буду основываясь на цикле статей «MaxSite CMS для чайников/верстальщиков», но это не значит, что мой вариант будет единственно верным. MaxSite CMS как раз и привлекательна тем, что позволяет получить правильный результат несколькими способами.

И последний момент. В этой статье я хотел бы обратить внимание не только на непосредственно код, но и на сам подход к созданию шаблона. В данном случае я просто делюсь опытом того, как это делаю сам.

Итак, приступим.


Исходный дизайн

Исходный дизайн можно посмотреть по этой ссылке. Также я сделал небольшой скриншот.


Готовим каталог

Создадим для шаблона свой каталог. В application/maxsite/templates/ сделаем каталог twenty-ten. Все изображения будем хранить в подкаталоге images, стили в css. По ходу статьи будем создавать и другие подкаталоги.


Готовим файлы

Файлы:

  • index.php
  • header.php
  • footer.php
  • info.php
  • functions.php
  • screenshot.jpg

скопируем из шаблона mini.

Создадим файл main-start.php следующего содержания:

<?php if (!defined('BASEPATH')) exit('No direct script access allowed');
 
ob_start();

Файл main-end.php будет таким:

<?php if (!defined('BASEPATH')) exit('No direct script access allowed');
 
global $MAIN_OUT;
 
$MAIN_OUT = ob_get_contents();
ob_end_clean();
 
require('main.php');

И main.php таким:

<?php if (!defined('BASEPATH')) exit('No direct script access allowed');
    require(getinfo('template_dir') . 'header.php'); 
?>
  
<?php global $MAIN_OUT; echo $MAIN_OUT; ?>

Краткое описание. В main-start.php включается буферизация вывода (например вывод главной страницы, записи, рубрики и т.п., то есть то, что отдаёт MaxSite CMS). Буферизация подразумевает, что весь текстовый вывод не отправляется в браузер, а помещается в некий буфер, который после можно вывести в произвольном месте. В main-end.php мы как раз и получаем результат буфера в глобальную переменную $MAIN_OUT. После этого подключается файл main.php, в котором собственно и будет храниться вся html-разметка страниц.

Теперь отредактируем файл info.php, в котором содержится информация о шаблоне:

<?php if (!defined('BASEPATH')) exit('No direct script access allowed'); 
 
$info = array(
    'name' => 'Twenty Ten',
    'description' => t('Шаблон MaxSite CMS', 'templates'),
    'version' => '1.0',
    'author' => 'WordPress team',
    'template_url' => 'http://maxsite.org/page/twenty-ten',
    'author_url' => 'http://theme.wordpress.com/themes/twentyten/'
);

Файл screenshot.jpg представляет собой скриншот шаблона в размере 250x200px. Обычно он делается уже после отладки всего шаблона.

В результате получится вот такая структура:


Первый запуск

Теперь проверим работоспособность шаблона. Идём в админ-панель: Настройки - Основные - Шаблон сайта и выбираем шаблон «twenty-ten». После этого переходим к сайту и видим вывод главной страницы.

Отдельно отмечу, что MaxSite CMS «скрывает» достаточно сложный код получения и вывода данных и уже на этом этапе шаблон работоспособен: в нём будут работать все ссылки, навигация, авторизация и т.п.

Если же возникла какая-то ошибка, то не спешите паниковать. Скорее всего ошиблись в какой-то мелочи. Мне очень часто пишут с просьбой о помощи, но при этом не могут элементарно прочесть текст ошибки. Так вот, в большинстве случаев PHP генерирует информацию достаточную для исправления ошибки. Например вы забыли сделать файл main.php. Возникнет такая ошибка:

A PHP Error was encountered
Severity: Warning
Message: require(main.php) [function.require]: failed to open stream: No such file or directory
Filename: twenty-ten/main-end.php
Line Number: 8

Описание ошибки: «failed to open stream: No such file or directory» - не найден файл или каталог. Дальше смотрим где возникла ошибка: «Filename: twenty-ten/main-end.php» - в файле main-end.php строка 8. Открываем файл и в 8-й строке видим код:

require('main.php');

Функция require() выполняет подключение указанного файла. Соответственно файл main.php функция не находит. Проверяем наличие файла (создаём его) и этим исправляем ошибку.

Во время программирования ошибки неизбежны: по невнимательности, из-за неверно используемых функций, других каких-то особенностей. Элементарное прочтение сообщения об ошибке здорово сэкономит и время и нервы. grin


Сброс css

Определимся с css-стилями. И хотя мы пока еще не приступили к верстке дизайна, для начала нужно выполнить т.н. сброс стилей. Дело в том, что браузеры имеют разные дефолтные установки и чтобы привести их к некому единому знаменателю и выполняется сброс. В Интернете вы найдёте много вариантов, я же использую сброс от Eric Meyer.

Обычно сброс оформляют в виде отдельного файла reset.css, но в последнее время я предпочитаю использовать единый css-файл шаблона. Главный плюс здесь в том, что не создаются дополнительные http-соединения при загрузке страниц. Второе преимущество - если использовать раздельные css-файлы, то приходится «прыгать» между ними исправляя стили одного элемента. Например раньше я выделял основную структуру в struct.css, а оформление в style.css, но со временем выяснил, что всё-таки удобней описать структуру в одном style.css, потому что структура содержит не только позиционирование, но и оформление (цвета, шрифты, фоны) и при едином файле всё настраивается в одном месте. Впрочем такой подход дело вкуса и привычки.

Итак, скопируем стили сброса в css/style.css.

После этого откроем header.php и вместо строк:

<link rel="stylesheet" href="<?= getinfo('stylesheet_url') ?>struct.css" type="text/css" media="screen">
<link rel="stylesheet" href="<?= getinfo('stylesheet_url') ?>style.css" type="text/css" media="screen">

Укажем одну

<link rel="stylesheet" href="<?= getinfo('stylesheet_url') ?>css/style.css" type="text/css" media="screen">

Мы убрали подключение struct.css и указали каталог css для style.css.


Моделирование шаблона

Прежде чем приступать в html-верстке, в обязательном порядке следует научиться делать модульную сетку, а точнее ячейки-блоки из которых в итоге состоит дизайн. Вначале выполняем визуальное моделирование, которое уже после кодируется в виде html.

Для моделирования можно использовать самые разные программы, начиная от фотошопа и специализированных сервисов и заканчивая примитивными paint или аля-Clip2Net.com или даже простым рисованием на бумаге. Всё, что нам требуется это нарисовать согласно дизайна функциональные блоки, которые отвечают за вывод меню, сайдбара, подвала, шапки и т.п. Чтобы вас не мучить, сразу привожу свой результат, который я сделал в программе Pencil.

На схеме я указал id и class блоков, чтобы несколько упростить понимание. Главное в моделировании не отступы или цвета, а вложенность блоков. Поскольку у нас будут плавающие (float) блоки, то для каждой пары требуется отдельный контейнер. Например в блоке #header div.line1 будет два float-блока: div.b1 и div.b2. Согласно дизайну первый - заголовок сайта, второй - описание.

Технически все блоки оформляются в виде html-тэга DIV. Строго говоря, можно было бы разместить заголовок сайта только в H1, а описание только в H2 и после применить стили, которые их разнесли бы их по краям шапки, но это будет в корне неверный подход. Модульная сетка подразумевает только позиционирование ячеек, но не конечное оформление. Именно поэтому в модульной сетке следует избегать использования оформительских тэгов, и тогда в любой ячейке можно будет разместить любой функциональный блок, не опасаясь, что структура развалится.

Обратите внимание на два, казалось бы одинаковых блока #all и #all-wrap. Посмотрев на дизайн мы видим, что основной контейнер имеет небольшой отступ от общего серого фона. Опытные верстальщики заметят, что по сути это просто внутренний отступ (padding). Но с padding есть несколько проблем из-за особенностей блочной модели HTML. Общаяя ширина (в дизайне) блока считается с учётом всех отступов и даже размеров границ (border), что не совпадает с блочной моделью HTML. И в принципе это не было бы проблемой, если бы не браузер IE, который имеет свою специфичную блочную модель. Поэтому, чтобы облегчить верстку намного эффективней сделать два вложенных блока, и для внутреннего задать внешний отступ (margin), который работает без проблем во всех браузерах.

Есть еще одна причина использования вложенных (wrap) блоков. В нашем дизайне отступ имеет один цвет с основным блоком (белый). Но очень часто, после предварительной верстки, клиент может пожелать добавить что-то вроде тени по краям, или контур, или цвет отступа или даже сложный фон. При использовании одного блока решить задачу будет сложновато. При двух - запросто. И не придётся переделывать верстку, достаточно будет ограничиться правкой стилей.


Начальные (default) css-стили

Перед тем, как непосредственно приступить к html-вёрстке, я обычно прописываю начальные (базовые) css-стили. Выше мы уже сделали сброс стилей и, теперь, логично было бы описать структуру страницы. Но, на самом деле структура может содержать html-тэги, которые пока еще не описаны. Возьмем для примера H1. Этим тэгом оформляются заголовки записей, но им же можно оформить и название сайта в шапке. Таким образом задав стиль в шапке, нам придётся его переопределять ниже - для записей, что приведёт к конфликту или перезаписи вышеопределённого H1.

Особенно часто возникают проблемы с отступами, интерлиньяжем блочных элементов, вроде P, DIV, BLOCKQUOTE, PRE и т.п. Скажем задав единичный line-height для DIV, что отлично подойдёт для вёрстки шапки, мы получим головную боль для всех DIV-блоков ниже, потому что текст в них должен визуально отображаться с интерлиньяжем как у абзаца P (обычно это 1.3em).

Именно поэтому после сброса желательно выставить некие базовые стили, которые будут использоваться во всех текстах сайта.

В самом простом варианте default-стили будут такими:

body, div, ul, ol, li, td, p, blockquote, code, pre, h1, h2, h3, h4, h5, h6 {line-height: 1.3em;}
p, code, pre, blockquote, ul, ol, table, dl {margin: 4px 0 7px 0;}
ol, ul {margin-left: 15px;}
ul {list-style-type: disc;}
ol {list-style-type: decimal; }
sup, sub {vertical-align: baseline; position: relative; font-size: .8em}
sup {top: -0.4em;}
sub {bottom: -0.3em;}
hr {color: #cccccc; background-color: #cccccc; height: 1px; border-width: 0;}
table {width: 100%;}
table th, table td {border: 1px solid #cccccc; padding: 2px 3px; vertical-align: top;}
table th {background: #f4f4f4;}
 
table.no-border, table.no-border td {border: none; padding: 0; vertical-align: top;}
 
dt {margin-bottom: .2em; font-weight: bold; background: #E5E5E5; padding: 4px 10px;}
dd {padding-left: 5em; margin-bottom: .4em; background: #F5F5F5;}
code, pre, blockquote {background: #eeeeee; border: 1px solid silver;}
code {padding: 1px 4px;}
pre {padding: 4px; overflow: auto;}
blockquote {padding: 4px 4px 4px 20px; margin-left: 30px; border-left: 4px solid #aaaaaa;}
label {cursor: pointer;}
 
input[type='checkbox'] {cursor: pointer; margin-top: 2px; vertical-align: middle;}
 
span.cut {}
div.break {clear: both;}
 
/* база заголовков */
h1 {font-size: 1.8em; margin: 0px 0 5px 0; font-weight: normal; }
h2 {font-size: 1.4em; margin: 15px 0 5px 0; font-weight: normal; }
h3 {font-size: 1.0em; margin: 15px 0 5px 0;}
h4 {font-size: 1.2em; margin: 15px 0 5px 0;}
h5 {font-size: 1.1em; margin: 15px 0 5px 0;}
h6 {font-size: 1.0em; margin: 15px 0 5px 0;}
 
/* ссылки */
a {color: orange; text-decoration: none;}
a:hover {color: maroon; text-decoration: underline;}

На самом деле стилей несколько больше, потому что есть смысл сразу описать все классы одного тэга. Ну скажем помимо просто A, можно указать и a.current_url. Я не стал приводить все эти стили, потому что их довольно много и они будут присутствовать в результирующем style.css.

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

В общем получается, что style.css будет состоять примерно из:

  • reset - сброс
  • default - начальные настройки основных тэгов
  • struct - структура
  • ul/ol - списки
  • виджеты, плагины и т.п.
  • хелперы - вспомогательные классы


Делаем HTML

Согласно нарисованной схемы, создаём HTML структуру. Файл main.php:

<?php if (!defined('BASEPATH')) exit('No direct script access allowed');
    require(getinfo('template_dir') . 'header.php'); 
?>
<div id="all">
    <div id="all-wrap">
        <div id="header">
            <div class="line1">
                <div class="b1">Заголовок</div>
                <div class="b2">Описание</div>
            </div>
 
            <div class="line2">изображение</div>
 
            <div id="header-menu">меню</div>
        </div>
 
        <div id="main">
            <div id="content">
                <div class="content-wrap">
                    содержимое страницы
                </div>
            </div>
     
            <div id="sidebar1">
                <div class="sidebar1-wrap">
                    сайдбар
                </div>
            </div>
        </div>
 
    <div id="footer">подвал</div>
 
    </div><!-- /div id="all-wrap"  -->
</div><!-- /div id="all"  -->
</body></html>

Как легко увидеть, html-структура целиком повторяет нашу визуальную модель. Отмечу только на дополнительные wrap-блоки. Особой погоды они сейчас не делают, но могут пригодиться после, если вдруг потребуется задать дополнительные отступы. Вообще при вёрстке лучше задать дополнительный wrap-блок, чем тратить много времени на настройку отступов и позиционирование. Когда у всех пользователей будут нормальные браузеры, то wrap-блоки будут не так актуальны.


CSS-позиционирование блоков

Следующим шагом будет описание html-блоков стилями. Современная вёрстка по сути и сводится к шаманству с CSS.

При вёрстке важно придерживаться нескольких правил.

  • Блоки основных ячеек должны иметь нулевые padding-отступы. По возможности и margin. Для отступов лучше использовать margin вложенного блока, чем padding внешнего.
  • Никогда (!) не используйте в (моделирующих) блоках ячеек border. Из-за этого меняется общая ширина блока и верстка может нарушиться.
  • Если при тестировании требуется визуально выделить блок, то используйте background с произвольным цветом.
  • Верстка происходит от общего к частному: от более «верхнего» блока к более «нижнему»; от родителя к ребёнку.

Итак, начнём с самого верхнего блока - body. Согласно дизайна он имеет серый цвет.

body {background: #F1F1F1;}
Продсказка. Для быстрого снятия цвета с экрана можно использовать «программы-пипетки», но несколько удобней это делать с помощью FireFox-плагина ColorZilla. Аналогично, для быстрого измерения расстояний - «линейка» MeasureIt.

Следующий блок #all. Этот блок позиционирует сайт по центру браузера и имеет фиксированную ширину (980px). Для центрирования произвольного блока в CSS используется небольшая хитрость: выставляется правый и левый отступ равным auto. При фиксированной ширине блока, браузер выставляет отступы от своих краёв одинаковыми и тем самым создаётся иллюзия центрирования. Также сразу отметим, что #all имеет верхний и нижний отступ в 20px. Ну и ко всему прочему #all имеет белый фон.

#all {width: 980px; margin: 20px auto; background: white;}
Запись «margin: 20px auto» является короткой записью «margin: 20px auto 20px auto», что указывает на отступы «margin: верх право низ лево». При совпадении верх-низ и право-лево, можно указывать только два значения. Если все значения совпадают, то достаточно указать «margin: отступ»

Основной блок у нас имеет границу 20px по краям. Именно для этого мы предусмотрели #all-wrap.

#all-wrap {margin: 0 20px;}

Итак позиционирование основного блока мы выполнили.


Шапка

Теперь займёмся шапкой #header. Тут уже будут нюансы. С одной стороны высота шапки может быть фиксированной. То есть мы можем посчитать общую высоту и высоту каждого блока. С другой стороны общую высоту можно не считать - она будет автоматом выставлена из входящих в неё блоков. Мы знаем, что у нас будет меняться меню и изображение. Поэтому можно оставить динамический общий размер шапки и для #header не указывать стили, а сделать это только для вложенных блоков.

Начнём с названия и описания сайта.

#header div.line1 div.b1 {width: 715px; float: left;}
#header div.line1 div.b2 {width: 225px; float: right;}

Первый блок мы задали шириной 715px. Второго - 225px (это ширина сайдбара согласно дизайну). Ширина первого получается так: общая ширина (980) - левый отступ (20) - правый отступ (20) - ширина сайдбара (225) = 715. Также мы сделали блоки плавающими (float).

Теперь есть смысл вернуться к main.php и прописать php-код для заголовка сайта и описания.

В MaxSite CMS для этого используется функция getinfo(). В нашем случае результат будет таким:

...
<div id="header">
    <div class="line1">
        <div class="b1"><?= '<h1><a href="' . getinfo('siteurl') . '">' . getinfo('name_site') . '</a></h1>' ?></div>
        <div class="b2"><?= '<h2>' . getinfo('description_site') . '</h2>' ?></div>
    </div>
...

То есть мы поместили название сайта в ссылку и H1, а описание - в H2. Теперь зададим стили.

#header div.line1 div.b1 h1 {font-size: 28px; font-family: Arial; margin: 40px 0 0 0; line-height: 1; font-weight: bold;}
    #header div.line1 div.b1 h1 a {color: black; text-decoration: none;}
#header div.line1 div.b2 h2 {font-size: 13px; font-style: italic; margin: 50px 0 0 0; line-height: 1;}

Тут мы устанавливаем размеры заголовков в пикселях (px). Обычно достаточно использовать пункты (pt или даже em), но если необходимо точно перенести размер или он должен не зависеть от базового шрифта, то лучше использовать именно пикселы. В заголовке у нас меняется шрифт с дефолтного Georgia на Arial. И здесь же мы устанавливаем единичный (100%, 1em) интерлиньяж (line-height), поскольку в default-стилях для всего сайта стоит 1.3. Чтобы точно спозиционировать элемент, следует учитывать эти интервалы. Мы же делаем проще - сбрасываем их и получаем точные размеры.

Поскольку у нас заголовок-ссылка, а ссылки имеют по-умолчанию другой цвет, то устанавливаем и стили для A.

Следующий блок у нас отвечает за вывод изображения. Сделаем его в виде IMG. Мы помним, что шапка у нас будет меняться из админ-панели, но на текущем этапе браться за сложный php-код пока не будем. Вместо этого мы сделаем небольшую «заглушку», которую позже заменим на полноценный код. Для этого вынесем код изображения в php-файл header-image.php, который разместим в каталоге шаблона components:

<?php if (!defined('BASEPATH')) exit('No direct script access allowed'); ?>
 
<img src="<?= getinfo('stylesheet_url') ?>images/headers/forestfloor.jpg" alt="" title="" width="940" height="198">

В данном случае мы просто отдаём файл forestfloor.jpg в IMG, который предварительно сохранили в каталоге шаблона images/headers.

В main.php соответственно меняем:

...
<div class="line2"><?php require(getinfo('template_dir') . 'component/header-image.php'); ?></div>
...

В стилях задаём:

#header div.line2 img {border-top: 4px solid black; margin-top: 25px;}

Указываем отступ от верхних заголовков и рисуем сплошную (solid) чёрную (black) верхнюю (border-top) линию высотой 4px.

Последний блок шапки - меню. В MaxSite CMS есть как минимум два варианта меню - простое стандартное и плагин Main menu. Первое меню работает на чистом CSS, второе позволяет создавать красивое выпадающее меню, но требует включённого JS. Но, если говорить совсем строго, то в MaxSite CMS код меню генерирует сама система, поэтому на долю вебмастера ложится задача только по созданю css-стилей. То есть наша задача-минимум - обеспечить нормальное отображение стандартного меню, а Main Menu отладить по желанию.

Чтобы упростить вёрстку мы вынесем в component код подключения меню - main-menu.php:

<?php if (!defined('BASEPATH')) exit('No direct script access allowed');
 
    if (!mso_hook_present('main_menu')) { ?>
    <div id="MainMenu">
        <div id="tab">
            <ul>
                <?php
                    $def_menu = t('/ | Главная_NR_about | О сайте_NR_comments | Комментарии_NR_contact | Контакты_NR_sitemap | Архив_NR_feed | RSS', 'templates');
                    if ( $menu = mso_get_option('top_menu', 'templates', $def_menu) ) 
                        echo mso_menu_build($menu, 'selected', true);
                ?>
            </ul>
        </div><!-- div id="tab" -->
    </div><!-- div id="MainMenu" -->
    <?php } 
    else 
    {
        mso_hook('main_menu'); 
    }
?>

Этот код встречается почти в каждом шаблоне MaxSite CMS, а пример верстки в соответствующих css-файлах. Подключим main-menu.php в main.php:

...
<div id="header-menu"><?php require(getinfo('template_dir') . 'component/main-menu.php'); ?></div>
...

Следующее шаманство связано с тем, что обычно меню генерируется в виде UL-LI-списка, и для его отображения в горизонтальном виде требуется менять свойство display и определённым способом задавать выравнивания и отступы.

#header-menu {background: black; height: 40px; font-family: Arial; font-size: 13px;}
 
    #MainMenu {height: 40px; margin-left: 20px;}
    #tab ul {margin: 0; padding: 0; list-style: none;}
    #tab li {display: inline; margin: 0; padding: 0;}
    #tab a {display: block; float: left; line-height: 40px; height: 40px; padding: 0 10px; text-decoration: none; text-align: center; color: #A0A0A0;}
    #tab li.selected a {color: white;}
    #tab a:hover {background: #333333; color: white;}

Данный код можно смело рекомендовать для изучения новичкам, а сейчас только отмечу что от шаблона к шаблону в этом коде достаточно менять лишь цвета и высоту элементов (line-height и height).


Основной блок

Основной блок #main состоит из двух частей: #content и #sidebar1. Сделаем вывод текста и сайдбара.

Меняем в main.php:

...
<div id="main">
    <div id="content">
        <div class="content-wrap">
            <?php global $MAIN_OUT; echo $MAIN_OUT; ?>
        </div>
    </div>
     
    <div id="sidebar1">
        <div class="sidebar1-wrap">
            <?php mso_show_sidebar('1', NR . '<div class="widget widget_[NUMW] widget_[SB]_[NUMW] [FN] [FN]_[NUMF]"><div class="w0"><div class="w1">', '</div><div class="w2"></div></div></div>' . NR); ?>
        </div>
    </div>
</div>
...

Вывод текстов осуществляется просто через echo, а вывод сайдбара с помощью функции mso_show_sidebar().

Мы уже знаем принцип, по которому получаются две колонки и всё, что нам следует сделать, так это практически один в один повторить код.

#main {margin-top: 40px;}
    #content {width: 680px; float: left;}
    #sidebar1 {width: 225px; float: right;}

Согласно дизайна, на главной странице вверху отображается черная линия. Но, если посмотреть другие страницы сайта, то этой линии не будет. Из этого следует вывод, что линия должна отображаться только у верхней фиксированной записи.

Обратите внимание ещё на один момент. В дизайне используется пустое поле 20px по краям. Именно этот отступ мы задали в #all-wrap. Верхняя запись (на голубом фоне) имеет этот самый 20px-отступ, но если посмотреть на записи ниже, то увидим уже 40px-отступ. Тоже самое расстояние используется и на вторых страницах сайта. Таким образом текст оказывается выровненным не по шапке (что было бы логичным), а «ступенькой». Так как мы переносим дизайн по возможности один в один, то для второго 20px-отступа задействуем div.content-wrap.

Вывод фиксированной записи в MaxSite CMS осуществляется в div.home_top, который мы сместим с отрицательным 20px-оступом, зададим внутрение отступы, чтобы текст не прилепал к краям, добавим нижний отступ и оформим черную линию сверху. Результирующий код таков:

#content {width: 680px; float: left;}
div.content-wrap {margin: 0 20px}
div.home_top {background: #F2F7FC; margin: 0 -20px 20px -20px; padding: 10px 20px; border-top: 4px solid black;}
В MaxSite CMS верхняя запись указывается так: Настройка шаблона - Номер top-записи для главной - указываем номер записи.


Подвал

Традиционно сложилось, что содержимое #footer хранится в отдельном файле footer.php.  Согласно дизайну в подвале отображается только название сайта и копирайт. В MaxSite CMS в подвале обычно отображается две строчки: название сайта с копирайтом, статистика по ресурсам и ссылки для логина. Я позволю себе использовать вывод, как это принято в MaxSite CMS.

Файл footer.php практически в неизменном виде присутствует во многих шаблонах MaxSite CMS, поэтому наши изменения касаются только дополнительных блоков div.r1 и div.r2:

<?php if (!defined('BASEPATH')) exit('No direct script access allowed'); 
 
    $site_name = getinfo('name_site');
    $date = date('Y');
    $CI = & get_instance();    
    
    $mq = $CI->db->query_count;
    
    echo '
        <div class="r1">
            &copy; ' . $site_name . ', ' . $date 
            . '<br>'
    . sprintf( 
        t('Работает на <a href="http://max-3000.com/">MaxSite CMS</a> | Время: 0.2929 | SQL: %s | Память: 1.75MB', 'templates')
        , $mq)
    . '<!--global_cache_footer-->';
 
    if (is_login())
        echo ' | <a href="' . getinfo('siteurl') . 'admin">' . t('Управление', 'templates') 
                . '</a> | <a href="' . getinfo('siteurl') . 'logout'.'">' . t('Выйти', 'templates') . '</a>';
    else
        echo ' | <a href="' . getinfo('siteurl') . 'login">' . t('Вход', 'templates') . '</a>';
    mso_hook('body_end');
    
    echo '
        </div>
        <div class="r2">
            Theme: <a href="http://theme.wordpress.com/themes/twentyten/">Twenty Ten</a>
        </div>';

Еще один важный момент, который касается подвала. Поскольку блок #main состоит из двух плавающих блоков переменной высоты, то нам нужны дополнительные разделяющие блоки, которые будут «отсекать» float-блоки от #footer. В main.php указываем:

<div class="break"></div>
<div id="footer"><?php require(getinfo('template_dir') . 'footer.php'); ?></div>
<div class="break"></div>

Пустые блоки div.break как раз и будут выполнять роль «разделителя».

Вариант с пустыми div.break лишь один из способов решения проблемы float-блоков. В качестве альтернативы например, можно заключить #header и #main в общий блок.

И стили для подвала:

#footer {border-top: 4px solid black; margin-top: 40px;}
    #footer div.r1 {width: 715px; float: left; margin: 10px 0; font-family: Arial; font-size: 13px;}
        #footer div.r1 a {color: black; text-decoration: none;}
    #footer div.r2 {width: 225px; float: right; margin: 10px 0; font-style: italic; font-size: 13px; color: #666666;}
        #footer div.r2 a {color: #666666; text-decoration: none;}


Настраиваем default-стили

После позиционирования ячеек сетки, следует вернуться к default-стилям (которые перед описанием сетки) и выстроить их согласно дизайну.

На самом деле это не совсем логично: возвращаться к default-стилям после настройки сетки. Правильней было бы вначале выставить именно default-стили, а уже после заниматься остальным. Но изначально мы всё-таки указали небольшой базис, которого для данного шаблона и в рамках статьи вполне достаточно. В реальном же проекте, вебмастер должен будет «прыгать» к default-стилям достаточно часто, поскольку их элементы появляются как раз после построения сетки.

В первую очередь выстроим заголовки. Заголовки записей - это H1. Тэг H2 используется в заголовках виджетов и при этом имеет класс h2.box. Второе назначение H2 - быть подзаголовком в тексте, хотя этого и не видно в исходном дизайне.

Для таких случаев в MaxSite CMS предусмотрен вывод тестовой страницы, чтобы верстальщик мог сразу выставить основное оформление. Активируем плагин «BBCode» и после этого в любой записи указываем [text-demo]

Если мы перейдём на такую тестовую страницу, то сразу увидим несоответствие H1: в заголовке записи используется шрифт Arial, а в тексте записи следует использовать основной шрифт Georgia. Тоже самое касается и гарнитур H2 для текста записи и заголовков виджетов.

В MaxSite CMS данная проблема решается очень просто. Текст записи (только текст!) выводится в блоке div.page_content. Заголовок же виджета вообще имеет свой отдельный класс, и, таким образом, мы вначале определяем общий стиль и ниже переопределяем его под другой вывод.

h1 {font-size: 1.6em; margin: 0px 0 5px 0; font-weight: bold; font-family: Arial;}
div.page_content h1 {font-size: 1.5em; margin: 7px 0; font-family: Georgia;}
 
h2 {font-size: 1.4em; margin: 15px 0 5px 0; font-weight: normal;  font-family: Arial;}
div.page_content h2 {font-size: 1.2em; font-weight: bold; font-family: Georgia;}

С ссылками несколько проще. Вначале определяем как должны выглядеть ссылки в тексте. Именно этот стиль задаётся для A. Также у нас есть ссылки в заголовках H1 и виджетах.

a {color: #0063CE; text-decoration: underline;}
a:hover {color: #FF4B33;}
 
h1 a {color: black; text-decoration: none;}
 
div.widget a {text-decoration: none;}
div.widget a:hover {text-decoration: underline;}


Отступы между записями

Каждая запись оформляется в div.page_only. Логично, что это будет нижний margin. При этом на одиночной странице (div.type_page) такой отступ не нужен.

div.page_only {margin-bottom: 30px;}
div.type_page div.page_only {margin-bottom: 0;}
Важный момент: визуально нам кажется, что отступы между записями должен задаваться верхним отступом H1. Но, в MaxSite CMS все логические блоки оформляются отдельно и поэтому позиционировать лучше именно родительский DIV-блок.


Блок информации (дата, рубрика, метки и т.п.)

С этим блоком сразу сделаем оговорку. На дизайне информация о записи выводится до и после текста. В MaxSite CMS без проблем возможен такой же вариант, но стандартно инфоблок выводится перед текстом. Поэтому мы сделаем этот блок как принято в MaxSite CMS, а для тех же кому захочется его изменить, следует использовать возможности type_foreach-файлов.

div.info {font-family: Arial; font-size: 0.9em; color: #888888;}
div.info span {font-weight: bold;}


Виджеты

Виджеты по дизайну выводятся более мелким шрифтом. Также нужно задать расстояние между виджетами. Заголовок виджета выводится как h2.box. Отличие от нашего H2 - нулевой верхний отступ. Также отметим, что в виджете используется серый цвет текстов, а заголовок черный.

div.widget {font-size: 0.9em; margin-bottom: 15px; color: #666666;}
h2.box {margin-top: 0; color: black;}

Заметьте ещё одну особенность: списки в виджетах имеют не «булечку», а «квадратик». Списки выводятся как ul.is_link. Соответственно указываем:

ul.is_link {list-style-type: square;}


Необходимое отступление

На этом этапе я должен сделать паузу. Как я уже объяснил выше, вёрстка выполняется от общего к частному, от крупного к мелкому и сейчас мы подошли как раз к той черте, когда крупного уже не осталось и мы должны заниматься мелкими правками.

Главная задача - показать основы вёрстки - уже решена и теперь нет смысла скатываться к описанию каждого плагина или блока имеющего специфичные стили.

Сделаю еще небольшое пояснение. Создание шаблона подразумевает несколько этапов настройки стилей, что упрощает вёрстку, но при этом, верстальщик может столкнуться с ситуацией, когда не сможет предусмотреть всех возможных вариантов вывода блоков. Например некоторые (достаточно специфичные) виджеты выводят данные в таблице. Соответственно нужно предусмотреть стили для этого случая. Но, на этапе разработки такие вещи неочевидны, не говоря уже о собственных стилях MaxSite CMS, которые появляются в зависимости от настроек или способа вывода данных.

Для облегчения работы вебмастера я «разместил» свою, достаточно большую «коллекцию» стилей MaxSite CMS, плагинов и хелперов в style.css этого шаблона.

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

При внимательном рассмотрении вы поймёте, что подавляющее большинство стилей, которые придётся менять, будут касаться смены цветов и шрифтов. В гораздо меньшем объёме - менять величины отступов. Таким образом, с помощью этого файла у вебмастера главной задачей будет выставить default-стили и стили модульной сетки. Остальное - мелкие правки.

Итак, со стилями определились. У нас остался один недоделанный блок - смена изображения в шапке.


Блок header-image

Наш шаблон не использует опций. Чтобы исправить этот недочёт достаточно скопировать два файла из шаблона Clouds:

  • options.php
  • options.ini

Для MaxSite CMS файл options.php имеет особое значение - в нём подключаются опции, которыми можно управлять из админ-панели. Сами же опции задаются в ini-файле. В нашем случае options.ini будет таким:

[Стиль меню в шапке]
[Стиль названия сайта в шапке]
[Стиль описания сайта в шапке]
 
[Файл картинки в шапке]
options_type = templates
options_key = my_image_header
type = select
values = PHP_START my_image_header PHP_END
description = "Выберите картинку, которую следует поместить в шапку. Размер изображения 940x198"
default = ""

Каждая секция - название опции. Верхние три пустых секции сообщают системе, что они не используются в шаблоне (они заданы в шаблоне default).

Для выбора картинки в шапке мы будем использовать опцию «Файл картинки в шапке», которая будет представлять из себя выпадающий список файлов (тип select). Сами файлы пусть хранятся в каталоге шаблона images/headers и, при желании, в uploads/headers - это означает, что файлы можно будет загрузить через админ-панель в Загрузках.

После загрузки произвольного файла он автоматически появится в списке выбора опции.

Обратите вимание на поле values. Текст «PHP_START my_image_header PHP_END» указывает системе на то, что следует выполнить функцию my_image_header(). Как вы уже поняли, это и будет нашей функцией, которая возвратит необходимые имена файлов (список формируется динамически).

Функцию my_image_header() следует разместить в файле functions.php шаблона. Этот файл имеет особое значение: он подключается как при работе шаблона, так и при работе в админ-панели. То есть когда необходимо «сообщить» админ-панели какие-то особенности шаблона, то используется имено этот файл. Например в нём выполняется регистрация сайдбара с помощью mso_register_sidebar().

Открываем functions.php и в конец добавляем:

if (!function_exists('my_image_header'))
{
    function my_image_header()
    {
        // подключение CodeIgniter
        $CI = & get_instance();
         
        // хелпер для работы с каталогами
        $CI->load->helper('directory'); 
 
        // результирующий массив с нашими файлами
        $all_files = array();
 
        // все файлы из images/headers шаблона
        $files = directory_map(getinfo('template_dir') . 'images/headers/', true);
        
        // функция directory_map возвращает не только файлы, но и подкаталоги
        // нам нужно оставить только файлы. Делаем это в цикле
        
        // вначале по images/headers шаблона
        $path = getinfo('template_dir') . 'images/headers/';
        foreach ($files as $file)
        {
            if (@is_dir($path . $file)) continue; // это каталог
            // добавим файл в массив сразу с полным адресом
            $all_files[] = getinfo('template_url') . 'images/headers/' . $file;
        }
        
        
        // аналогично для uploads/headers
        $files = directory_map(getinfo('uploads_dir') . 'headers/', true);
        
        $path = getinfo('uploads_dir') . 'headers/';
        foreach ($files as $file)
        {
            if (@is_dir($path . $file)) continue; // это каталог
            
            // добавим файл в массив сразу с полным адресом
            $all_files[] = getinfo('uploads_url') . 'headers/' . $file;
        }
        
        // если файлов нет, то возвращаем пустую строчку
        if (!$all_files) return '';
        
        // преобразуем массив в строчку с разделителем #
        return implode($all_files, '#');
    }
}

В коде я разместил комментарии, поэтому не будем на нём останавливаться.

Теперь нам нужно обеспечить получение опции my_image_header, в которой хранится полный http-путь изображения. Открываем файл component/header-image.php:

<?php if (!defined('BASEPATH')) exit('No direct script access allowed');
 
    if ($image_header = mso_get_option('my_image_header', 'templates', ''))
        echo '<img src="' . $image_header . '" alt="" title="" width="940" height="198">';
    else
        echo '<img src="' . getinfo('stylesheet_url') . 'images/headers/forestfloor.jpg" alt="" title="" width="940" height="198">';

Тут просто: получаем опцию и если она определена, то формируем IMG на основе опции. Если опции нет, то формируем на основе images/headers/forestfloor.jpg.


Подведём итоги

При создании шаблона я использую свои заготовки. Прежде всего это основные файлы, вроде main-start.php, functions.php и т.п. Они практически не требуют изменений. Файл main.php используется для задания html-разметки. Более-менее сложные блоки я выношу в виде components, которые подключаются как простые файлы. От проекта в проекту постепенно создаётся новые компоненты, что не требует каждый раз их заново создавать. Файл footer.php может меняться в зависимости от дизайна.

При работе с css-файлом придерживаюсь описанного выше подхода: один файл стилей, в нём секции сброса, default-стилей, описание структуры, какие-то мелкие уточнения, вроде списков. После идут блоки, формирующиеся самой MaxSite CMS, стили плагинов и несколько хелперов.

Не могу утверждать, что мой способ единственно верный, просто за много лет работы по созданию сайтов я пришёл именно к такому варианту и для меня он наиболее оптимален.

В результирующих файлах шаблона я разместил файлы стилей:

  • style-all-default.css - мой рабочий файл стилей
  • style-all-format.css - отформатированный для любителей «построчного» стиля
  • style-all-mini.css - сжатый, который задублирован как style.css.

Суть у всех файлов одинакова, используйте тот, который считаете нужным.

Также в main-menu.php я привожу пример динамической модификации пунктов Main Menu, в частности добавляются пункты для зарегистрированных пользователей.

Данный шаблон я также рекомендую посмотреть вебмастерам, которые по ошибке считают, что шаблон MaxSite CMS сложнее WordPress'овских - просто сравните его с «родным» Twenty Ten (он в комплекте WordPress).

Скачать шаблон Twenty Ten для MaxSite CMS 21.

Комментариев: 10 RSS

2jen06-03-2011 12:28

ЗдОрово! Если, скажем, статья об опциях носит более общий, озакомительный характер, то здесь просто готовая шпвргалка по добавлению/изменению опций.

И вообще, весь материал подан четко, предметно и последовательно, с акцентом на важных деталях.

3Аноним07-03-2011 09:25

Отличное руководство. Всё подробно и чётко разжёвано.

5Игорь02-05-2011 12:45

Попробовал установить предлагаемый шаблон. У меня выскочила ошибка. Устранилась удалением папки шаблона с хостинга. Что не так делаю?

6Игорь02-05-2011 12:51

К предыдущему посту Код ошибки "Вызов неопределенной mso_rss функции () в / home/us9000/newyearbiz.ru/www/application/maxsite/templates/twenty-ten/header.php на линии 12"

С чем может быть связано?

8Руслан Сафин23-05-2011 20:12

Можно вам на суд отдать шаблон, который сам сверстал? Не с нуля делал конечно, но попотеть пришлось, ибо не профи я в этом деле, а лишь любитель=)

9jen23-05-2011 20:24

Руслан Сафин: Можно вам на суд отдать шаблон, который сам сверстал?

С шаблоном вам лучше на форум http://forum.max-3000.com/ в раздел «Плагины и шаблоны»

10JokeRNtFan24-01-2012 19:05

Привет! У меня сайт на этой теме и проблема такая - создал страницу О блоге и она автоматически обрезалась кнопкой читать далее, и сама кнопка не работает. При нажатии все та же обрезанная статья остается...делал как страницу а не запись в рубрику. Подскажите где что изменить буду очень благодарен!

Оставьте комментарий!

Комментарий будет опубликован после проверки. Вы соглашаетесь с правилами сайта.

(обязательно)

О сайте

Здесь вы получите самую полную информацию о создании сайтов на MaxSite CMS.

Рейтинг@Mail.ru