You are here

1 接管theme_breadcrumb函数

admin 的头像
Submitted by admin on 星期四, 2015-09-17 09:21

作者:老葛,北京亚艾元软件有限责任公司,http://www.yaiyuan.com

我们是可以在主题层覆写面包屑的,但是有一个问题,我们这里定义的是自己的模块,我们想在自己的模块里面修改theme_breadcrumb函数。我们知道,我们是不能够直接修改Drupal核心代码的,所以将其接管过来是最佳的办法。这也是我们添加上下文链接的第一步。

我们首先需要知道,theme_breadcrumb是在什么地方定义的。说真的,真心受不了,Google不能用。搜索个theme_breadcrumb都出不来结果。好吧,我们直接登陆http://api.drupal.org/api,在里面搜索theme_breadcrumb。我们看到这个函数是在includes/theme.inc文件里面定义的。函数的代码也很简单:

 

function theme_breadcrumb($variables) {

  $breadcrumb = $variables['breadcrumb'];

 

  if (!empty($breadcrumb)) {

    // Provide a navigational heading to give context for breadcrumb links to

    // screen-reader users. Make the heading invisible with .element-invisible.

    $output = '<h2 class="element-invisible">' . t('You are here') . '</h2>';

 

    $output .= '<div class="breadcrumb">' . implode(' » ', $breadcrumb) . '</div>';

    return $output;

  }

}

很多资料上,讲主题函数的覆写的时候,通常都以这个作为例子。我记得以前的Drupal专业开发指南里面,都拿这个作为例子。

知道了这个函数的位置以后,我们还需要知道,哪个hook_theme钩子函数中,注册了这个主题函数。而theme_breadcrumb这个函数是在drupal_common_theme里面注册的,通过system_theme实现。对应代码如下:

   'breadcrumb' => array(

      'variables' => array('breadcrumb' => NULL),

    ),

想要修改主题的注册表信息,我首先想到的是hook_theme_alter,但是通过Google查找了一下,发现应该使用hook_theme_registry_alter。和我们平时的不一样。我们向breadcrumb2.module追加以下代码:

 

/**

 * Implements hook_theme_registry_alter().

 */

function breadcrumb2_theme_registry_alter(&$theme_registry) {

  if (isset($theme_registry['breadcrumb'])) {

    $path = drupal_get_path('module', 'breadcrumb2');

    $theme_registry['breadcrumb']['path'] = $path;

    $theme_registry['breadcrumb']['template'] = 'breadcrumb';

    $theme_registry['breadcrumb']['function'] = NULL;

  }

}

在这里,我们首先检查,有没有设置$theme_registry['breadcrumb'],如果已经设置了,我们对它进行修改,为它设置$theme_registry['breadcrumb']['template'],同时为它设置$theme_registry['breadcrumb']['path'],最后将$theme_registry['breadcrumb']['function']置为空。这里的'path''template''function'是三个键,如果设置了'template',就应该把'function'置为空,否则默认还是使用'function''function'表示这是一个主题函数,'template'表示这是一个模板文件。'path'用来设置模板所在的目录,我们把它修改为了'breadcrumb2'所在的目录了。

现在清除缓存,我们会得到这样的错误消息:

Warning: include(D:\xampp\htdocs\breadcrumb2/sites/all/modules/breadcrumb2/breadcrumb.tpl.php) [function.include]: failed to open stream: No such file or directory in theme_render_template() (line 1495 of D:\xampp\htdocs\breadcrumb2\includes\theme.inc). 

Warning: include() [function.include]: Failed opening 'D:\xampp\htdocs\breadcrumb2/sites/all/modules/breadcrumb2/breadcrumb.tpl.php' for inclusion (include_path='.;D:\xampp\php\PEAR') in theme_render_template() (line 1495 of D:\xampp\htdocs\breadcrumb2\includes\theme.inc).

意思是说,在breadcrumb2找不到breadcrumb.tpl.php,我们还没有创建嘛,这说明了,我们前面的代码起作用了,而且工作的很好。我们现在就创建breadcrumb.tpl.php文件,里面的代码如下:

<?php

 

/**

 * @file

 * Default theme implementation to display a breadcrumb.

 *

 * Available variables:

 * - $contextual_links: contextual links for breadcrumb.

 * - $breadcrumb: An array of breadcrumb link.

 * @see template_preprocess()

 * @see breadcrumb2_preprocess_breadcrumb()

 * @see template_process()

 *

 * @ingroup themeable

 */

?>

 123456

<?php if (!empty($breadcrumb)): ?>

<div class="breadcrumb-wrapper">

  <h2 class="element-invisible">   <?php print t('You are here'); ?>  </h2>

  <div class="breadcrumb"> <?php print implode(' » ', $breadcrumb); ?> </div>

</div>

<?php endif; ?>

中间的“123456”,是用来测试,是不是这个模板文件起作用,模板覆写的时候,我经常使用这个办法,在模板里面加点东西,用来判断它是否起作用。注释里面有个$contextual_links,这个我们在后面才会添加。

 

我们回到breadcrumb2_theme_registry_alter,在这里面,我们可以加上两行调试代码:

  print debug($theme_registry['breadcrumb']);

  print debug($theme_registry['page']);

   然后,再清除缓存,我们呢可以看到打印出来的消息:

array (

  'variables' => 

  array (

    'breadcrumb' => NULL,

  ),

  'type' => 'module',

  'theme path' => 'modules/system',

  'function' => 'theme_breadcrumb',

  'preprocess functions' => 

  array (

  ),

  'process functions' => 

  array (

  ),

)

array (

  'template' => 'page',

  'path' => 'themes/seven',

  'type' => 'theme_engine',

  'theme path' => 'themes/seven',

  'render element' => 'page',

  'preprocess functions' => 

  array (

    0 => 'template_preprocess',

    1 => 'template_preprocess_page',

    2 => 'contextual_preprocess',

    3 => 'overlay_preprocess_page',

    4 => 'shortcut_preprocess_page',

    5 => 'seven_preprocess_page',

  ),

  'process functions' => 

  array (

    0 => 'template_process',

    1 => 'template_process_page',

    2 => 'rdf_process',

  ),

)

通过将整个数组,打印出来,我们可以看到有多少个键可用。以及每个键的赋值情况。我前面的代码写好了以后,发现了一个问题,就是无法在主题层覆写breadcrumb.tpl.php文件。就是说,我们将breadcrumb.tpl.php复制到themes\bartik\templates下面,并稍微的调整一下里面的内容,比如把刚才的“123456”修改为“123”。清除缓存,发现起作用的还是我们模块里面的模板文件。这是在实际应用当中发现的一个问题。到现在还没有解决。本来打算,一边写作,一边写代码,后来灵感大爆发,直接把模块先写完了。我写到这的时候是20121224日,实际上,1211号就发布了beta4版了,很多功能都已经实现。

不过今天依然没有解决这个无法覆写的问题,不过我想,肯定会解决的。我通过Google搜索过,也有人遇到过同样的问题,但是没有解决。不过今天Google罢工了。我们继续前进,来看一下怎么添加上下文。


Drupal版本: