Изменения темизации в drupal 7 (часть 2)

Продолжение первой части. Мы рассматриваем изменения в темизации drupal 7.

HTML классы генерируются через переменную

Любая тема теперь может вывести $classes из шаблона темы при рендере. Т.е. то что ранее делалось в том же zen'е через function zen_preprocess_page(&$vars, $hook), теперь достигается простым использованием в page.tpl.php такой конструкции:

<div class="<?php print $classes ?>">
  ...
</div>

HTML атрибуты генерируются через переменную

В любой теме вы теперь сможете использовать $attributes, $title_attributes и $content_attributes. RDF-модуль и другие модули могут добавлять важную информацию через эти переменные.

Пример:

<div id="..." class="..."<?php print $attributes; ?>>
  <h2<?php print $title_attributes; ?>>...</h2>
  <div class="content"<?php print $content_attributes; ?>>...</div>
</div>

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

Переменные process functions могут использоваться для любых хуков темы.

К примеру теперь можно будет назначить правило, дабы во всех меню ссылки, начинающиеся с http:/https: открывались в новом окне. Таким вот образом:

<?php
function mytheme_preprocess_menu_link(&$variables) {
  if (
    substr($variables['element']['#href'], 0, 5) == 'http:' ||
    substr($variables['element']['#href'], 0, 6) == 'https:'
  ) {
    $variables['element']['#localized_options']['attributes']['target'] = '_blank';
  }
}
?>

Все функции тем теперь имеют унифицированный аргумент, $variables

В drupal 6 обходились через описание аргументов в hook_theme(). В drupal 7 упростили процедуру.

Как было в drupal 6:

<?php
function drupal_common_theme() {
  return array(
    ...
    'table' => array(
      'arguments' => array('header' => NULL, 'rows' => NULL, 'attributes' => array(), 'caption' => NULL),
    ),
    ...
  );
}
 
function theme_table($header, $rows, $attributes = array(), $caption = NULL) {
  ...
}
?>

Как стало в drupal 7

<?php
function drupal_common_theme() {
  return array(
    ...
    'table' => array(
      'variables' => array('header' => NULL, 'rows' => NULL, 'attributes' => array(), 'caption' => NULL, 'colgroups' => array(), 'sticky' => TRUE),
    ),
    ...
  );
}
 
function theme_table($variables) {
  $header = $variables['header'];
  $rows = $variables['rows'];
  $attributes = $variables['attributes'];
  $caption = $variables['caption'];
  $colgroups = $variables['colgroups'];
  $sticky = $variables['sticky'];
  ...
}
?>

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

Имена функций должны начинаться имени темы

Функции в template.php теперь должны использовать соответствующее имя темы. Теперь не надо использовать phptemplate_function.

Все CSS и JavaScript файлы должны быть описаны в .info файле

В drupal6 style.css и script.js подключались автоматически. Теперь этого не будет. Требуется указывать все файлы стилей и скриптов. Опять же - это шаг к большей строгости кода.

Переименован $block->content в $content внутри block.tpl.php

В принципе, без комментариев. Хотя с этим связана довольно долгая история, с которой можно ознакомиться на drupal.org

Раздельный рендеринг шаблона

Из заголовка не понятно "о чем это". Поясню. В drupal 7 появляется замечательная функция render(). И вторая замечательная функция hide(). Что они делают - будет ясно из примера. Ниже приведен код из node.tpl.php

<div class="content">
  <?php
    // Спрячем комментарии и ссылки. Потом мы сможем вывести их отдельно.
    hide($content['comments']);
    hide($content['links']);
    print render($content);
  ?>
</div>
 
<?php print render($content['links']); ?>
<?php print render($content['comments']); ?>. 

render() возвращает все объекты, содержащиеся в $content. Таким образом print render($content) работает как print $content в drupal 6. Когда же мы хотим вывести отдельные элементы $content, мы делаем это с помощью такого кода(для ссылок): print render($content['links']). Если нам надо спрятать отдельные элементы, мы делаем это с помощью функции hide() перед вызовом print render($content).

В ядро добавлен jQuery UI (1.7)

Файлы JQuery UI вы можете найти в misc/ui. И можете добавлять css и js из данной библиотеки через drupal_add_js() и drupal_add_css().