render api - pavel makhrinsky
TRANSCRIPT
Render API
Pavel Makhrinsky
http://donetsk.drupal.ua
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, populate 2 // 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]: gumanista