Изменения темизации в drupal 7 (часть 3)
Продолжение первой и второй частей. Мы рассматриваем изменения в темизации drupal 7.
Присоединение JavaScript и CSS для drupal_render
Теперь мы можем отдельным элементам указывать, какие js и css файлы с ними связаны.
Как было в Drupal 6:
<?php function example_admin_settings() { // Добавляем example.admin.css drupal_add_css(drupal_get_path('module', 'example') .'/example.admin.css'); // Добавляем inline-JavaScript drupal_add_js('alert("Вы познакомились с тестовой формой.");', 'inline'); // Добавляем js настройки. drupal_add_js(array('mymodule' => 'example'), 'setting'); $form['example'] = array( '#type' => 'fieldset', '#title' => t('Example'); ); return $form; } ?>
Как будет в Drupal 7:
<?php function example_admin_settings() { $form['#attached_css'] = array( // Добавляем example.admin/css. drupal_get_path('module', 'example') . '/example.admin.css' ), $form['#attached_js'] = array( // Добавляем inline JavaScript. 'alert("Вы познакомились с тестовой формой.");' => 'inline', // Add a JavaScript setting. Note that when the key is a number, the 'data' property will be used. array( 'data' => array('mymodule' => array(...)), 'type' => 'setting' ), ); $form['example'] = array( '#type' => 'fieldset', '#title' => t('Example'); ); return $form; } ?>
$closure станет $page_bottom, новый регион $page_top и скрытые регионы
Drupal 6 располагал специальной переменной $closure, которую выводили обычно в конце HTML body и которая могла быть темизована через theme_footer() . В Drupal 7 пошли путем приведения вывода к одному общему стандарту для различных областей страницы. Что это значит? Что теперь у нас есть регион page_bottom, в котором и выводится переменная $closure, вам не надо теперь прописывать ее специально (ура! бывало, о ней забывали в процессе создания темы, что вызывало минуты размышления "а что тут не так). Также появился регион page_top. Рассмотрим различия в коде:
Drupal 6:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> ... <body class="<?php print $body_classes; ?>"> ... <?php print $closure; ?> </body> </html>
Drupal 7:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML+RDFa 1.0//EN" "http://www.w3.org/MarkUp/DTD/xhtml-rdfa-1.dtd"> ... <body class="<?php print $classes; ?>"> <?php print $page_top; ?> ... <?php print $page_bottom; ?> </body> </html>
Если вы создаете свои произвольные регионы, важно помнить что нужно включить page_top, page_bottom в ваш .info файл (и вообще сделать включение обязательных регионов привычкой при создании тем).
regions[content] = Content regions[help] = Help regions[page_top] = Page top regions[page_bottom] = Page bottom regions[indicators] = Indicators regions_hidden[] = indicators
page_top и page_botoom являются скрытыми регионами (hidden), таким образом они не будут отображаться в админке в разделе администрирования блоков. Может оказаться полезным создание большего количества спрятанных регионов для ваших тем (к примеру для вывода ваших самописных модулей), что вы можете теперь делать в .info файле, массивом regions_hidden[] :
regions[content] = Content regions[help] = Help regions[page_top] = Page top regions[page_bottom] = Page bottom regions[indicators] = Indicators regions_hidden[] = indicators
$left и $right переменные теперь называются $sidebar_first и $sidebar_second; CSS ID соответственно изменились
В drupal 6 сайдбары (колонки, если хотите) назывались $left и $right. В drupal 7 они называются $sidebar_first и $sidebar_second.
Drupal 6
<?php if (!empty($left)): ?> <div id="sidebar-left" class="column sidebar"> <?php print $left; ?> </div> <!-- /sidebar-left --> <?php endif; ?> ... <?php if (!empty($right)): ?> <div id="sidebar-right" class="column sidebar"> <?php print $right; ?> </div> <!-- /sidebar-right --> <?php endif; ?>
Drupal 7
<?php if ($sidebar_first): ?> <div id="sidebar-first" class="column sidebar"><div class="section region"> <?php print $sidebar_first; ?> </div></div> <!-- /.section, /#sidebar-first --> <?php endif; ?> <?php if ($sidebar_second): ?> <div id="sidebar-second" class="column sidebar"><div class="section region"> <?php print $sidebar_second; ?> </div></div> <!-- /.section, /#sidebar-second --> <?php endif; ?>
CSS идентификаторы тоже изменились:
.sidebar-left --> .sidebar-first
.sidebar-right --> .sidebar-second
$picture стала $user_picture, и CSS класс 'picture' изменился на 'user-picture'
$picture выводила изображение (аватарку) из профиля пользователя. Теперь, видимо, решили сделать имя более конкретным и отвечающим нуждам - $user_picture.
Добавились новые классы для скрытия содержимого
Этот пункт - особое "Вау!" от drupal 7 для верстальщика. Добавились 2 класса: .element-hidden и .element-invisible. У каждого свое назначение:
.element-hidden - назначение этого класса скрыть элемент от всех пользователей. Используется для элементов, которые не должны быть показаны сразу после открытия страницы. К примеру это выплывающие/проявляющиеся/еще-как-то-анимированные блоки, меню и т.п. К ним удобно применять jquery show() и hide() функции.
.element-invisible - предназначен для сокрытия элементов визуально. В документации было очень непонятно описано что же это обозначает, и мне пришлось покопаться в коде и обсуждениях на drupal.org. Основная идея в том, чтобы для полновесных браузеров этот элемент не был виден, но обозначался к примеру для парсеров, которые отметают элементы с display:none, или спецефичных устройств с звуковым выводом(их еще называют срин-ридеры, устройства которые озвучивают содержание сайта, часто используются людьми с нарушениями зрения). Чтобы было совсем понятнее, посмотрим как это реализовано в коде (system.css) в drupal 7:
.element-hidden { display: none; } .element-invisible { height: 0; overflow: hidden; position: absolute; }
JavaScript переменная Drupal.jsEnabled удалена
По той причине что больше нет смысла ее использовать. Либо jquery работает, либо нет :) Процет браузеров, который поддерживает джаваскрипт, но не поддерживает jquery исчезающе мал.
PHPTemplate обзавелся wildcard
Нет, правда, я не знаю как это адекватно перевести :) В общем wildcard - групповой символ, когда вы хотите обозначить множественное значение. В поиске зачастую "some*" звездочка это wildcard. В Drupal 6 мы таким образом именовали файлы шаблонов: page-user.tpl.php или page-user-1.tpl.php. И если мы хотели изменить все страницы пользователей мы меняли page-user.tpl.php, невольно изменяя и страницу входа на сайт (login page). В Drupal 7 же будет доступно такое решение в названиях файлов шаблонов: page-user-%.tpl.php. Символ % тут заменяет целочисленные аргументы - т.е. он будет действовать для page-user-1.tpl.php, page-user-2.tpl.php и т.п., но не будет работать для page-user-edit.tpl.php. Что несколько облегчит наши тяжкие раздумья насчет архитектуры сайта :)
Изменена system_elements()
Причина - появившиеся при тестировании баги, связанные с drupal_render().
Дополнительные изменения видимости элементов
В связи с тем что на вооружение drupal7 взят описанный выше класс .element-invisible, теперь при отключенном css будет видно, как проходит инсталляция, на каком этапе сейчас находится установка сайта (ранее при отключенном css все это было проблематично увидеть, аналогично со скрин-ридерами дело обстоит), а также текущее положение пользователя в хлебных крошках.
Изменены атрибуты alt и title у RSS-иконки
В drupal 6 атрибут alt был статично прописан как "Syndicate content", а title параметр брался из переменной $title. В drupal 7 и alt и title содержат один текст, который представляет из себя "Subscribe to " + $title.
Изменился вывод $search_box
Если в drupal 6 форма поиска выводилась в любом месте темы через $search_box, то в drupal 7 эта возможность убрана. Теперь поиск это часть системы блоков. Т.е. форма поиска - элемент блока поиска, и темизоваться будет как соответствующий блок. Что гарантирует дополнительную работу при обновлении d6->d7 людям, которые использовали $search_box.
Изменение в построении меню, ссылок и табов
Изменения связаны с появлением drupal_render(), соответственно функция menu_tree_output() выводит теперь массив элементов для рендера. Функции theme_menu_item_link() и theme_menu_item() были удалены, теперь их заменяют элементы theme_menu_link().
theme_links() обзавелся новым параметром $heading для большей доступности
Вывод будет теперь более гибким. Пока сложно понять, насколько это будет полезным. Выглядеть будет так:
<?php print theme('links', $secondary_menu, array('id' => 'secondary-menu', 'class' => array('links', 'clearfix')), array('text' => t('Secondary menu'), 'level' => 'h2', 'class' => array('element-invisible'))); ?>
Улучшены theme_get_setting() и THEME_settings()
В Drupal 6 можно было добавлять собственные формы (настройки) в admin/build/themes/settings/имятемы. Нужно было создавать файл theme-settings.php в директории темы и использовать следующее решение:
<?php /** * Implementation of THEMEHOOK_settings() function. * * @param $saved_settings * array An array of saved settings for this theme. * @return * array A form array. */ function phptemplate_settings($saved_settings) { } ?>
В drupal 7 все стало несколько более гибким, и теперь в theme-settings.php вы можете использовать функцию THEMENAME_form_system_theme_settings_alter(&$form, $form_state). К примеру, у вас есть тема "foo" и вы хотите добавить текстовое поле с значением по умолчанию "hi all".
<?php function foo_form_system_theme_settings_alter(&$form, $form_state) { $form['caberet_example'] = array( '#type' => 'textfield', '#title' => t('Widget'), '#default_value' => theme_get_setting('foo_example'), '#description' => t("Place this text in the widget spot on your site."), ); } ?>
Для того чтобы установить значение по умолчанию, вы просто добавляете в ваш .info файл строчку:
settings[foo_example] = hi all
и в любом php файле темы вызвать
<?php $foo_example = theme_get_setting('foo_example'); ?>
Маркер для обязательных полей
Теперь для того чтобы отметить какое-либо поле как "обязательное", вы можете использовать новую функцию theme_form_required_marker() . В drupal 6 надо было использовать theme_form_element(), т.е. переопределять эту довольно емкую функцию - теперь эти лишние телодвижения упростили, сделав для такой довольно популярной задачи theme_form_required_marker() .
Новая функция theme_link()
Сделана для упрощения переопределения ссылок. Для тех, кто пользовался hook_preprocess_link() вполне знакома конструкция (для drupal 6):
<?php function mytheme_preprocess_link(&$variables) { // In order to style links differently depending on what they are linking to, // add classes that contain information about the link path. if (strpos($variables['path'], ':') !== FALSE) { // For external links, add a class indicating an external link and a class // indicating the scheme (e.g., for 'mailto:...' links, add a 'link-mailto' // class). $variables['options']['attributes']['class'][] = 'link-external'; $variables['options']['attributes']['class'][] = 'link-' . parse_url($variables['path'], PHP_URL_SCHEME); } else { // For internal paths, add a class indicating an internal link. $variables['options']['attributes']['class'][] = 'link-internal'; if (empty($variables['path']) || $variables['path'] == '<front>') { // Add a class indicating a link to the front page. $variables['options']['attributes']['class'][] = 'link-front'; } else { // For internal links not to the front page, add a class for each part // of the path. For example, for a link to 'admin/structure/block', add // the classes 'link-path-admin', 'link-path-admin-structure', and // 'link-path-admin-structure-block'. $class = 'link-path'; foreach (explode('/', $variables['path']) as $path_part) { $class .= '-' . $path_part; $variables['options']['attributes']['class'][] = $class; } } } } ?>
Как это может выглядеть сейчас в drupal 7? Так:
<?php function mytheme_link($variables) { // Place a span within and outside the anchor tag in order to implement some // special styling. return '<span class="link-wrapper"><a href="' . check_plain(url($path, $options)) . '"' . drupal_attributes($options['attributes']) . '><span class="link-content-wrapper">' . ($options['html'] ? $text : check_plain($text)) . '</span></a></span>'; } ?>
Для "родных тем" ядра будет облегчен доступ к основным ссылкам
Для тех кто работает только с клавиатурой или использует устройства голосового воспроизведения контента(скрин-ридеры).
