Версия: 3.x
Пример создания темы оформления по сетке

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

Что требуется для создания темы оформления?

  1. Установленная копия движка ReadyScript (можно trial, все равно на .local она работает без ограничений, вечно)
  2. Сверстанные по сетке макеты. Для примера, подготовлены 5 простых макетов, из которых предстоит собрать тему оформления.
  • index.html – главная страница
  • catalog.html – страница со списком товаров
  • product.html – страница просмотра товара
  • anytext.html – любая текстовая страница
  • 404.html – страница для ошибок

Отсюда можно скачать полный архив с демо-версткой.

Необходимо установить на время создания темы оформления следующие опции в разделе Управление->Настройки системы:

dev_options.png
Настройки системы

Создаем пустышку

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

Темы оформления в ReadyScript располагаются в папке /templates, соответственно создадим в ней каталог с нашей новой темой. Назовем его gridexample. Разместим там файлы:

  • theme.xml, следующего содержания:
    1 <?xml version="1.0" encoding="utf-8"?>
    2 <theme scriptType="shop" scriptMajorVersion="2" themeType="pc">
    3  <general>
    4  <author>ReadyScript lab.</author>
    5  <name>Тестовая тема оформления gs960</name>
    6  <description>Создана для статьи о создании собственной темы по сетке gs960</description>
    7  <version>2.0.0.0</version>
    8  </general>
    9  <shades>
    10  <shade>
    11  <id>black</id>
    12  <title>Черная</title>
    13  <color>#000000</color>
    14  </shade>
    15  <shade>
    16  <id>green</id>
    17  <title>Зеленая</title>
    18  <color>#00FF00</color>
    19  </shade>
    20  </shades>
    21 </theme>
  • layout.tpl, следующего содержания:
    1 {* Основной шаблон *}
    2 {addcss file="960gs.css"} {* подключаем CSS фреймворк gs960 *}
    3 {addcss file="style.css"} {* подключаем файл ТЕКУЩАЯ_ТЕМА/resource/css/style.css *}
    4 
    5 {if $THEME_SHADE == 'green'}{addcss file="style_green.css"}{/if} {* Подключаем дополнительный стиль, если выбрана зеленая тема *}
    6 {$app->setDoctype('HTML')}
    7 {$app->blocks->renderLayout()} {* Запускаем рендеринг данной страницы *}
  • preview_black.jpg - скриншот темы в черном цвете
  • preview_green.jpg - скриншот темы в зеленом цвете

Необходимо также сразу перенести картинки, css-стили, скрипты из каталога с версткой в соответствующие папки создаваемой темы. т.е. в resource/img, resource/css, resource/js.

Далее заходим в административную панель ReadyScript в раздел Веб-сайт -> Настройка сайта. Выбираем нашу тему оформления.

gs_select_theme.png
Выбор темы оформления

Тема установлена, можно переходить к её оформлению.

Формируем blocks.xml или переносим сетку в Конструктор сайта

В случае использования тем по сетке, на сторону ReadyScript переносится обязанность генерировать сетку для страницы. Каждая страница может состоять из трех типов элементов:

  • Контейнер - это корневой элемент для секций, создает рабочую область. Контейнеру присваивается класс, container_N, где N - количество колонок, в соответствии с правилами gs960. В контейнеры обычно оборачивают независимые горизонтальные секции сайта, например, Шапка, Контент, Футер - это 3 разных контейнера. Почему удобно делить страницу на контейнеры? Потому, что контейнеры могут наследоваться на остальных страницах, т.е. Шапку и Футер удобно определить один раз на странице по-умолчанию, а вот центральную часть (Контент) определять разной на каждой странице.
  • Секция - область внутри контейнера, имеющая определенную ширину. Основное предназначение секции - это удерживание содержимого в пределах своей области. Секции присваивается класс grid_N, где N - количество колонок, в соответствии с правилами gs960.
  • Блок - видимая часть модуля, в которой отображается определенная информация. Блок размещается внутри секции. Каждый модуль может иметь неограниченное число блоков. Например, модуль "Каталог" содержит в себе следующие блоки: "Последние просмотренные товары", "Список категорий", "Рекомендуемые товары".

Далее мы будем конструировать страницы на основе нашей верстки с использованием описанных выше трех составляющих. Элементы верстки с классами container_... - это контейнеры, элементы с классом grid_... - это секции, все что находится внутри блока секций - это HTML-код блока. HTML-код блоков мы будем переносить уже в шаблоны соответствующих блоков, а структуру контейнеров и секций создадим в Конструкторе сайта.

Начнем со страницы по-молчанию. Согласно верстке, на всех страницах имеется 3 контейнера:

  • шапка
  • контент (центральная часть)
  • футер

Посмотрим, как в верстке описаны контейнеры:

1 <div class="container_12 header">
2  ... содержимое контейнера "Шапка"
3 </div>
4 <div class="container_12">
5  ... содержимое контейнера "Контент"
6 </div>
7 <div class="container_12 footer">
8  ... содержимое контейнера "Футер"
9 </div>

Создадим данные контейнеры в конструкторе сайта.

Добавим контейнер "Шапка", нажатием на одноименную кнопку. Контейнер шапки имеет класс container_12, из этого следует, что используется 12 колоночная система верстки - это означает, что полная ширина страницы составляет - 12 колонок и общая ширина секций, которые могут поместиться в однку строку также составляет 12 колонок. Контейнер также имеет дополнительный класс header необходимо указать его в поле CSS класс.

add_container.png
Окно добавления контейнера

По аналогии добавим 2 других контейнера - "Контент", "Футер". Все контейнеры - 12 колоночные. У контейнеров "Шапка" и "Футер" есть дополнительные классы, header и footer соответственно. У контейнера "Контент" дополнительного класса - нет. После создания контейнеров страница по-умолчанию выглядит следующим образом:

default_containers.png
Страница по-умолчанию с контейнерами
Заметки

Пока речь идет о контейнерах, то стоит рассмотреть все имеющиеся параметры у контейнера, исключительно для справки.

  • Ширина - Количество колонок, на которое будет делиться ширина контейнера.
  • CSS класс - Дополнительный класс, который будет приписан в аттрибуте class у HTML-элемента
  • Название - Любое текстовое название контейнера
  • Внешний элемент - HTML-элемент, в который будет обернут HTML-элемент контейнера.
  • CSS-класс оборачивающего блока - CSS-класс, для внешнего HTML-элемента.
  • Внешний шаблон - позволяет задать произвольный шаблон, в котором можно задать любую оборачивающую верстку для контейнера.
  • Внутренний шаблон - позволяет задать произвольный шаблон, который будет оборачивать все содержимое контейнера.

Внешний элемент

Если у контейнера задан внешний элемент, например div, и задан CSS-класс оборачивающего блока, например - wrap-block, то итоговый сгенерированный HTML будет иметь следующий вид:

1 <div class="wrap-block">
2  <div class="container_12">
3 
4  </div>
5 </div>

Внешний шаблон

Если у контейнера задан внешний шаблон следующего содержания:

1 <div class="wrapper-block">
2  <div class="some-block">...любое содержание...</div>
3  <div class="some-block-n2">...любое содержание...</div>
4  <div class="container-inside">
5  {$wrapped_content} {* Зарезервированная пременная. Означает - место вставки HTML-кода контейнера *}
6  </div>
7 </div>

Итоговый сгенерированный HTML-код контейнера будет иметь следующий вид:

1 <div class="wrapper-block">
2  <div class="some-block">...любое содержание...</div>
3  <div class="some-block-n2">...любое содержание...</div>
4  <div class="container-inside">
5  {* начало стандартного HTML кода контейнера *}
6  <div class="container_12">
7  ... содержимое контейнера
8  </div>
9  {* конец стандартного HTML кода контейнера *}
10  </div>
11 </div>

Как видно из примера, опция внешний шаблон позволяет привнести любой HTML-код вокруг элемента контейнера.

Внутренний шаблон

Если у контейнера задан внутренний шаблон следующего содержания:

1 <div class="inside-wrapper">
2  <div class="in-some-block">...любое содержание...</div>
3  <div class="in-some-block-n2">...любое содержание...</div>
4  <div class="content-inside">
5  {$wrapped_content} {* Зарезервированная пременная. Означает - место вставки HTML-кода содержимого контейнера *}
6  </div>
7 </div>

Итоговый сгенерированный HTML-код контейнера будет иметь вид:

1 <div class="container_12">
2  <div class="inside-wrapper">
3  <div class="in-some-block">...любое содержание...</div>
4  <div class="in-some-block-n2">...любое содержание...</div>
5  <div class="content-inside">
6  ... содержимое контейнера
7  </div>
8  </div>
9 </div>

Как видно из примера, опция внутрненний шаблон позволяет привнести любой HTML-код вокруг содержимого контейнера.

Далее приступим к переносу Секций из верстки в Конструктор сайта. Рассмотрим секции контейнера "Шапка".

1 <div class="container_12 header">
2  <div class="grid_4">...</div>
3  <div class="prefix_4 grid_4">...</div>
4  <nav class="topMenu grid_12">...</nav>
5 </div>

Видно, что в контейнере присутствуют 3 секции.

  1. ширина - 4 колонки, пользовательских классов - нет.
  2. ширина - 4 колонки, префикс - 4 колонки, пользовательских классов - нет
  3. ширина - 12 колонок, пользовательский CSS класс - topMenu

Чтобы добавить секцию необходимо выбрать пункт "Добавить секцию", в выпадающем меню контейнера.

add_section.png
Окно добавления секции

Аналогичным образом переносим все секции из нашей верстки во все контейнеры. Получаем следующую сетку:

default_sections.png
Секции в контейнерах страницы по-умолчанию
Заметки

Рассмотрим все имеющиеся параметры у секций.

  • Название секции для автоматической вставки модулей - этот параметр позволяет поставить метку на секцию.(левая, центральная или правая колонка или другое значение). Другие модули при установке могут использовать эту информацию для автоматического добавления своих блоков на страницы шаблона.
  • Ширина - ширина секции, указывается в колонках.
  • Внутреннее выравнивание - устанавливает выравнивание блоков внутри секции. В случае, если задано значение "на всю ширину", то блоки вставляются как есть. Если задано значение "слева" или "справа", то блоки внутри секции будут обернуты div'ом со стилем float:left или float:right соответственно.
  • Префикс - Отступ-слева (префикс по терминологии gs960), указывается в колонках. На уровне CSS задается с помощью: padding-left.
  • Суффикс - Отступ справа (суффикс по терминологии gs960), указывается в колонках. На уровне CSS задается с помощью: padding-right.
  • Сдвиг влево(pull) - Смещение влево (pull по терминологии gs960), указывается в колонках. На уровне CSS задается с помощью: position:relative;left:XX;
  • Сдвиг вправо(push) - Смещение вправо (push по терминологии gs960), указывается в колонках. На уровне CSS задается с помощью: position:relative;left:XX;
  • Пользовательский CSS класс - CSS класс, добавляемый к элементу секции.

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

  • Шапка
    • Логотип (Системный модуль → Логотип сайта)
    • Номер телефона (Произвольный HTML)
    • Меню (Меню → Меню)
  • Контент
    • Каталог (Каталог → Список категорий)
    • Новости (Статьи → Список свежих новостей)
    • Центральная часть (Системный модуль → Главное содержимое страницы)
  • Футер
    • Логотип (Системный модуль → Логотип сайта)

Чтобы добавить блок, необходимо воспользоваться соответствующим пунктом выпадающего меню секций.

add_block.png
Окно выбора блока для вставки

Например, чтобы добавить логотип в шапку сайта, выберите "Системный модуль" в списке слева, а справа отметьте блок "Логотип сайта". Откроется диалог настройки блока.

logo_block_setting.png
Диалог настройки блока Логотип

Блока "Номер телефона", в системе не существует, поэтому воспользуемся блоком "Произвольный HTML", и просто перенесем часть HTML из верстки.

add_html.png
Добавление произвольного HTML

По аналогии добавим и настроим все блоки на странице по-умолчанию. В результате получим следующее.

default_blocks.png
Блоки в секциях страницы по-умолчанию

Таким образом мы подготовили сетку для страницы по умолчанию. Такая расстановка контейнеров и секций будет генерировать представленную ниже структуру HTML:

1 <div class="container_12 header">
2  <div class="grid_4">
3  //блок Логотип
4  </div>
5  <div class="prefix_4 grid_4">
6  //блок Произвольный HTML
7  </div>
8  <div class="topMenu grid_12">
9  //блок Меню
10  </div>
11 </div>
12 
13 <div class="container_12">
14  <div class="grid_3">
15  //Блок Категории товаров
16  //Блок Список свежих новостей
17  </div>
18 
19  <div class="grid_9">
20  //Блок Главное содержимое страницы
21  </div>
22 </div>
23 
24 <div class="container_12 footer">
25  <div class="grid_12">
26  //Блок Логотип
27  </div>
28 </div>

Страница по-умолчанию подойдет для отображения всех страниц нашей верстки, кроме главной. Это связано с тем, что у главной страницы - нет так называемого "главного содержимого" и если мы откроем главную страницу с сеткой страницы "по умолчанию", то в середине будет пусто. Это означает, что для главной страницы мы должны отдельно задать содержание центрального контейнера "Контент", а контейнеры "Шапка" и "Футер" - использовать от страницы по-умолчанию.

Рассмотрим подробнее как это можно сделать.

Сперва необходимо добавить страницу "Главная страница" в Конструкторе сайта.

add_page.png
Диалог добавления страницы

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

clone_container.png
Клонирование контейнера

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

cloned_container.png
Клонированный контейнер

Удаляем ненужный для главной страницы блок "Главное содержимое страницы" и добавляем в секцию 9 блок Каталог товаров → Продукты из категории. Производим настройку блока.

top_products.png
Настройка блока Продукты из категории

Завершаем формирование сетки в Конструкторе сайта нажатием на кнопку "Сохранить эталон темы", расположенную в правом верхнем углу страницы. В папке с темой будет создан файл blocks.xml со сведениями о структуре сетки и параметрах всех блоков.

Раскидываем HTML-верстку блоков по tpl шаблонам

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

Делается это с помощью папки moduleview, которую мы должны создать в каталоге с темой. Чтобы перегрузить, например, шаблон "blocks/topproducts/top_products.tpl" из модуля catalog, нам нужно создать файл по следующему пути moduleview/catalog/blocks/topproducts/top_products.tpl.

где:

  • moduleview - папка для перегрузки шаблонов модулей
  • catalog - имя модуля
  • blocks - указывает, что это папка для шаблонов блочных контроллеров
  • topproducts - имя блочного контроллера
  • top_products.tpl - имя шаблона

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

block_info.png
Информаия о блоке

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

Итак, для наших нужд нужно создать следующие шаблоны:

  • moduleview/main/blocks/logo/logo.tpl - шаблон отображения логотипа
  • moduleview/main/blocks/breadcrumbs/breadcrumbs.tpl - шаблон хлебных крошек
  • moduleview/menu/blocks/menu/hor_menu.tpl - шаблон отображения меню
  • moduleview/catalog/blocks/category/category.tpl - шаблон отображения списка категорий в левой колонке
  • moduleview/catalog/blocks/topproducts/top_products.tpl - шаблон Лидеров продаж
  • moduleview/catalog/list_products.tpl - шаблон просмотра категории. (его использует фронт контроллер, поэтому нет секции blocks)
  • moduleview/catalog/product.tpl - шаблон карточки товара
  • moduleview/article/blocks/lastnews/last_news.tpl - шаблон списка новостей в левой колонке
  • moduleview/article/view_article.tpl - шаблон просмотра новости

Существует 2 методики быстрой перегрузки шаблонов модулей:

1.С помощью модификации существующего шаблона. Т.е. сперва нужно найти шаблон в папке с модулем (Например: /modules/catalog/view/....) и скопировать его в соответствующую папку вашей темы (/templates/НАЗВАНИЕ ТЕМЫ/moduleview/catalog/...). А далее просто изменить HTML вокруг конструкций, возвращающих данные.

  1. Создание с нуля. Т.е. можно сразу создать шаблон в папке с темой (/templates/НАЗВАНИЕ ТЕМЫ/moduleview/МОДУЛЬ/....). Заполнить его необходимым HTML-кодом, а далее заменять строки переменными. Здесь возникает логичный вопрос: "Как можно узнать доступные в шаблоне переменные?". Ответ очень прост, с помощью режима отладки. Нужно кликнуть на иконку "Информация о блоке", и в новом окне откроются доступные переменные в шаблоне.
varclick.jpg
Настройки блоков

Нажмите на иконку

varinfo.jpg
Информация о переменных блока

В отдельном окне откроются все переменные, паредаваемые в шаблон

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

Чтобы узнать более подробные сведения о переменной, в Smarty доступна конструкция {var_dump($var)}

Нужно учитывать, что если опция "Подробное отображение ошибок" отключена, то во время любого исключения или ошибки 404 будет отображаться шаблон exception.tpl. Поэтому наполним его следующим кодом:

1 <!DOCTYPE html>
2 <html>
3 <head>
4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
5 <title>Ой, ошибочка {$error.code}</title>
6 <link rel="stylesheet" type="text/css" href="{$THEME_CSS}/style.css">
7 </head>
8 <body>
9  <section class="exceptionBlock">
10  <div class="code">{$error.code}</div>
11  <div class="message">{$error.comment}</div>
12  </section>
13 </body>
14 </html>

Дело в том, что в отличие от других шаблонов темы оформления, этот шаблон не оборачивается стандартной шапкой и футером из тегов html, head, body, а возвращается как есть, поэтому мы должны позаботиться сами о подключении CSS файлов здесь.

Создание единого файла темы оформления

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

Для загрузки новой темы оформления в систему ReadyScript, нужно зайти в административную панель в раздел Веб-сайт → Настройка сайта. Открыть диалог выбора темы оформления и нажать на кнопку "Выбрать zip-файл". После загрузки файла, тема станет доступна для выбора.

Итоговый файл темы оформления

Скачать итоговую тему оформления, собранную по сетке можно здесь. Темы "Воздушная", "Классическая", "Детская", присутствующие в дистрибутиве ReadyScript также собраны по сетке. Их также можно использовать как эталон для разработки собственных тем.