Вы здесь

Обновление тем версии 6.x до версии 7.x

Стандартные блоки получили читаемые идентификаторы CSS ID

Стандартные блоки получили идентификаторы, которые позволяют определить назначение блока из названия его идентификатора.

Блок Drupal 6 CSS ID Drupal 7 CSS ID
Новое в блогах block-blog-0 block-blog-recent
Меню книги block-book-0 block-book-navigation
Новые комментарии block-comment-0 block-comment-recent
Обсуждаемые темы block-forum-0 block-forum-active
Новое на форуме block-forum-1 block-forum-new
Выбор языка block-locale-0 block-locale-language-switcher
Лента сайта block-node-0 block-node-syndicate
Последний опрос block-poll-0 block-poll-recent
Автор документа block-profile-0 block-profile-author-information
Форма поиска block-search-0 block-search-form
Популярное содержание block-statistics-0 block-statistics-popular
Сделано на Drupal block-system-0 block-system-powered-by
Вход в аккаунт block-user-0 block-user-login
Навигация block-user-1 block-user-navigation
Новые пользователи block-user-2 block-user-new
Сейчас на сайте block-user-3 block-user-online

Соответственно изменились и описания стилей.

Drupal 6:

/* Make the text in the user login block bigger. */
#block-user-0 {
  font-size: 1.5em;
}

Drupal 7:

/* Make the text in the user login block bigger. */
#block-user-login {
  font-size: 1.5em;
}

Основные и дополнительные ссылки переименованы в основное и дополнительное меню

В темах, которые используют эти меню, должны быть обновлены их переменные.

Drupal 6 (page.tpl.php):

<div id="menu">
  <?php if (isset($secondary_links)) { ?><?php print theme('links', $secondary_links, array('class' => 'links', 'id' => 'subnavlist')); ?><?php } ?>
  <?php if (isset($primary_links)) { ?><?php print theme('links', $primary_links, array('class' => 'links', 'id' => 'navlist')) ?><?php } ?>
</div>

Drupal 7 (page.tpl.php):

<div id="menu">
  <?php if (isset($secondary_menu)) { ?><?php print theme('links', $secondary_menu, array('class' => 'links', 'id' => 'subnavlist')); ?><?php } ?>
  <?php if (isset($main_menu)) { ?><?php print theme('links', $main_menu, array('class' => 'links', 'id' => 'navlist')) ?><?php } ?>
</div>

You will also need to make the appropriate variable name changes if your theme's theme.info is defining features[]. Defining renamed or replaced features may cause all features to render as blank or empty arrays.

Также нужно изменить название переменных в .info-файле темы, если они определены в features[].

Drupal 6:

  features[] = primary_links
  features[] = secondary_links

Drupal 7:

  features[] = main_menu
  features[] = secondary_menu

Если в .info-файле темы определена переменная features[] = mission, то учтите, что эта возможность была удалена и заменена переменной $mission, которая может быть использована в шаблоне страницы.

Переменная $taxonomy удалена из шаблона node.tpl.php

Раньше, переменная $taxonomy использовалась для доступа к массиву невыводимых ссылок таксономии текущего документа. В Drupal 7, все ссылки перемещены в объект $node. Термины таксономии управляются модулем Field, что означает, что доступ к терминам осуществляется тем же образом, что и к другим полям документа. Тип поля для ссылок на термины называется «Ссылка на термин». Это поле можно добавить в тип документов так же, как и любой другое поле. У каждого поля есть системное название, которое начинается с префикса field_. Например, если поле ссылки на термин добавлено для словаря Animals, вы можете выбрать для этого поля системное название field_animals. Чтобы вывести термины field_animals, их нужно обработать через функцию render():

<?php
render
($content['field_animals']);
?>

Для доступа к массиву невыводимых ссылок таксономии теперь используется запись node->content['links']['terms']['#value']. Выводимые ссылки таксономии не затронуты; шаблон node.tpl.php может получить к ним доступ через переменную $terms как и ранее. В шаблонах тем для Drupal 6 нужно заменить переменную >$taxonomy на переменную $terms.

Drupal 6:

<?php if ($taxonomy): ?>
   <div class="terms"><?php print $terms ?></div>
<?php endif;?>

Drupal 7:

<?php if ($terms): ?>
  <div class="terms"><?php print $terms ?></div>
<?php endif;?>

Соответствие стандарту RDF требует изменений в начале файла page.tpl.php

Drupal 7 использует вывод RDF, который требует следующих изменений в шаблоне html.tpl.php.

  • DOCTYPE нужно изменить на XHTML+RDFa 1.0
  • Для соответствия стандарту XHTML 1.1, атрибут lang нужно удалить, оставив только xml:lang
  • Префиксы пространства имён RDF используемые в HTML-документе должны быть преобразованы в теге html и содержаться в переменной $rdf_namespaces
  • Профиль GRDDL нужно определить в теге <head>.

Drupal 6:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<?php print $language->language ?>" lang="<?php print $language->language ?>" dir="<?php print $language->dir ?>">
  <head>

Drupal 7:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML+RDFa 1.0//EN"
  "http://www.w3.org/MarkUp/DTD/xhtml-rdfa-1.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<?php print $language->language ?>" dir="<?php print $language->dir ?>"
  <?php print $rdf_namespaces ?>>
  <head profile="<?php print $grddl_profile ?>">

Класс clear-block переименован в clearfix

Наименование класса clear-block использовалось в Drupal для тех же целей, в которых используется класс clearfix в среде разработчиков CSS. Также, использование слова block смущало пользователей Drupal, которые больше знакомы с системой блоков Друпала, чем со свойствами в наборах правил CSS. Название этого класса изменено для того, чтобы не смущать новых разработчиков тем сообщества Drupal.

Drupal 6:

<div class="clear-block">
  ...
</div>

Drupal 7:

<div class="clearfix">
  ...
</div>

Шаблон box.tpl.php удалён

У тех частей содержания, которые использовали этот шаблон, теперь есть свои функции. Списки результата поиска теперь оформляются с помощью функции theme_search_results_listing(), а бокс формы комментариев с помощью функции theme_comment_form_box().

Переменная $help стала регионом

В Drupal 7 к стандартным регионам (left, right, content, header, footer), добавлен новый регион [help]. По умолчанию, содержание этого региона соответствует содержанию переменной $help шаблона page.tpl.php в Drupal 6.

regions[help] = Help

Справочный текст окружён в шаблоне block.tpl.php тегом <div>, который используется для его оформления с помощью CSS.

Переменная $mission удалена, взамен введён регион highlight

В Drupal 6 шаблон темы получал специальную переменную $mission, которая занималась выводом миссии (текст вводился на странице Информация о сайте) сайта на его первой странице. Темы Drupal 6 также имели параметр вывода этой переменной на странице настройки темы. В Drupal 7 удалены параметры настройки миссии и переключателя её включения на сайте со страницы тем в пользу более настраиваемых блоков, которые можно разместить в любых регионах и для которых доступно большее количество параметров вывода.

По умолчанию, Drupal 7 теперь включает в себя регион с названием highlight, который теперь используется для вывода миссии. Содержание этого региона окружено тегами <div> в шаблоне block.tpl.php, используются свои классы CSS, что позволяет легко оформить миссию нужным вам образом.

Если в используемой вами дополнительной теме нет этого региона, то достаточно будет лишь добавить этот регион в .info-файл темы точно так же, как и другие регионы.

Друпал 6:

.info-файл:

features[] = mission

Файл page.tpl.php:

<?php print $mission; ?>

Друпал 7:

.info-файл

regions[highlighted] = Highlighted

Файл page.tpl.php:

<?php print render($page['highlighted']); ?>

Переменная $footer_message удалена

В Drupal 6 шаблон темы получал специальную переменную, которая называлась $footer_message и занималась выводом информации в нижней колонке (нижнем регионе). В шаблоне эта переменная обычно использовалась перед переменной $footer. По сути, это сообщение было лишь отдельным блоком и поэтому в Drupal 7 эта переменная удалена в пользу блока, который имеет более широкие настройки.

Для обновления своих тем, просто удалите переменную $footer_message из своих шаблонов.

Если в используемой вами дополнительной теме нет региона $footer, то достаточно будет лишь добавить этот регион в .info-файл темы точно так же, как и другие регионы:

regions[footer] = Footer

Регион content стал обязательным; содержание документа стало блоком

В Drupal 6 переменная $content файла page.tpl.php занималась выводом содержания документа. Содержание документа могло быть окружено регионами и располагающимися в них блоками, но сама эта переменная в другой регион перемещена быть не могла.

В Drupal 7 переменная $content стала полноценным регионом и обязательна для всех тем. Это требование введено из-за того, что при включении темы, Друпал должен знать где разместить основное содержание страницы по умолчанию.

В Drupal 6 можно было разместить блоки только после основного содержания страницы в этом регионе. Единственным путём разместить блок до основного содержания было определение отдельного региона для этих целей. Drupal 7 теперь делает основное содержание страницы таким же блоком как и остальные. Это делает возможным размещение в этом регионе блоков как после, так и до основного содержания без необходимости создания ещё одного региона.

В связи с этими изменениями основное содержание теперь обёрнуто разметкой определённой в шаблоне block.tpl.php. И если ранее класс .block применялся только к блокам расположенным в сайдбарах (левой и правой колонках/регионах), то в Drupal 7 этот класс будет применён и к содержанию документа, поэтому правки требуют .css-файлы, которые описывают класс .block. Вам потребуется конкретизировать этот класс добавив в него название региона, например #left-sidebar .block.

Second phase variable process functions

There are now two sets of variables process functions. The first are the existing "preprocess" functions. The second are "process" functions which are run after preprocessors. All the various prefixes and suffixes apply to this second phase in the exact same way. This is useful when certain variables need to be worked on in two phases.

For example, adding classes into an array for the "preprocess" phase then flattening them into a string in the "process" phase so it's ready to print within a template. See next section.

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

Теперь все шаблоны могут использовать переменную $classes для отображения динамических классов. Динамические классы добавляются с использованием ключа с меткой classes_array:

<?php
function mytheme_preprocess_node(&$vars) {
 
// Add a striping class.
 
$vars['classes_array'][] = 'node-' . $vars['zebra'];
}
?>

Стандартный template_process (вторая фаза процессора) позаботится о выравнивании массива в плоскую строку, делая её пригодной для печати из шаблона. Динамические классы генерируются для общих шаблонов по умолчанию, но благодаря реализации этого механизма, любой шаблон может иметь переменную $classes.

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

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

Все шаблоны теперь могут печатать переменные $attributes, $title_attributes и $content_attributes из шаблона для прорисовки динамических атрибутов. Модуль RDF и другие модули добавляют важную информацию в эти переменные, поэтому важно убедиться, что эти переменные печатаются корректно во всех переопределённых файлах шаблонов. Эти три переменные содержат атрибуты для всех элементов прорисовываемых шаблоном и элементы заголовка и содержания соответственно. Путём добавления атрибутов в эти переменные является скармливание ключевых переменных с меткой attributes_array, title_attributes_array и content_attributes_array.

<?php
function mytheme_preprocess_node(&$vars) {
 
// If the node was saved with a log message and the currently logged in user
  // has permission to view that message, add it as a title attribute (tooltip)
  // when displaying the node.
 
if (!empty($vars['node']->log) && user_access('view revisions')) {
   
$vars['attributes_array']['title'] = $vars['node']->log;
  }

 
// Force the direction of node titles to be left to right, regardless of
  // language or any other settings.
 
$vars['title_attributes_array']['dir'] = 'ltr';
}
?>

Стандартный template_process (вторая фаза процессора) позаботится о выравнивании массива в плоскую строку, делая её пригодной для печати из шаблона. В результате выравнивания будет получена либо пустая строка (если динамические атрибуты не установлены), либо строка в ведущим пробелом. Вследствие этого, переменные атрибутов должны размещаться в шаблоне без пробела от того элемента, с которым они должны выводиться.

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

As is shown in the example, the convention is for the "id" and "class" attributes to be printed explicitly within the template, and for the attributes variables to be used for all other attributes. Therefore, to ensure that no attribute gets printed twice within the same element, the following rules should be followed:

  • Preprocess functions within modules must not add "id" or "class" to the attributes arrays.
  • Preprocess functions within themes may add "id" and/or "class" to the attributes arrays, but if they do so, the theme must also override the corresponding template file and ensure that the same attribute isn't being printed explicitly.
  • Templates must not print any attribute other than "id" or "class" explicitly on any element for which an attributes variable is also being printed. Instead, the theme must use a preprocess function, as shown above.

Variable process functions могут использоваться для всех хуков темизации

В Друпале 6, функции предобработки могли использоваться только для хуков темизации прорисовываемых шаблонами. В Друпале 7, специфичная для хуков предобработка и функции обработки могут использоваться для всех хуков темизации, вне зависимости от того, прорисовываются они шаблоном или функциями. Например, тема может сделать все ссылки меню начинающиеся с 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';
  }
}
?>

Every preprocess function adds to the time it takes to theme the item, so especially for theme functions that get called a lot, keep an eye on performance when adding preprocess functions.

To minimize performance overhead, the non-hook-specific preprocess and process functions are called for templates only. See the API documentation for theme() for the full list of hook-specific and non-hook-specific preprocess and process functions.

У всех функций темизации теперь один аргумент $variables

В Друпале 6, функции темы регистрировали свои аргументы в hook_theme(). В Друпале 7, все все функции темы имеют один аргумент $variables как массив с ключами-переменными и регистрируют ожидаемые ключи внутри массива в hook_theme().

Друпал 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) {
  ...
}
?>

Друпал 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'];
  ...
}
?>

Названия функций должны использовать название темы

Названия функций в файле template.php теперь обязаны совпадать с названием темы. Не стоит использовать phptemplate_function. Это изменение сделано в патче: Die, themeEngineName_ prefix, die!. При обновлении темы, убедитесь что названия функций в файле template.php (и других подключенных файлах) не начинаются с названия движка шаблонов (phptemplate).

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

В Drupal 6, файлы style.css и script.js могли быть включены в тему автоматически, даже если и не были определены в файле .info. В Drupal 7, подключение этих файлов должно быть явно определено в файле .info. Дополнительную информацию об этом изменении вы можете найти в документе Remove default values for stylesheet and scripts includes from system module. Если вашей теме не нужны эти файлы, или нужны и они уже явно определены, то изменений не потребуется.

Переменная $block->content переименована в $content в файле block.tpl.php

Изменение связано с упрощением кода. Подробнее смотрите документ Simplify block rendering.

Подробная прорисовка в шаблонах документов и пользователей

Авторы шаблонов теперь могут печатать части содержания документа и профиля как им удобно, сохраняя при этом совместимость с новыми модулями и добавляемым им новым содержанием. Чтобы сделать это, нужно использовать 2 новых функции: render() и hide(). Пример из шаблона node.tpl.php:

<div class="content">
  <?php
   
// We hide the comments and links now so that we can render them later.
   
hide($content['comments']);
   
hide($content['links']);
    print
render($content);
 
?>

</div>

<?php print render($content['links']); ?>

<?php print render($content['comments']); ?>

Функция render() возвращает все пункты переменной $content. Поэтому, печать render($content) эквивалентна печати $content в Друпале 6. Когда автора шаблона хочет напечатать часть массива $content, он может сделать это использовав render(content['links']). Если печать ссылок идёт после печати всех остальных данных $content, то нужно сначала использовать hide($content['links']) перед вызовом render($content). После этого, ссылки могут быть напечатаны в шаблоне ниже, используя render($content['links']).

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

Вы можете найти файлы jQuery UI в папке misc/ui и при необходимости добавлять файлы JavaScript и CSS используя drupal_add_js() и drupal_add_css(). Если вы обновляете тему, для которой использовался дополнительный модуль работающий с jQuery UI, то обратитесь к документу Converting 6.x modules to 7.x.

JavaScript и CSS прикреплены к drupal_render

(issue) Введена возможность связывать определённые элементы интерфейса с определёнными JavaScript и CSS. Подробнее это сформулировано в документах #attached_js и #attached_css.

Drupal 6:

<?php
function example_admin_settings() {
 
// Add example.admin.css
 
drupal_add_css(drupal_get_path('module', 'example') .'/example.admin.css');
 
// Add some inline JavaScript
 
drupal_add_js('alert("You are visiting the example form.");', 'inline');
 
// Add a JavaScript setting.
 
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(
   
// Add example.admin/css.
   
drupal_get_path('module', 'example') . '/example.admin.css'
 
),
 
$form['#attached_js'] = array(
   
// Add some inline JavaScript.
   
'alert("You are visiting the example form.");' => '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() (которая могла быть обработана через hook_footer() в модуле). Для приведения к общим правилам вывода данных в различных областях страницы, в Друпале 7 стандартизированы регионы и введён регион [page_bottom] вместо переменной $closure. Кроме того, к нему в пару добавляется регион page_top. В Друпале 7 нужно выводить переменную $page_top вверху HTML-тега body и $page_bottom внизу.

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.

regions[content] = Content
regions[help] = Help
regions[page_top] = Page top
regions[page_bottom] = Page bottom

Регионы page_top и page_bottom являются скрытыми. Это означает, что они не показываются на странице блоков. При создании специфичных тем, может быть целесообразным создание дополнительных скрытых регионов. Например, чтобы дать возможность модулям выводить свои данные в большем количестве областей темы без показа блоков на странице блоков. Определить скрытый регион можно используя запись regions_hidden[] в файле .info:

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

В 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 ID применявшиеся к этим переменным:

Drupal 6:

.sidebar-left
.sidebar-right

Drupal 7:

.sidebar-first
.sidebar-second

Переменная $picture переименована в $user_picture

Названия переменной и класса стали более читаемыми. CSS-класс .picture также изменён на .user-picture.

Drupal 6 (user-picture.tpl.php):

<div class="picture">
  <?php print $picture; ?>
</div>

Drupal 7:

<?php if ($user_picture): ?>
  <div class="user-picture">
    <?php print $user_picture; ?>
  </div>
<?php endif; ?>

Новые классы для скрытия содержания, которое должно остаться доступным

Для скрытия элементов страницы введены три новых класса: .element-hidden, .element-invisible и .element-invisible.element-focusable. Каждый класс используется для своих целей:

.element-hidden
Назначение этого класса — скрывать элементы от всех пользователей. Этот класс должен использоваться для элементов, для которых не требуется их немедленный показ на странице. Например, это может быть свёрнутый элемент , который может быть раскрыт пользователем при клике мышкой. Эффект оказываемый этим классом может быть применён и с использованием функций jQuery — show() и hide().

.element-invisible
Назначение этого класса — скрывать элементы визуально, но сохранить их доступность для скрин-ридеров. Этот класс должен использоваться для элементов, которые предназначены для пользователей скрин-ридеров и обычный показ которых на странице неудобен. Информация выводимая в таком классе должна быть краткой, но ёмкой, для избежания излишней перегрузки информацией пользователя скрин-ридера. Этот класс не должен использоваться для фокусируемых элементов (таких как ссылки или элементы форм), так как в этом случае возникнут проблемы как у пользователей скрин-ридеров, так и пользователей которые скрин-ридером не пользуются.

.element-invisible.element-focusable
Назначение этого класса — расширить класс .element-invisible, позволив невидимому элементу попадать в фокус при навигации через клавиатуру.

Переменная JavaScript Drupal.jsEnabled удалена

В Drupal 6 вы могли проверить включенность JavaScript в браузере пользователя и переключиться на jQuery:

if( Drupal.jsEnabled ) {
   // something
}

В Drupal 7, переменная Drupal.jsEnabled удалена, так как вероятность того, что jQuery не будет работать в браузере с включенным JavaScript крайне низка. Подробности вы можете узнать в документе Kill the killswitch.

В PHPTemplate стало возможным использование масок

В Drupal 6 можно было использовать правило определённое для какого-либо одного конкретного шаблона, например page-user.tpl.php или page-user-1.tpl.php. Применение такого правило было громоздким, так как использование одного шаблона могло затронуть данные которые вы не хотели затрагивать или было недостаточным для изменения данных, которые вы хотели изменить.

Согласно новым правилам, в адресах шаблонов теперь можно использовать маску %, например page-user-%.tpl.php. Шаблоны для которых используются явно определённые аргументы (без маски), например page-user-edit.tpl.php, маски не затронут.

Include theme definition explicitly on element when using system_elements()

In system_elements(), it is now necessary to include the theme definition explicity on the element, rather than allowing the system to "fallback" and assign it automatically. Refer to issue 127731.

Добавлена разметка, делающая процесс установки понятным для пользователей скрин-ридеров

В Drupal 6 не было разметки, которая бы показывала текущие задачи процесса установки и их статус. Разница в статусе определялась только CSS. В Drupal 7 добавлена функция theme_task_list(), которая позволяет:

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

<h2 class="element-invisible">Installation tasks</h2>

Добавить задачам текст (done) и (active), который будет также виден только пользователям скрин-ридеров и при выключенных CSS.

<span class="element-invisible">(done)</span>

theme_breadcrumb() добавлены невидимые заголовки

В Drupal 6 не существовало разметки, показывающей пользователям скрин-ридеров то, что данные ссылки являются ссылками навигационной линейки.

В Drupal 7 добавлены заголовки перед списком ссылок навигационной линейки, которые видны пользователям скрин-ридеров и при выключенных CSS. Эти заголовки добавляются к содержанию выводящемуся функциями theme_breadcrumb() и garland_breadcrumb().

<h2 class="element-invisible">You are here</h2>

Изменены атрибуты alt и title значка RSS

В Drupal 6 атрибут alt, который использовался для значка RSS и выводился функцией theme_feed_icon() был статически прописан как Syndicate content. Атрибут title брался из переменной $title.

В Drupal 7 атрибут alt для изображения и атрибут title для ссылки приведён к однообразию. Текст собирается из фразы «Subscribe to $title», к которой прибавляется значение переменной $title обработанной функцией theme_feed_icon().

Вывод формы поиска перемещён из шаблонов тем в блоки

В Drupal 6 форма search_box выводилась путём использования переменной $search_box в файле шаблона темы.

В Drupal 7 форма поиска это часть системы блоков. В шаблонах темы потребуется убрать переменную $search_box и изменить CSS для оформления формы поиска в блоке.

Changes to menu tree, link and tab rendering functions

function menu_tree_output() now returns a structured array of data that can be rendered to html using drupal_render().

Function theme_menu_item_link() and theme_menu_item() have been removed and are effectively replaced by in terms of rendering a menu tree by theme_menu_link(). This is the default function used to render each link in the tree returned by menu_tree_output().

Function theme_menu_local_task() takes different parameters and has a companion theme_menu_local_action() that did not exist in Drupal 6. Both of these function take as the first parameter a menu link array with 'title', 'href', and 'localized_options' keys. In Drupal 6, the first parameter was a string. The change to array was made in order to allow removal of theme_menu_item_link(). The second parameter theme_menu_local_task() of is still a boolean, $active.

theme_links() has a new parameter $heading for accessibility

To meet Web Content Accessibility Guidelines (WCAG) requirements, HTML headings should be used before all content sections, which includes lists of links such as menus. The headers ensure that there is a quick way for assistive technology users to browse through the content; however, most visual users do not need headers on navigation lists, because they can get a sense of the structure by how they are arranged visually on the page. So, the recommendation is to add a header with the "element-invisible" CSS class on it, so that only assistive technology users will notice the header.

It is also important that the header level used (H2, H3, etc.) be appropriately nested in the heading hierarchy. So, it is not recommended to just blindly add an H2 header before each list.

For that reason, the theme_links() function, which is normally called via theme('links', ...), has a new third parameter $heading to add the required heading to a list of links.

For example - Drupal 6 in a typical page.tpl.php file:

<?php print theme('links', $secondary_menu, array('id' => 'secondary-menu', 'class' => array('links', 'clearfix'))); ?>

Drupal 7:

<?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'))); ?>

This will result in a semantically correct and accessible secondary menu in Drupal 7, because an invisible heading has been added:

<h2 class="element-invisible">Secondary menu</h2>

For more information:

theme_links() now allows more targeted overrides

(issue) Modules can now specify a more specific theme callback for links, so that theming of links can be overridden for specific purposes.

For instance, the Node module uses 'links__node' rather than just 'links' as its theme callback when adding links to nodes, so if you want to override just the theming of these links, you can do it in a mytheme_links__node() function, rather than adding some complicated logic to the the generic mytheme_links() function.

Other examples in Drupal core are links__contextual, links__system_main_menu, links__system_secondary_menu, etc.

theme_get_setting() and THEME_settings() have been improved

In Drupal 6, themes could add custom form elements to their “configure theme settings” page at admin/build/themes/settings/THEMENAME. Themes would need to create a theme-settings.php page in their theme directory and use a function with the following syntax:

<?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) { }
?>

In Drupal 7, much more flexibility is given to themes to modify the entire theme settings form. In a theme’s theme-settings.php, themes should now use a THEMENAME_form_system_theme_settings_alter(&$form, $form_state) function. This gives the same power to themes that modules have if they use hook_form_system_theme_settings_alter(). See the “Forms API Quickstart Guide” and “Forms API Reference” on http://api.drupal.org/api/7, as well as the hook_form_FORM_ID_alter() docs to learn the full flexibility of Forms API. Note that themes can no longer use the phptemplate_ prefix to the function; you’ll need to use the actual name of your theme as the prefix.

Here’s an example if you had a “foo” theme and wanted to add a textfield whose default value was “blue bikeshed”:

<?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."),
  );
}
?>

In order to set the default value for any form element you add, you’ll need to add a simple line to your .info file: settings[SETTING_NAME] = DEFAULT_VALUE. For our foo theme, you’d need to edit the foo.info file and this line:

settings[foo_example] = blue bikeshed

In any of your theme’s php files, you can retrieve the value the user set by calling:

<?php
$foo_example
= theme_get_setting('foo_example');
?>

Добавлена функция theme_form_required_marker() для генерации маркеров обязательных элементов формы

Разметка для геренарции маркеров для обязательных элементов формы теперь управляется отдельной функцией theme_form_required_marker() вместо более общей theme_form_element(). Это позволяет многократно использовать маркер в различных местах или изменять разметку без изменения все функции theme_form_element().

theme_link()

Разметка для генерации ссылок теперь управляется функцией theme_link(), вместо ранее применявшегося статичного кодирования в функции l(). This allows you to implement a preprocess function or an override function in order to customize the markup of any link. Doing so may slow down Drupal pages that have many links, so it is recommended to evaluate the benefit vs. the performance trade-off, but the capability exists for sites and themes that need it. This theme function is for customizing the markup of links, generically. Other theme functions exist for customizing links based on context. For example, to customize menu links, override theme_menu_link() instead.

hook_preprocess_link():

<?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;
      }
    }
  }
}
?>

overriding theme_link():

<?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>';
}
?>

Skip to main content links in core themes

To meet Web Content Accessibility Guidelines (WCAG) 2.0 guideline 2.4.1 Bypass Blocks, web pages need to have a link to help keyboard only users and screen readers more easily access the main content of a website.

Garland's implementation is hidden visually, but keep them available for screen-readers. Furthermore, if a keyboard only user tabs through a site the link will become visible as it gains focus.

To hide the skip navigation you can use one the new classes available to hide content in an accessible manner.

Alter hooks available to themes

Hooks that are used to alter content before being displayed on the page are now available to themes. Some important ones to note are:

Note that although technically all of the alter hooks are exposed to the theme, only a given number of them will actually work due to the way the Drupal bootstrap works. If you need to use hook_menu_alter, for example, you'll have to use a module. These hooks can be exposed in template.php.

Drupal 7.x:

<?php
/**
* Implement hook_page_alter().
*/
function mytheme_page_alter(&$page) {
 
// Remove elements from the page.
}

/**
* Implement hook_css_alter().
*/
function mytheme_css_alter(&$css) {
 
// Replace some CSS files with this theme's special CSS.
}
?>

Изменены стили модуля System

Стили, которые связаны с определённым поведением отделены от общих стилей.

  • Стили файлов default.css и system.css объединены вместе в файле system.css. Файл default.css удалён.
  • Был добавлен файл system-behavior.css, который определяет оформление элементов связанных с определёнными действиями, например автозавершением, перетаскиванием пунктов мышкой, прогресс-баром и т.д.

Темам добавлен параметр, определяющий вывод значков для добавления ярлыка страницы

В Drupal 7, при включенном модуле Shortcut, стандартная тема Seven добавляет значки +/– к заголовкам страниц (если у пользователя есть соответствующие права), что позволяет быстро добавлять ярлык этой страницы.

Видимость этих значков определяется параметрами темы. Если вы хотите, чтобы эти значки показывались при включении модуля Shortcut, то в .info-файл темы нужно добавить следующий код:

settings[shortcut_module_link] = 1

Для перекрытия шаблонов используются два дефиса вместо одного

В Drupal 6, шаблоны могли быть целенаправленно перекрыты. Например, тема могла содержать шаблон node-article.tpl.php, который использовался только для типа документов article. В Drupal 7, необходимо будет переименовать такой шаблон с использованием в его названии двух дефисов, т.е. в node--article.tpl.php. Один дефис по-прежнему используется для разделения слов, например user-picture.tpl.php или node--long-content-type-name.tpl.php. Таким образом, два дефиса в названии шаблона всегда говорят о целенаправленном перекрытии, а не просто о разделении слов дефисами.

Если ваша тема использует функции препроцесса, посмотрите страницу http://drupal.org/update/modules/6/7#theme_hook_suggestions_2, на которой рассказано как это изменение затронет вашу тему.

CSS-файлы иногда загружаются через @import, иногда через тег LINK

До Drupal 6, CSS-файлы обычно добавлялись на страницу с использованием оператора @import внутри тегов STYLE. Drupal 6 стал использовать тег LINK. В Drupal 7, теги LINK используются в случае включения параметра «Собирать и сжимать все CSS-файлы в один файл», но оператор @import иногда используется и когда этот параметр выключен. Необходимость этого вызвана ограничением браузера Internet Explorer на количество загружаемых файлов, так как он может загрузить только первый 31 тег, которые добавляют CSS-файлы. Информацию о том, когда используются теги LINK и когда операторы @import, можно найти в документации по API, на странице drupal_pre_render_styles().

CSS-файлы для определённых браузеров добавляются с использованием drupal_add_css()

Drupal 7 предоставляет возможность определить ключи для браузеров при использовании drupal_add_css().

Drupal 6

template.php:

<?php
...
function
phptemplate_get_ie_styles() {
  global
$language;

 
$iecss = '<link type="text/css" rel="stylesheet" media="all" href="'. base_path() . path_to_theme() .'/fix-ie.css" />';
  if (
$language->direction == LANGUAGE_RTL) {
   
$iecss .= '<style type="text/css" media="all">@import "'. base_path() . path_to_theme() .'/fix-ie-rtl.css";</style>';
  }

  return
$iecss;
}
...
?>

page.tpl.php:

<?php
...
<?
php print $styles ? >
<!--[if
lt IE 7]>
  <?
php print phptemplate_get_ie_styles(); ? >
<![endif]-->
...
?>

Drupal 7

template.php:

<?php
...
function
garland_preprocess_html(&$vars) {
  ...
 
drupal_add_css(path_to_theme() . '/fix-ie.css', array('weight' => CSS_THEME, 'browsers' => array('IE' => 'lt IE 7', '!IE' => FALSE), 'preprocess' => FALSE));
}
...
?>

Подробную информацию о ключах IE и !IE, см. в документации по API на странице drupal_pre_render_conditional_comments().

Рекомендуется всегда использовать drupal_add_css() для добавления CSS-файлов, т.к. это позволяет знать точное количество добавляемых файлов. Эта информация может быть важна при работе с Internet Expolore и связана с ограничениями этого браузера, который позволяет загружать только первый 31 тег LINK/STYLE.

Targeted overrides (suggestions) available for theme_menu_link() and theme_menu_tree()

In addition to other changes to menu rendering, a Drupal 7 theme can implement a THEMENAME_menu_tree__MENU_NAME() and/or THEMENAME_menu_link__MENU_NAME() function to override theme_menu_tree()/theme_menu_link() for a specific menu. For example, THEMENAME_menu_link__management() would override theme_menu_link() for links within the "Management" menu. This is similar to how "node--article.tpl.php" overrides "node.tpl.php".

theme_submenu() was removed

Drupal core does not provide theme_submenu() anymore.

New $title_prefix and $title_suffix template variables

Templates in Drupal 7 have two new standard variables, $title_prefix and $title_suffix, which are renderable arrays that contain output intended to be displayed before or after (respectively) the main title tag that appears in the template.

All standard templates that potentially have a title (e.g., nodes, blocks, comments, the main page.tpl.php file, etc.) should render these variables. It is important that the variables be rendered even if the title itself is not being displayed, since the variables might contain important data added by modules (for example, contextual links) associated with the template as a whole.

Example (from page.tpl.php):

<?php print render($title_prefix); ?>
<?php if ($title): ?><h1 class="title" id="page-title"><?php print $title; ?></h1><?php endif; ?>
<?php print render($title_suffix); ?>

theme_node_form() was removed

Drupal core does not provide theme_node_form() anymore. Node forms now have a CSS classes of .node-form and .node-TYPE-form for facilicate simple node type specific styling of the node form.

node_get_types() renamed to node_type_get_types()

In template.php, replace:

foreach (node_get_types() as $type => $name) {
unset($settings['toggle_node_info_' . $type]);
}

with:

foreach(node_type_get_types() as $type => $name) {
unset($settings['toggle_node_info_'. $type]);
}

Core themes now contain "package = Core" in their .info files

Each core theme now contains the line: package = Core in their
.info files. This is a core only property that was added to
to help the Update Manager module identify core modules and themes. It should
not be used in custom or contributed themes.

search-result.tpl.php now uses proper H3 headings for search result titles

<h3> heading elements are now used to wrap each search result title to allow for heading based navigation for keyboard only users (accessibility improvement). This required a change from a DL list to an OL list with changes in two templates - search-results.tpl.php and seach-result.tpl.php.

Rendering was pushed to the last possible moment in search results theming, resulting in more changes to these templates and the pre-processing functions. One note: the $type variable is now $module (this variable is not used in the default search result markup).

Drupal 6 markup for search-results.tpl.php:

<dl class="search-results <?php print $type; ?>-results">
  <?php print $search_results; ?>
</dl>
<?php print $pager; ?>

Drupal 7 markup for search-results.tpl.php:

<?php if ($search_results) : ?>
  <h2><?php print t('Search results');?></h2>
  <ol class="search-results <?php print $module; ?>-results">
    <?php print $search_results; ?>
  </ol>
  <?php print $pager; ?>
<?php else : ?>
  <h2><?php print t('Your search yielded no results');?></h2>
  <?php print search_help('search#noresults', drupal_help_arg()); ?>
<?php endif; ?>

Drupal 6 markup for search-result.tpl.php:

<dt class="title">
  <a href="<?php print $url; ?>"><?php print $title; ?></a>
</dt>
<dd>
  <?php if ($snippet) : ?>
    <p class="search-snippet"><?php print $snippet; ?></p>
  <?php endif; ?>
  <?php if ($info) : ?>
  <p class="search-info"><?php print $info; ?></p>
  <?php endif; ?>
</dd>

Drupal 7 markup for search-result.tpl.php:

<li class="<?php print $classes; ?>"<?php print $attributes; ?>>
  <?php print render($title_prefix); ?>
  <h3 class="title"<?php print $title_attributes; ?>>
    <a href="<?php print $url; ?>"><?php print $title; ?></a>
  </h3>
  <?php print render($title_suffix); ?>
  <div class="search-snippet-info">
    <?php if ($snippet) : ?>
      <p class="search-snippet"<?php print $content_attributes; ?>><?php print $snippet; ?></p>
    <?php endif; ?>
    <?php if ($info) : ?>
      <p class="search-info"><?php print $info; ?></p>
    <?php endif; ?>
  </div>
</li>

The corresponding pre-processing functions for search results have also changed.

The name attribute in a and map elements is invalid

Due to Drupal 7's XHTML+RDFa 1.0 doctype (which inherits the HTML 1.1 doctype), the HTML output should be compatible with XHTML 1.1, in particular there should be no name attribute in the a and map HTML elements.

Друпал 6:

<a id="new" name="new">

Друпал 7:

<a id="new">

PHPTemplate is now the default theme engine

In Drupal 6, specifying the theme engine in .info files was required:

engine = phptemplate

In Drupal 7, this line is no longer necessary because it is assumed by default. You may safely remove it from your .info file.

Themes using the Smarty engine are not affected, and PHP only themes may still be used by specifying "theme" as the engine:

engine = theme

Custom regions must be printed differently in page.tpl.php

In Drupal 6, when you wanted to print a region you had just made, you just put this into your page.tpl.php:

<?php
print $foo_sidebar;
?>

In Drupal 7, all of the regions you wish to add must be printed using render and the page variable:

<?php
print render($page['foo_sidebar']);
?>

Thumbnail size has changed

The Appearance page in Drupal 7 (Themes in Drupal 6) was substantially reorganized. Accordingly, the size of the thumbnail to include with a theme in Drupal 7 changed. In Drupal 7, the thumbnail file should be 294px wide by 219px tall. See http://drupal.org/node/647754 for instructions on how to make your thumbnail file.

$show_blocks theme variable has been removed

The $show_blocks theme variable for pages, which used to be FALSE on pages such as 404 errors to indicate that the sidebars should not be shown, has been removed in Drupal 7. The reasoning was that it wasn't really possible for the theme system to know, for a given theme, which regions were "non-essential sidebars" and shouldn't be shown, and which were essential regions (navigation etc.).

In addition, theme('maintenance_page') no longer has a $show_blocks argument.

Regions are now rendered with their own TPL file: region.tpl.php

(issue) All theme regions, when rendered in the page, are rendered using a new region.tpl.php file. This ensures that regions are rendered consistently, and the template_preprocess_region() function ensures that each region has a consistent class attribute applied to it (classes: region, region-REGIONNAME).

Example - Drupal 6 - page.tpl.php

<div id="header-region" class="clear-block"><?php print $header; ?></div>

Drupal 7:

      <?php print render($page['header']); ?>

New html.tpl.php file

html.tpl.php takes over part of the Drupal 6 page.tpl.php, by providing the structure for the HTML header (the <!DOCTYPE> and the <html>, <head>, and <body> elements. See the documentation for html.tpl.php at api.drupal.org and the source code for html.tpl.php for the default html.tpl.php file, which of course can be overridden in a theme, just like any other tpl.php file.

HTML rendering of form elements has different CSS classes

Issue: The HTML rendering of form elements has changed, in that they have different CSS classes applied to the surrounding DIV: .form-type-TYPE and .form-item-NAME. Previously, the assigned classes were .form-item-TYPE and .NAME-wrapper. In both cases, TYPE is the #type component of the form element, and NAME is the array key. For example, in:

$form['body'] = array(
  '#type' => 'textarea',
  ...
);

TYPE would be textarea, and NAME would be body. (For multi-word types and names, underscores are converted to hyphens.)

Local tasks and actions can now be altered

Previously, theme_menu_local_tasks() took no $variables, so preprocess functions on it were impossible. Modules can now alter the primary and secondary tabs using preprocess or process functions.

Themes that overrode the old definition of theme_menu_local_tasks() will need to update their theme declaration to mirror the changes to the default implementation in includes/menu.inc.

theme('node_submitted') and theme('comment_submitted') no longer exist

In Drupal 6, the template_preprocess_node() and template_preprocess_comment() functions called theme('node_submitted') and theme('comment_submitted') respectively, in order to create the "Submitted by" lines, which come into the node.tpl.php and comment.tpl.php files as variable $submitted. In Drupal 7, these two theme calls have been eliminated, and now the submitted information is generated directly in template_preprocess_node() and template_preprocess_comment().

So, if you want to override how the submitted by information is presented in a theme, you have two choices:

In your theme's mytheme_preprocess_node()/comment() function, do something different in place of:

       $variables['submitted'] = t('Submitted by !username on !datetime', array('!username' => $variables['name'], '!datetime' => $variables['date']));

Override node.tpl.php/comment.tpl.php and use the $name and $date variables to do something different in the section:

    <?php if ($display_submitted): ?>
        <div class="submitted">
          <?php print $submitted; ?>
        </div>
      <?php endif; ?>

Комментарии

Изображение пользователя Анонимно

А что такое "скрин-ридер"?