drupal render api
DESCRIPTION
Presentation from Drupal camp 2011TRANSCRIPT
Render API
Pavel Makhrinsky
e-mail: [email protected]: gumanistadrupal.org: http://drupal.org/user/773216facebook: https://www.facebook.com/gumanist
Overview
●Form API successor●Drupal 6 ‘theme’ replacement●System to build structured arrays into content●The way to build presentation layer
Theming ways
●Noob way●Drupal 6 way●Drupal 7 way
Noob way
●Inline● Inline● Inline● Inline● Inline
1 <div class="nav">2 <ul class="topnav"> 3 <li id="lefttopnav" <?php if($levelone == 'home') echo "class=\"current\"";?>><?php echo $menu1;?></li>4 <li <?php if($levelone == "item-2") echo "class=\"current\"";?>> <?php echo $menu2;?></li>5 <li <?php if($levelone == "item-3") echo "class=\"current\"";?>> <?php echo $menu4;?></li>6 <li <?php if($levelone == "item-4") echo "class=\"current\"";?>> <?php echo $menu6;?></li>7 <li <?php if($levelone == "item-5") echo "class=\"current\"";?>> <?php echo $menu5;?></li>8 <li <?php if($levelone == 'item-6') echo "class=\"current\"";?>> <?php echo $menu7;?></li>9 </ul>10 </div>
Drupal 6 way
●Use theme functions● Implement hook_theme●Move large markup to templates
1 $items = array('item-1', 'item-2', 'item-3', 'item-4', 'item-5');2 $output = theme('item_list', $items);
Drupal 6 way - advantages
●Common way to render elements●Reusable functions●Predictable markup●Possibility to change generation●Output altering
Drupal 6 way - disadvantages
●Slower performance●Caching difficulties●Different parameters
Drupal 7 way
●Use renderable arrays●Alter content you need
1 $items = array('item-1', 'item-2', 'item-3', 'item-4', 'item-5');2 $output = array(3 '#items' => $items,4 '#theme' => 'item_list'5 );
Drupal 7 way advantages
●Content alterable in a common way●All the renderable elements have preprocess
and process functions●Transparent caching●Resources could be attached to elements
Render API details
●hook_theme●Renderable array structure●Content altering●#type, #theme, #theme_wrappers●#states●Resources●Performance and caching
hook_theme()
●hook_theme○ variables | render element○ file○ path○ template○ function○ preprocess functions
Renderable array structure
● ‘#’ elements●system elements
○ #children○ #access○ #printed○ #sorted
Content altering
●#pre_render●#post_render●preprocess and process functions
#type
●Loads defaults from hook_element_info()
1 function module_template_element_info() {2 return array(3 'file_template' => array(4 '#name' => 'misc',5 '#fileinfo' => array(6 'filename' => '[module_name].[name].[extension]',7 'path' => 'includes',8 'extension' => 'inc'9 )10 )11 ); 11 }
1 // If the default values for this element have not been loaded yet, populate2 // them.3 if (isset($elements['#type']) && empty($elements['#defaults_loaded'])) {4 $elements += element_info($elements['#type']);5 }
#theme
●Invokes theme() function1 // Get the children of the element, sorted by weight.2 $children = element_children($elements, TRUE); 3 4 // Initialize this element's #children, unless a #pre_render callback already 5 // preset #children. 6 if (!isset($elements['#children'])) { 7 $elements['#children'] = ''; 8 } 9 // Call the element's #theme function if it is set. Then any children of the10 // element have to be rendered there.11 if (isset($elements['#theme'])) {12 $elements['#children'] = theme($elements['#theme'], $elements);13 }14 // If #theme was not set and the element has children, render them now.15 // This is the same process as drupal_render_children() but is inlined16 // for speed.17 if ($elements['#children'] == '') {18 foreach ($children as $key) {19 $elements['#children'] .= drupal_render($elements[$key]);20 }21 }
#theme_wrappers
●Wrap #children element with code1 // Let the theme functions in #theme_wrappers add markup around the rendered2 // children.3 if (isset($elements['#theme_wrappers'])) {4 foreach ($elements['#theme_wrappers'] as $theme_wrapper) {5 $elements['#children'] = theme($theme_wrapper, $elements);6 }7 }
#states
●Adds JavaScript to change the state of an element based on another element
1 $form['toggle_me'] = array( 2 '#type' => 'checkbox', 3 '#title' => t('Tick this box to type'), 4 ); 5 $form['settings'] = array( 6 '#type' => 'textfield', 7 '#states' => array( 8 // Only show this field when the 'toggle_me' checkbox is enabled. 9 'visible' => array(10 ':input[name="toggle_me"]' => array('checked' => TRUE),11 ),12 ),13 );
Resources
●#attached property●Allow attach
○ CSS○ JavaScript○ Libraries
●Not cached
Performance and caching
●Setting cache for renderable arrays●Some cache usage tips
#cache
●'keys' => an array of keys which will be concatenated to form the cache key.
●'bin' => the name of the cache bin to be used (as in 'cache' or 'cache_page', etc.
●'expire' => a Unix timestamp indicating the expiration time of the cache.
●'granularity' => a bitmask indicating the cache type. This should be DRUPAL_CACHE_PER_PAGE, DRUPAL_CACHE_PER_ROLE, or DRUPAL_CACHE_PER_USER
Some cache usage tips
●Don’t cache small items●Items from #attached not stored with rendered
items●Use cache targeting●Cache items will not be expired until cron runs,
regardless of the expiration time used
Elements 5 100 500With #cache 3211 3276 3235Without #cache 747 4257 18336
Summary
●Don’t use direct call of theme() function●Generate HTML as later as possible
Links● Render API
○ http://drupal.org/node/933976○ http://drupal.org/node/930760○ http://api.drupal.org/api/drupal/includes--common.inc/function/drupal_render/7
● States ○ http://api.drupal.org/api/drupal/includes--common.inc/function/drupal_process_states/7
● Drupal API○ http://api.drupal.org
● Examples module○ http://drupal.org/project/examples
● Cache backends○ http://drupal.org/project/apc○ http://drupal.org/project/memcache○ http://drupal.org/project/filecache
Thank you
e-mail: [email protected]: gumanistadrupal.org: http://drupal.org/user/773216facebook: https://www.facebook.com/gumanist