所有模板引用都始于theme函数并递归调用其嵌套的theme函数,以下示意代码简单地描述了theme的整个机制

function theme($template, $variables)
{
    // hook_theme 声明template
    foreach($modules as $module) {
        $theme_info += {$module}_theme();
    }
    if(empty($theme_info[$template])) return TEMPLATE_NOT_FOUND;
    
    // preprocess function加工$variables
    if(function_exists('{$theme}_preprocess_{$template}')) {
        $variables = {$theme}_preprocess_{$template}($variables);
    }
    
    $info = $theme_info[$template];
    
    // 如果设置了template属性,将读取tpl
    if(!empty($info['template']))
        return get_template_from_file('{anymodule or theme path}'.$info['template'].'.tpl.php', $variables);
    else {
        // 否则将调用theme function
        if(function_exists('{$theme}_{$template}'))
            return {$theme}_{$template}($variables);
        else
            // 这是最base的模板,一般位于module内部
            return theme_{$template}($variables);
    }
}
{$template} : 当前模板名称
{$theme} : 当前使用的theme名称

修改模板,以user login为例

* template必须通过hook_theme声明
* template必须使用theme('hook', $vars);来输出
* theme里的template.php可以实现HOOK,前缀必须是theme的名称
* form在没有指定#theme的时候,默认会引用与form ID一样的模板,即form是user_login,它会自动调用`theme('user_login', $variables);`
* preprocess functions可以修改模板变量

user/login的page callback是function user_login,它并没有声明template,所以第一步应该在template.php声明user_login template

function yourtheme_theme() {
  $items = array();
 
  $items['user_login'] = array(
    'render element' => 'form',
    'path' => drupal_get_path('theme', 'yourtheme') . '/templates',
    'template' => 'user-login',
    'preprocess functions' => array(
       'yourtheme_preprocess_user_login'
    ),
  );
  return $items;
}

通过以上代码,可以创建sites/all/themes/yourtheme/templates/user-login.tpl.php,它会自动应用在user login page上。而有时候有必须修改模板的动态数据,但form提供给template的变量固定,这时就可以用yourtheme_preprocess_user_login对模板变量进行修改。

About overriding themable output

https://www.drupal.org/node/1...

常见的模板

  • theme_html

  • theme_page

  • theme_user_profile

  • theme_region

  • theme_block

  • theme_node

  • theme_field

  • theme_comment

  • theme_taxonomy_term

  • theme_webform_form

  • theme_menu_local_task

Template Suggestions

template不仅仅是固定不变,template的命名可以规则化,使template可以指定属于某些内容而不是全部。而这种规则化一般需要module预先实现,已经有相当一部分module实现规则化,例如node, taxomoy。

假如我们需要指定ID = 1的内容模板,我们可以把template命名为node--1.tpl.php。但我们很难从程序文件或者代码里得知module支持那些命名规则,所以官方提供一篇文档方便开发者查阅:Drupal 7 Template (Theme Hook) Suggestions

menu template

// in template.php
function mytheme_menu_tree($variables) {
  return '<ul class="menu">' . $variables['tree'] . '</ul>';
}
 
function mytheme_menu_link(array $variables) {
  $element = $variables['element'];
  $sub_menu = '';
 
  if ($element['#below']) {
    $sub_menu = drupal_render($element['#below']);
  }
  $output = l($element['#title'], $element['#href'], $element['#localized_options']);
  return '<li' . drupal_attributes($element['#attributes']) . '>' . $output . $sub_menu . "</li>\n";
}

How to Add Theme Settings for Drupal 7

// in theme-settings.php
function hook_form_system_theme_settings_alter(&$form, &$form_state, $form_id = NULL)  {
  // Work-around for a core bug affecting admin themes. See issue #943212.
  if (isset($form_id)) {
    return;
  }

  // Create the form using Forms API: http://api.drupal.org/api/7
  $form['theme_settings']['background_file'] = array(
    '#type' => 'managed_file',
    '#title' => t('Background'),
    '#required' => TRUE,
    '#upload_location' => file_default_scheme() . '://backgrounds/',
    '#default_value' => theme_get_setting('background_file'),
    '#upload_validators' => array(
      'file_validate_extensions' => array('gif png jpg jpeg'),
    ),
  );
}
// in template.php
function theme_preprocess_html(&$variables, $hook) {
  $fid = theme_get_setting('background_file');
  $variables['background_url'] = '';
  if($fid) {
    $loaded = file_load($fid);
    if(!$loaded->status) {
      $loaded->status = FILE_STATUS_PERMANENT;
      file_save($loaded);
    }
    $variables['background_url'] = file_create_url($loaded->uri);
  }
}

常用模板

$items = array(
    l('Batch history', 'admin/reports/salesforce/batch'),
    l('Currently queued items', 'admin/reports/salesforce/current'),
);
$output .= theme('item_list', array('items' => $items));
$header = array('Nid', 'Title', 'Created');
$rows []= array(1, 'item 1', '2009/1/3');
$rows []= array(2, 'item 2', '2009/1/4');
$output = theme('table', array(
    'header' => $header,
    'rows' => $rows
));
$links[] = array(
    'href'  => 'node/1',
    'title' => 'blog 1',
    'query' => array('tag' => 'blog'),
);
print theme('links', array(
    'links' => $operations,
    'attributes' => array('class' => array('links', 'inline')),
));

猫之良品
2.5k 声望139 粉丝

资深Drupal, magento与Joomla


引用和评论

0 条评论