
Create a theme for Drupal 6. Part 1

To create Drupal themes on the Internet, you can find several articles (a good article, I advise you to read ), but usually it all ends with a banal set of templates and an info file. In this topic, I will try to tell in an accessible way how to create a flexible and not the simplest topic.
Start
First, we need to create a directory in the sites / all / themes directory with the name of our theme. I named the theme mytheme and created the sites / all / themes / mytheme directory .
In the created directory we create css directories for styles, js for scripts, images for pictures, templates for templates, preprocess about this later. We also create a template.php file in which we will write all the logic of the topic and mytheme.info to describe the topic. You can also add favicon.ico and logo.png .
mytheme.info
The file contains all the information needed by the kernel to work with the theme.
Create a file with the following contents:
Copy Source | Copy HTML- ; Название темы, как оно будет отображаться в админке
- name = MyTheme
- ; Описание темы
- description = Моя новая тема
- ; Версия ядра
- core = 6.x
- ; Шаблонизатор используемый темой, по умолчанию phptemplate
- engine = phptemplate
- ; Версия темы
- version = 6.x-1.01
-
- ; Путь к скриншоту темы
- screenshot = images/screenshot.png
-
- ; Регионы темы, в которые можно будет вставлять блоки
- regions[sidebar_right] = Right sidebar
- regions[sidebar_left] = Left sidebar
- regions[header_line] = Line in header
- regions[footer_line] = Line in footer
- regions[content_top] = Content top
- regions[content_bottom] = Content bottom
- regions[content_right] = Content right
- regions[comments_rigth] = Comments right
- regions[page_bottom] = Page bottom
-
- ; Настройки темы, которые будут доступны из админки
- ;features[] = name
- features[] = node_user_picture
- features[] = comment_user_picture
- features[] = search
- ;features[] = favicon
- ;features[] = primary_links
- ;features[] = secondary_links
-
- ; Стили
- stylesheets[all][] = css/blocks.css
- stylesheets[all][] = css/comments.css
- stylesheets[all][] = css/fields.css
- stylesheets[all][] = css/forms.css
- stylesheets[all][] = css/html-reset.css
- stylesheets[all][] = css/layout.css
- stylesheets[all][] = css/messages.css
- stylesheets[all][] = css/navigation.css
- stylesheets[all][] = css/nodes.css
- stylesheets[all][] = css/pages.css
- stylesheets[all][] = css/tabs.css
-
- ;stylesheets[print][] = css/print.css
-
- ;stylesheets[handheld][] = css/mobile.css
- ;stylesheets[only screen and (max-device-width: 480px)][] = css/iphone.css
-
- ; Скрипты
- ;scripts[] = js/script.js
This is enough for Drupal to see and recognize our topic. I chose this set of styles and regions, because I find it convenient. You can change to your taste.
template.php
The most delicious part of the topic. In this file we will write all the logic - hooks.
First, define HOOK_theme () .
Copy Source | Copy HTML- function mytheme_theme(&$existing, $type, $theme, $path) {
- // Определяем базовую тему, если наша тема дочерняя
- static $base_themes = array();
- $base_themes[] = $theme;
-
- // Добавляем хук "process", который будет вызываться после "preprocess".
- if ($type == 'theme') {
- foreach (array_keys($existing) as $hook) {
- if (function_exists($theme . '_preprocess')) {
- $existing[$hook]['preprocess functions'][] = $theme . '_preprocess';
- }
- if (function_exists($theme . '_preprocess_' . $hook)) {
- $existing[$hook]['preprocess functions'][] = $theme . '_preprocess_' . $hook;
- }
- foreach ($base_themes as $base_theme) {
- if (function_exists($base_theme . '_process')) {
- $existing[$hook]['preprocess functions'][] = $base_theme . '_process';
- }
- if (function_exists($base_theme . '_process_' . $hook)) {
- $existing[$hook]['preprocess functions'][] = $base_theme . '_process_' . $hook;
- }
- }
- }
- }
-
- // Добавляем препроцессы только для данной темы, они не распространятся на дочерние темы
- if ($theme == 'mytheme') {
- return array(
- // Добавляем регион. Это необходимо, чтобы мы могли использовать шаблоны для регионов
- 'region' => array(
- // Аргументы, которые будут доступны
- 'arguments' => array('elements' => NULL),
- // Путь к шаблону
- 'path' => drupal_get_path('theme', 'mytheme') . '/templates',
- // Название шаблона. Полное имя файла будет region.tpl.php
- 'template' => 'region',
- // Функции, которые будут подготавливать переменные для шаблонизации
- 'preprocess functions' => array(
- 'template_preprocess',
- 'mytheme_preprocess',
- 'mytheme_preprocess_region',
- 'mytheme_process',
- ),
- ),
- // Выносим header и footer в отдельные шаблоны
- 'header' => array(
- 'arguments' => array('elements' => NULL),
- 'path' => drupal_get_path('theme', 'mytheme') . '/templates',
- 'template' => 'header',
- 'preprocess functions' => array(
- 'template_preprocess',
- 'mytheme_preprocess',
- 'mytheme_preprocess_header',
- 'mytheme_process',
- ),
- ),
- 'footer' => array(
- 'arguments' => array('elements' => NULL),
- 'path' => drupal_get_path('theme', 'mytheme') . '/templates',
- 'template' => 'footer',
- 'preprocess functions' => array(
- 'template_preprocess',
- 'mytheme_preprocess',
- 'mytheme_preprocess_footer',
- 'mytheme_process',
- ),
- ),
- );
- }
- return array();
- }
Define theme_blocks ($ region) . The function returns the set of blocks available for the current user in the specified region.
Copy Source | Copy HTML- function mytheme_blocks($region) {
- if ($region) {
- $output = '';
-
- if ($list = block_list($region)) {
- foreach ($list as $key => $block) {
- $output .= theme('block', $block);
- }
- }
-
- // Контент для данного региона
- $output .= drupal_get_content($region);
-
- $elements['#children'] = $output;
- $elements['#region'] = $region;
-
- // Возвращаем темизированный регион с блоками. Используется region.tpl.php
- return $output ? theme('region', $elements) : '';
- }
- }
Define template_preprocess (& $ variables, $ hook) . The function prepares the variables that will be passed to the template.
Copy Source | Copy HTML- function mytheme_preprocess(&$vars, $hook) {
- $key = ($hook == 'page' || $hook == 'maintenance_page') ? 'body_classes' : 'classes';
-
- if (array_key_exists($key, $vars)) {
- if (is_string($vars[$key])) {
- $vars['classes_array'] = explode(' ', $vars[$key]);
- unset($vars[$key]);
- }
- }
- else {
- $vars['classes_array'] = array($hook);
- }
-
- // Тут немного магии.
- // Для каждого хука типа hook_preprocess_anything() мы ищем соответствующий файл
- // в каталоге preprocess и вызываем его
- $name = 'preprocess/preprocess-'. str_replace('_', '-', $hook) .'.inc';
- if (is_file(drupal_get_path('theme', 'mytheme') . '/' . $name)) {
- include($name);
- }
- }
Define the HOOK_process () described earlier.
Copy Source | Copy HTML- function mytheme_process(&$vars, $hook) {
- if (array_key_exists('classes_array', $vars)) {
- // Сливаем в строку все стили для элемента
- $vars['classes'] = implode(' ', $vars['classes_array']);
- }
- }
-
Define a function that returns the path to our topic.
Copy Source | Copy HTML- function _mytheme_path() {
- static $path = FALSE;
- if (!$path) {
- $matches = drupal_system_listing('mytheme\.info$', 'themes', 'name', 0);
- if (!empty($matches['mytheme']->filename)) {
- $path = dirname($matches['mytheme']->filename);
- }
- }
- return $path;
- }
-
And finally, add a couple of functions for handling classes and id for pages
Copy Source | Copy HTML- if (!function_exists('drupal_html_class')) {
- function drupal_html_class($class) {
- $class = strtr(drupal_strtolower($class), array(' ' => '-', '_' => '-', '/' => '-', '[' => '-', ']' => ''));
-
- $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);
-
- return $class;
- }
- }
-
- if (!function_exists('drupal_html_id')) {
- function drupal_html_id($id) {
- $id = strtr(drupal_strtolower($id), array(' ' => '-', '_' => '-', '[' => '-', ']' => ''));
- $id = preg_replace('/[^A-Za-z0-9\-_]/', '', $id);
- return $id;
- }
- }
Part 2 , Part 3