The Render APIin Drupal 7
Ефим Web-Evt ЕвтушенкоE-mail: [email protected]: Web-Evt
? Что такое Render API Зачем это нужно Как это работает? Концепция “render arrays” Ключевые свойства render array Как происходит рендеринг страницы Render API в темировании
Обзор доклада
Система, позволяющая преобразовать структурированные массивы данных в строку Произошла от системы рендеринга в Drupal 6 Forms API Формирует весь отдаваемый контент в Drupal 7 Основная функция – drupal_render()
Что такое Render API
/** * Drupal 6 page callback * @return string */function mymodule_drupal6_page() { $items = mymodule_get_items(); $output = theme('mymodule_items', $items); $output .= theme('pager'); return $output;}
/** * Drupal 7 page callback * @return array */function mymodule_drupal7_page() { $items = mymodule_get_items(); $output[] = array( '#theme' => 'mymodule_items', '#items' => $items ); $output[] = array( '#theme' => 'pager' ); return $output;}
Модули могут получить доступ и внести изменения в отдаваемый контент Единая система формирования контента Повторное использование callback функций генерации контента (page-, block-)
Зачем это нужно
Render array – ассоциативный массив данных, построенный по определенному принципу Рендеринг – преобразование массива render array в HTML код Страница Drupal представляет собой огромный массив – render array Рендеринг данных происходит только на самой последней стадии
Концепция “render arrays”
$page = array( '#show_messages' => TRUE, '#theme' => 'page', '#type' => 'page', 'content' => array( 'system_main' => array( /* ... */ ), 'another_block' => array( /* ... */ ), '#sorted' => TRUE, ), 'sidebar_first' => array( // ... ), 'footer' => array( // ... ), // ...);
#type#theme#theme_wrappers#attached#cache#pre_render / #post_render#prefix / #suffix#markup#access#printed
Ключевые свойства render array
#type: элемент, описанный в hook_element_info(). Например, link, radio, checkbox, .. Вы должны описать все необходимые свойства используемого элемента (например, #title и #options для элемента checkboxes)
Render array - #type
#theme: имя вызываемой функции темирования Функция должна отрендерить все дочерние элементы
Render array - #theme
#theme_wrappers: массив функций темирования Обрабатывается после #theme Это позволяет дополнительно обернуть дочерние элементы нужными нам тегами Используется для форм, филдсетов, ..
Render array - #theme_wrappers
<form …> <input type=“checkbox”../> <input type=“text”../></form>
Пример: #theme_wrappers
<form …> <div class=“extra-container”> <input type=“checkbox”../> <input type=“text”../> </div></form>
#attached: присоединить ресурс к элементу Типы ресурсов: JS, CSS, library, … Можно присоединить любую функцию
Render array - #attached
function mymodule_attached_example_page() { // .. some code // attach JS and CSS files $build['#attached'] = array( 'js' => array( drupal_get_path('module', 'taxonomy') . '/taxonomy.js' ), 'css' => array( drupal_get_path('module', 'taxonomy') . '/taxonomy.css' ), ); // attach library $build['#attached']['library'][] = array( 'system', 'drupal.ajax' ); // attach external resource $build['#attached']['js'][] = array( 'http://code.jquery.com/jquery-1.4.2.min.js' => array( 'type' => 'external' ) ); // attach function $build['#attached']['drupal_add_http_header'] = array( array( 'Content-Type', 'application/rss+xml; charset=utf-8' ), ); return $build;}
#attached: присоединить ресурс к элементу Типы ресурсов: JS, CSS, library, … Можно присоединить любую функцию Нет необходимости загружать ресурсы через hook_init() При кэшировании не теряются ресурсы
Render array - #attached
#cache: настройки кэширования элемента Возможность кэширования отдельных частей страницы Свойства:
keys / cid – ключ кэша granularity – кэш по роли, юзеру, странице expire – время жизни bin – хранилище (таблица cache по умолчанию)
Render array - #cache
function mymodule_cache_example_page() { // .. some code $build[] = array( '#theme' => 'mymodule_items', '#items' => array('item1', 'item2’), '#cache' => array( // Drupal will create a cache id with drupal_render_cid_create() 'keys' => array('render_example', 'cache', 'demonstration’), // Cache granularity settings: element has diffecrent cache versions for each page and role 'granularity' => DRUPAL_CACHE_PER_PAGE | DRUPAL_CACHE_PER_ROLE, // Custom cache storage 'bin' => 'cache_mymodule', // Clear cache after next general cache wipe 'expire' => CACHE_TEMPORARY ) ); $build[] = array( '#theme' => 'mymodule_items2', '#items' => array('item1', 'item2’), // Set up caching properties '#cache' => array( // These properties are ignored in favor of cid property //'keys' => array('render_example', 'cache', 'demonstration'), //'granularity' => DRUPAL_CACHE_PER_PAGE | DRUPAL_CACHE_PER_ROLE, 'cid' => 'mymodule_items', // Default cache storage 'bin' => 'cache', // Cache can be cleared only by calling cache_clear_all($cid) 'expire' => CACHE_PERMANENT ) ); return $build;}
drupal_render() – выполняет рендеринг массива; принимает единственный аргумент – массив render array render() – алиас, дополнительно проверяющий, что получен действительно render array drupal_render_children() – рендеринг дочерних элементов
Рендер
Проверка свойства #access и #printed Проверка кэша Загрузка свойств по-умолчанию (если указан #type) Вызов #pre_render функций Вызов функции темирования #theme Вызов функций темирования #theme_wrappers Вызов #post_render функций Обработка #attached ресурсов (JS, CSS) Кэшировать данные (если указан #cache) Возвратить #prefix . $output . #suffix
Как работает drupal_render()
Все элементы страницы (page) собраны в одном массиве render array hook_page_build() дает возможность добавить элементы на страницу hook_page_alter() дает возможность изменить существующие элементы на странице
Рендер страницы
// index.phpmenu_execute_active_handler();
// menu.inc: menu_execute_active_handler()drupal_deliver_page($page_callback_result, $default_delivery_callback);
// common.inc: drupal_deliver_html_page($page_callback_result)print drupal_render_page($page_callback_result);
// common.inc: drupal_render_page($page_callback_result)// invoke hook_page_build
block_page_build($page);
// invoke hook_page_alter
drupal_render($page);
drupal_render() / render() – отрендерить элемент hook_page_alter() – возможность изменить любой элемент на странице hide() / show() – скрыть/показать элемент
Render API и темирование
Пример: render() и hide()<!-- node.tpl.php --><!-- .. some code .. --><div class="content"<?php print $content_attributes;?>><?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() – отрендерить элемент hide() / show() – скрыть/показать элемент hook_page_alter() – возможность изменить любой элемент на странице 2 вида функций темирования: properties-as-variable element-as-variable
Render API и темирование
/** * Implements hook_theme(). */function mymodule_theme() { return array( // Properties-as-variable 'mymodule_items' => array( 'variables' => array( 'items' => array(), 'title' => '' ) ), // Element-as-variable 'mymodule_element' => array( 'render element' => 'element' ), );}/** * Properties-as-variable theme implementation */function theme_mymodule_items($vars) { $items =& $vars['items']; $title =& $vars['title']; // ...}/** * Element-as-variable theme implementation */function theme_mymodule_element($vars) { $element =& $vars['element']; // ...}
Забудьте про theme(), используйте render arrays Render API позволяет сделать код более:
прозрачным и понятным быстрым удобным
Выводы
Drupal APIhttp://api.drupal.org Render Arrays in Drupal 7http://drupal.org/node/930760 Examples modulehttp://drupal.org/project/examples
Ссылки
Спасибо за внимание!Вопросы?
Ефим Web-Evt ЕвтушенкоE-mail: [email protected]: Web-Evt