继续看theme之page

前面看到每个模块的hook_theme会被在主题初始化的时候被调用,进一步,通过追踪源码,可以发现page被定义在system_theme函数中,而system_theme是通过调用common.inc中的drupal_common_theme函数来实现对page的实现。而在drupal_common_theme函数中的page是这样定义的:

‘page’ => array(
‘arguments’ => array(‘content’ => NULL, ‘show_blocks’ => TRUE, ‘show_messages’ => TRUE),
‘template’ => ‘page’,
),

这里包含的信息不多,最终得到的hooks中,page是这样定义的

[page] => Array
        (
            [template] => page
            [path] => themes/pushbutton
            [include files] => Array
                (
                )

            [type] => theme_engine
            [theme path] => themes/pushbutton
            [arguments] => Array
                (
                    [content] => 
                    [show_blocks] => 1
                    [show_messages] => 1
                )

            [theme paths] => Array
                (
                    [0] => modules/system
                    [1] => themes/pushbutton
                )

            [preprocess functions] => Array
                (
                    [0] => template_preprocess
                    [1] => template_preprocess_page
                )

        )

由此可见,新添加的有proprocess function. 同时添加了主题相关的信息。这个处理发生在函数_theme_process_registry里面。关于preprocess 函数的添加,其过程是这样的,
(这里只看是module的情况):
如果定义了template_preprocess , 则将这函数添加到preprocess function 中
如果定义了template_preprocess_hook , 则添加这个函数,注意此时这里的hook是page,如果是其他的table,link之类的,那么hook的名字应作相应的改变。
对于每个模块,如果定义了module_preprocess , 则添加这个函数
对于每个模块,如果定义了module_preprocess_hook,则添加这个函数。
另外还有一条,如果定义了module_theme函数的返回值中定义了”original hook” , 并且函数prefix_preprocess_”original hook” 存在,则添加这个函数,这里prefix是template或者是模块名。
总之,这段说明有点麻烦,贴下代码吧:


// Check for default _preprocess_ functions. Ensure arrayness.

      if (!isset($info[‘preprocess functions’]) || !is_array($info[‘preprocess functions’])) {

        $info[‘preprocess functions’] = array();

        $prefixes = array();

        if ($type == ‘module’) {

          // Default preprocessor prefix.

          $prefixes[] = ‘template’;

          // Add all modules so they can intervene with their own preprocessors. This allows them

          // to provide preprocess functions even if they are not the owner of the current hook.

          $prefixes += module_list();                //注意这里的prefixes数组,它包含了所有的模块列表

        }

        elseif ($type == ‘theme_engine’ || $type == ‘base_theme_engine’) {

          // Theme engines get an extra set that come before the normally named preprocessors.

          $prefixes[] = $name .’_engine’;

          // The theme engine also registers on behalf of the theme. The theme or engine name can be used.

          $prefixes[] = $name;

          $prefixes[] = $theme;

        }

        else {

          // This applies when the theme manually registers their own preprocessors.

          $prefixes[] = $name;

        }
        foreach ($prefixes as $prefix) {      //对template 以及每个模块名作下面的检查。

          if (function_exists($prefix .’_preprocess’)) {

            $info[‘preprocess functions’][] = $prefix .’_preprocess’;

          }
          if (function_exists($prefix .’_preprocess_’. $hook)) {

            $info[‘preprocess functions’][] = $prefix .’_preprocess_’. $hook;

          }
          if (!empty($info[‘original hook’]) && function_exists($prefix .’_preprocess_’. $info[‘original hook’])) {

            $info[‘preprocess functions’][] = $prefix .’_preprocess_’. $info[‘original hook’];

          }

        }

      }

由此看出,虽然每个模块可以定义一个module_theme函数,说明主题中每个hook是怎样被处理的,但事实上,在被处理之前,还有很多函数对去作事先处理。如果tempalate_preprocess,template_preprocess_hook定义过,那么每个theme函数都会去调用这个函数。

事实上,template_preprocess是在theme.inc中定义的。因此每个theme函数都会首先调用它。
猜想,每个模板被调用之前,应该要经过preprocess处理来定义一些php变量,然后模板中才可以去引用这些变量。下面需要具体去看预处理做了些什么事情,模板中又引用了一些什么样的变量。

接着来:
在template_preprocess 和 template_preprocess_page函数中,主要是在添一个数组 $variables , 在填完之后,调用theme.inc 中的函数 theme_render_template, 这个函数接受两个参数,其中第一个是模板文件,第二个是前面预处理函数中定义的variables, 而这个函数比较简单,就直接把它贴出来了。


function theme_render_template($template_file, $variables) {

  extract($variables, EXTR_SKIP);  // Extract the variables to a local namespace

  ob_start();                      // Start output buffering

  include “./$template_file;      // Include the template file

  $contents = ob_get_contents();   // Get the contents of the buffer

  ob_end_clean();                  // End buffering and discard

  return $contents;                // Return the contents

}


第一个据是通过调用php函数extract,把$variables展开到当前的名字空间。然后就引入模板文件,其中模板文件中就包含了对这些$variables的引用。最后把输出返回。支持,theme(page,$return)的整个调用过程就分析完了。绕了好大一个弯,还真不是那么简单。



本文地址: http://www.bagualu.net/wordpress/archives/1719 转载请注明




发表评论

电子邮件地址不会被公开。 必填项已用*标注