drupal PHPTemplate中的区域

从Drupal 4.7开始,主题可以实现任意数量的区域,用于区块或者其它内容的显示。你可以到Drupal的区块管理页面(admin/build/block)看一下,你将看到,实际上区域本质上就是一个容器,你可以向里面添加区块。你也可以使用PHP向区域中添加非区块内容。什么是区域呢,一个比较好的例子就是边栏。

这些区域可以用于整个页面,或者其它的主题元素中,比如接电或者评论。 

PHPTemplate引擎定义了5个默认的区域:left(左栏), right(右栏), content(内容), header(页首), 和footer(页脚)。为了实现这些区域,在drupal主题中,只需要在page.tpl.php模板文件中包含进变量$sidebar_left, $sidebar_right, $content, $header, 和$footer_message就可以了,比如,<?php print $header; ?>。

 

如何实现自定义区域

对于一个主题,如果你不想使用默认的区域,想自己定义一套的话,你可以使用_regions()钩子函数。在这种情况下,你的自定义区域,将会覆写PHPTemplate的默认区域。

如果在主题目录中还没有template.php文件的话,那么创建一个;如果有的话,就使用现有的。然后,打开template.php文件,向里面添加一个mytheme_regions()函数,用来定义你的区域。每个区域都需要一个名字(没有空格的字符串)和一个描述(展示给用户的文本,比如在区块管理页面)。在下面的代码中,我们为"mytheme"主题重新定义了除左栏以外的PHPTemplate的默认区域,还为它添加了两个新的区域。

 

<?php
function mytheme_regions() {
  return array(
    'right' => t('right sidebar'),
    'content' => t('content'),
    'header' => t('header'),
    'footer' => t('footer'),
    'floater' => t('floater'),
    'inline1' => t('inline 1')
  );
}
?>

注意:对于函数名,你需要注意几点:

  • 使用你的主题名来代替mytheme_regions(),比如bluemarine_regions()
  • 不要在区域名中使用连字符;可以使用下划线。
  • 还有,你的主题名是你的基主题名(base theme name),而不是你的style.css文件所在的目录。例如,box_cleanslate覆写了box_grey主题的style.css文件;在这里,你的函数名应该为box_grey_regions。

 

如何向页面写入主题的区域变量。

如果你需要在page.tpl.php中使用你的区域的话,你不需要为你的区域去创建一个变量,然后再将内容指定给它;PHPTemplate已经自动帮你完成了。你所需要做的就是,通过编辑你主题的page.tpl.php文件,将变量写入到页面。对于你定义的每个新的区域,只需要在page.tpl.php中加一个print语句就可以了。对于前面定义的'floater'区域,可以这样调用:

<?php  print $floater;?>.

 

当然,你可以使用HTML,CSS,PHP(这个可能用到)来为你的区域定制一个好看的外观。

相关联接: http://drupal.org/node/29139 , Think in Drupal

Drupal版本:

如何将drupal区域指定到节点,评论中

默认情况下,所有定义的区域都传递给page.tpl.php。但是只需要额外的几步,你也可以将特定的区域应用到其它的模板文件中:node.tpl.php,comment.tpl.php等等。下面是如何实现的。

在你定义区域的template.php文件中,定义一个_phptemplate_variables()函数(如果已经存在的话,就使用已有的)。在这里,你要做的就是将区域内容指定到一个特定的主题调用中。当调用_phptemplate_variables()时,将会向$hook变量传递一个主题参数,比如'node'。所以,使用下面的代码,我们可以将区域指定到节点模板文件中:

<?php
function _phptemplate_variables($hook, $variables) {
  // Load the node region only if we're not in a teaser view.
  if ($hook == 'node' && !$vars['teaser']) {
    // Load region content assigned via blocks.
    foreach (array('inline1') as $region) {
      $variables[$region] = theme('blocks', $region);
    }
  }
  return $variables;
}
?>

注意,我们在这里做了检查,确保不是处于一个'teaser'视图中,这样只有当处于完整的节点视图中时,才加载内置区域。

现在,在你的节点模板中,你就可以把区域变量包含进来了。下面是标准的phptemplate node.tpl.php模板加进'inline1'区域后的样子:

  <div class="node<?php if ($sticky) { print " sticky"; } ?><?php if (!$status) { print " node-unpublished"; } ?>">
    <?php if ($picture) {
      print $picture;
    }?>
    <?php if ($page == 0) { ?><h2 class="title"><a href="<?php print $node_url?>"><?php print $title?></a></h2><?php }; ?>
    <span class="submitted"><?php print $submitted?></span>
    <span class="taxonomy"><?php print $terms?></span>
    <div class="content"><div class="floatleft"><?php print $inline1?></div><?php print $content?></div>
    <?php if ($links) { ?><div class="links">&raquo; <?php print $links?></div><?php }; ?>
  </div>

 

大多数情况下,你都会为你的区域添加一些样式,你可以像往常一样,通过主题的style.css文件来完成。例如,在这里,我们将让内置区域向左浮动:

div.floatleft {
  float: left;
}

由于一个节点的变量传递给了其它的节点模板,所以你也可以在node-type模板中实现你的自定义外观。

这种方式还可以应用到其它的主题元素中。下面的例子将特定的区域指定到了节点和评论中:

<?php
function _phptemplate_variables($hook, $variables) {
  // Load region content assigned via blocks.
  // Load the node region only if we're not in a teaser view.
  if ($hook == 'node' && !$variables['teaser']) {
    foreach (array('node1', 'node2') as $region) {
      $variables[$region] = theme('blocks', $region);
    }
  }
  else if ($hook == 'commment') {
    foreach (array('comment1', 'comment2') as $region) {
      $variables[$region] = theme('blocks', $region);
    }
  }
  return $variables;
}
?>

相关联接: http://drupal.org/node/29139 , Think in Drupal

Drupal版本:

没有区块的drupal区域

如果你想将内容指定到区域中,而又不通过区块来实现的话,你可以使用drupal_set_content()函数。这允许你绕过通常的区块机制,你可以尝试以下几点:

 

将内容设置到区域中

在你的模块代码中,将内容设置给区域。在这里,你可以使用themename_regions()数组中不存在的区域名。这样,这些区域对于区块来说就不可用,因此里面也就不会放置区块内容了。假定你的区域叫做'region1' 和'region2'。在你的模块中,可以这样做:

<?php
$output = 'whatever';
drupal_set_content('region1', $output);
?>

 

在template.php文件中,设置一个变量,并将区域内容指定给这个变量。

<?php
function _phptemplate_variables($hook, $variables) {
  // Load region content assigned via drupal_set_content().
  if ($hook == 'page') {
    foreach (array('region1', 'region2') as $region) {
      $variables[$region] = drupal_get_content($region);
    }
  }
  return $variables;
}
?>

 

输出你的内容
在你的page.tpl.php文件中,在需要的地方输出区域:

<?php
print $region1;
?>

相关联接: http://drupal.org/node/29139 , Think in Drupal

Drupal版本: