Создаём тему для Drupal 6. Часть 1

Drupal
image
По созданию тем для друпала в интернете можно найти несколько статей (хорошая статья, советую почитать), однако обычно всё заканчивается банальным набором шаблонов и инфо-файлом. В этом топике я постараюсь доступно рассказать как создать гибкую и не самую простую тему.

Начало


Для начала нам потребуется создать директорию в каталоге sites/all/themes с названием нашей темы. Я назвал тему mytheme и создал каталог sites/all/themes/mytheme.
В созданном каталоге создаем директории css — для стилей, js — для скриптов, images — для картинок, templates — для шаблонов, preprocess — об этом позже. Также создаем файл template.php в котором мы будем писать всю логику темы и mytheme.info для описания темы. Можно еще добавить favicon.ico и logo.png.

mytheme.info


Файл содержит всю информацию, необходимую ядру для работы с темой.
Создадим файл примерно со следующим содержанием:
Copy Source | Copy HTML
  1. ; Название темы, как оно будет отображаться в админке
  2. name = MyTheme
  3. ; Описание темы
  4. description = Моя новая тема
  5. ; Версия ядра
  6. core = 6.x
  7. ; Шаблонизатор используемый темой, по умолчанию phptemplate
  8. engine = phptemplate
  9. ; Версия темы
  10. version = 6.x-1.01
  11. ; Путь к скриншоту темы
  12. screenshot = images/screenshot.png
  13. ; Регионы темы, в которые можно будет вставлять блоки
  14. regions[sidebar_right] = Right sidebar
  15. regions[sidebar_left] = Left sidebar
  16. regions[header_line] = Line in header
  17. regions[footer_line] = Line in footer
  18. regions[content_top] = Content top
  19. regions[content_bottom] = Content bottom
  20. regions[content_right] = Content right
  21. regions[comments_rigth] = Comments right
  22. regions[page_bottom] = Page bottom
  23. ; Настройки темы, которые будут доступны из админки
  24. ;features[] = name
  25. features[] = node_user_picture
  26. features[] = comment_user_picture
  27. features[] = search
  28. ;features[] = favicon
  29. ;features[] = primary_links
  30. ;features[] = secondary_links
  31. ; Стили
  32. stylesheets[all][] = css/blocks.css
  33. stylesheets[all][] = css/comments.css
  34. stylesheets[all][] = css/fields.css
  35. stylesheets[all][] = css/forms.css
  36. stylesheets[all][] = css/html-reset.css
  37. stylesheets[all][] = css/layout.css
  38. stylesheets[all][] = css/messages.css
  39. stylesheets[all][] = css/navigation.css
  40. stylesheets[all][] = css/nodes.css
  41. stylesheets[all][] = css/pages.css
  42. stylesheets[all][] = css/tabs.css
  43. ;stylesheets[print][] = css/print.css
  44. ;stylesheets[handheld][] = css/mobile.css
  45. ;stylesheets[only screen and (max-device-width: 480px)][] = css/iphone.css
  46. ; Скрипты
  47. ;scripts[] = js/script.js


Этого достаточно, чтобы друпал увидел и опознал нашу тему. Я выбрал такой набор стилей и регионов, т.к. нахожу его удобным. Вы можете изменить на свой вкус.

template.php


Самая вкусная часть темы. В этом файле мы будем писать всю логику — хуки.

Для начала определим HOOK_theme().
Copy Source | Copy HTML
  1. function mytheme_theme(&$existing, $type, $theme, $path) {
  2. // Определяем базовую тему, если наша тема дочерняя
  3. static $base_themes = array();
  4. $base_themes[] = $theme;
  5. // Добавляем хук "process", который будет вызываться после "preprocess".
  6. if ($type == 'theme') {
  7. foreach (array_keys($existing) as $hook) {
  8. if (function_exists($theme . '_preprocess')) {
  9. $existing[$hook]['preprocess functions'][] = $theme . '_preprocess';
  10. }
  11. if (function_exists($theme . '_preprocess_' . $hook)) {
  12. $existing[$hook]['preprocess functions'][] = $theme . '_preprocess_' . $hook;
  13. }
  14. foreach ($base_themes as $base_theme) {
  15. if (function_exists($base_theme . '_process')) {
  16. $existing[$hook]['preprocess functions'][] = $base_theme . '_process';
  17. }
  18. if (function_exists($base_theme . '_process_' . $hook)) {
  19. $existing[$hook]['preprocess functions'][] = $base_theme . '_process_' . $hook;
  20. }
  21. }
  22. }
  23. }
  24. // Добавляем препроцессы только для данной темы, они не распространятся на дочерние темы
  25. if ($theme == 'mytheme') {
  26. return array(
  27. // Добавляем регион. Это необходимо, чтобы мы могли использовать шаблоны для регионов
  28. 'region' => array(
  29. // Аргументы, которые будут доступны
  30. 'arguments' => array('elements' => NULL),
  31. // Путь к шаблону
  32. 'path' => drupal_get_path('theme', 'mytheme') . '/templates',
  33. // Название шаблона. Полное имя файла будет region.tpl.php
  34. 'template' => 'region',
  35. // Функции, которые будут подготавливать переменные для шаблонизации
  36. 'preprocess functions' => array(
  37. 'template_preprocess',
  38. 'mytheme_preprocess',
  39. 'mytheme_preprocess_region',
  40. 'mytheme_process',
  41. ),
  42. ),
  43. // Выносим header и footer в отдельные шаблоны
  44. 'header' => array(
  45. 'arguments' => array('elements' => NULL),
  46. 'path' => drupal_get_path('theme', 'mytheme') . '/templates',
  47. 'template' => 'header',
  48. 'preprocess functions' => array(
  49. 'template_preprocess',
  50. 'mytheme_preprocess',
  51. 'mytheme_preprocess_header',
  52. 'mytheme_process',
  53. ),
  54. ),
  55. 'footer' => array(
  56. 'arguments' => array('elements' => NULL),
  57. 'path' => drupal_get_path('theme', 'mytheme') . '/templates',
  58. 'template' => 'footer',
  59. 'preprocess functions' => array(
  60. 'template_preprocess',
  61. 'mytheme_preprocess',
  62. 'mytheme_preprocess_footer',
  63. 'mytheme_process',
  64. ),
  65. ),
  66. );
  67. }
  68. return array();
  69. }


Определим theme_blocks($region). Функция возвращает набор блоков, доступных для текущего пользователя в заданном регионе.
Copy Source | Copy HTML
  1. function mytheme_blocks($region) {
  2. if ($region) {
  3. $output = '';
  4. if ($list = block_list($region)) {
  5. foreach ($list as $key => $block) {
  6. $output .= theme('block', $block);
  7. }
  8. }
  9. // Контент для данного региона
  10. $output .= drupal_get_content($region);
  11. $elements['#children'] = $output;
  12. $elements['#region'] = $region;
  13. // Возвращаем темизированный регион с блоками. Используется region.tpl.php
  14. return $output ? theme('region', $elements) : '';
  15. }
  16. }


Определим template_preprocess(&$variables, $hook). Функция подготавливает переменные, которые будут переданы в шаблон.
Copy Source | Copy HTML
  1. function mytheme_preprocess(&$vars, $hook) {
  2. $key = ($hook == 'page' || $hook == 'maintenance_page') ? 'body_classes' : 'classes';
  3. if (array_key_exists($key, $vars)) {
  4. if (is_string($vars[$key])) {
  5. $vars['classes_array'] = explode(' ', $vars[$key]);
  6. unset($vars[$key]);
  7. }
  8. }
  9. else {
  10. $vars['classes_array'] = array($hook);
  11. }
  12. // Тут немного магии.
  13. // Для каждого хука типа hook_preprocess_anything() мы ищем соответствующий файл
  14. // в каталоге preprocess и вызываем его
  15. $name = 'preprocess/preprocess-'. str_replace('_', '-', $hook) .'.inc';
  16. if (is_file(drupal_get_path('theme', 'mytheme') . '/' . $name)) {
  17. include($name);
  18. }
  19. }


Определим HOOK_process() описанный ранее.
Copy Source | Copy HTML
  1. function mytheme_process(&$vars, $hook) {
  2. if (array_key_exists('classes_array', $vars)) {
  3. // Сливаем в строку все стили для элемента
  4. $vars['classes'] = implode(' ', $vars['classes_array']);
  5. }
  6. }


Определим функцию, которая вернет путь к нашей теме.
Copy Source | Copy HTML
  1. function _mytheme_path() {
  2. static $path = FALSE;
  3. if (!$path) {
  4. $matches = drupal_system_listing('mytheme\.info$', 'themes', 'name', 0);
  5. if (!empty($matches['mytheme']->filename)) {
  6. $path = dirname($matches['mytheme']->filename);
  7. }
  8. }
  9. return $path;
  10. }


Ну и наконец, добавим пару функций для обработки классов и id для страниц
Copy Source | Copy HTML
  1. if (!function_exists('drupal_html_class')) {
  2. function drupal_html_class($class) {
  3. $class = strtr(drupal_strtolower($class), array(' ' => '-', '_' => '-', '/' => '-', '[' => '-', ']' => ''));
  4. $class = preg_replace('/[^\x{002D}\x{0030}-\x{0039}\x{0041}-\x{005A}\x{005F}\x{0061}-\x{007A}\x{00A1}-\x{FFFF}]/u', '', $class);
  5. return $class;
  6. }
  7. }
  8. if (!function_exists('drupal_html_id')) {
  9. function drupal_html_id($id) {
  10. $id = strtr(drupal_strtolower($id), array(' ' => '-', '_' => '-', '[' => '-', ']' => ''));
  11. $id = preg_replace('/[^A-Za-z0-9\-_]/', '', $id);
  12. return $id;
  13. }
  14. }


Часть 2, Часть 3
Tags:drupalтемизациядизайнсоздание темы
Hubs: Drupal
+45
28.5k 221
Comments 16

Popular right now

Web designer
from 80,000 ₽SellaviМосква
Старший веб-дизайнер
from 150,000 to 200,000 ₽Институт Музыкальных ИнициативМосква
Product designer
from 60,000 to 80,000 ₽Madrobots.ruБарнаул

Top of the last 24 hours