Drupal 7 开发内部培训资料, 分头诗人

drupal 7 通过编写代码方式创建自定义区块。

猪跑啦独家原创专稿,欢迎您转载本文,转载请注明来源。
标签: block 区块

我们先看看跟block相关的钩子。
hook_block_info () –用于在模块中声明新的区块,以及指定区块的初始设置。每个区块通过一个数组声明,其中使用了在本模块中用来唯一标识区块的delta作为该数组的键。注意:是在本模块中唯一标识。也就是说:其他模块中可能出现与本模块中区块同名的delta。这就意味着:通过“模块名+delta”可以唯一确定一个区块。block的基本信息,如是否缓存,是否默认开启,是否默认显示在某些页面,显示在哪些页面等。
在每个区块声明数组中有很多键值对:

  • info:必须,指定区块的人读名。
  • cache:可选,指定区块的缓存类型。
  • properties:可选,附加给区块的元数据。
  • weight:可选,指定区块的权重。
  • status:可选,指定区块的启用状态。
  • region:可选,指定区块的所在区域。
  • visibility:可选,用于区块可见性,解释了pages的值。
  • pages:可选,用于区块可见性。

hook_block_info_alter() – 我们知道,凡是钩子以 alter结尾的,都是要来修改已有的内容的。这个也不例外。价值在于不需要
hook_block_configure() -用于定义区块设置表单。在Drupal后台的区块管理列表中(http://你的网站域名/admin/structure/block)的Operations一栏,可以看到每个区块都有一个configure链接,点击进去就是每个区块的设置表单了。该钩子函数就是为这个设置表单添加新的设置项目的。首先通过delta确定需要定义设置的区块,然后创建表单项,再通过Drupal的持久变量提供默认值。
hook_block_save() -用于保存来自hook_block_configure()的区块设置。它需要的参数有两个:

  • $delta:需要定义设置的区块。
  • $edit:来自通过hook_block_configure()定义的区块设置表单的数据,它的键是表单的元素。

hook_block_view() - 用于生成区块的内容。它的返回值是一个数组,该数组有两个键:

  • subject:区块的标题。
  • content:区块的内容。

一个最基本的自定义区块,不一定要上面5个钩子都调用,只需要调用
hook_block_info()跟hook_block_view ()就可以,下面我们还是做一个例子:
首先我们做一个模块,名字叫:blocktest,模块的建立可以参考前面章节,这里不再详述。
接下来我们调用hook_block_info(),
 

/**
* Implements hook_block_info().
*/
function blocltest_block_info() {
  $blocks = array();
  $blocks['YOUR_BLOCK_ABC'] = array(
    'info' => t('YOUR BLOCK NAME'),
  );
  return $blocks;
}


调用hook_block_info() 代码非常简单,只需要定义一个数组,数组存放区块的基本信息,并且返回该数组就可以。其中代码:
 

$blocks['YOUR_BLOCK_ABC'] = array(
    'info' => t('YOUR BLOCK NAME'),
  );


是定义了一个区块,名字叫YOUR_BLOCK_ABC,当我们需要建立多一个区块的时候,例如我们要再建立一个区块YOUR_BLOCK_DEF可以这样写:
 

function blocltest_block_info() {
  $blocks = array();
  $blocks['YOUR_BLOCK_ABC'] = array(
    'info' => t('YOUR BLOCK NAME'),
  );
  $blocks['YOUR_BLOCK_DEF'] = array(
    'info' => t('YOUR BLOCK NAME'),
  );

  return $blocks;
}


这样就会有两个区块的信息了。

然后再来定义hook_block_view(),我们可以通过switch循环出所有区块的基本信息。最后为每个区块绑定一个内容。做法如下面代码。
 

/**
* Implements hook_block_view().
*/
function blocltest_block_view($delta = '') {
  $block = array();
  switch ($delta) {
    case 'YOUR_BLOCK_ABC':
      $block['subject'] = '';
      $block['content'] = _ blocltest_BLOCK_ABC_CONTENT();
      break;
  }
  return $block;
}


$delta是要来存储hook_block_info() 的区块的,循环$delta,当区块名称为YOUR_BLOCK_ABC的时候,我们就让他显示_ blocltest_BLOCK_ABC_CONTENT() 函数的内容。


最后一步,当然是要写上_ blocltest_BLOCK_ABC_CONTENT()函数了
 

function _ blocltest_BLOCK_ABC_CONTENT() {
  $output = t('Hello world');
  return $output;
}


简单的几步,我们就能完成一个基本的区块。
可以在后台开启模块,

再进入区块页面查看,你就能看到我们自定义的模块了。

我们把他放到sidebar_first 区域看看效果。

怎么样,很简单吧?
这是最基本的用法,再来深入点,我想模块安装后就自动放在sidebar_first里面,并且只有首页才显示。怎么做呢?只需在hook_block_info 里面增加两个属性就可以了。我们改一下hook_block_info代码:
 

/**
* Implements hook_block_info().
*/
function blocltest_block_info() {
  $blocks = array();
  $blocks['YOUR_BLOCK_ABC'] = array(
    'info' => t('YOUR BLOCK NAME'),
    'region' => 'sidebar_first',
    'visibility' => BLOCK_VISIBILITY_LISTED,
    'pages' =>'<front>',
    'status' =>1,
  );
  return $blocks;
}


粗体的三行代码中,第一行是说,默认放在sidebar_first 下面,第二行意思是只在特定页面显示,而第三行是指出具体的页面,第四行是状态默认是开启,通过这样的修改后,只要安装模块,区块就自动增加到左侧栏、而且只有在首页显示。

除此之外,还可以为我们的自定义区块做一个配置表单。这里需要引用hook_block_configure() 跟hook_block_save(),我们先来调用 hook_block_configure():
 

function blocktest_block_configure($delta = '') {
  $form = array();
  if ($delta == 'YOUR_BLOCK_ABC') {
    $form['setting'] = array(
      '#type' => 'textfield',
      '#title' => t('自定义区块的设置'),
      '#default_value' => variable_get('blocktest_custom_block_setting',  ' Hello, 我们是为知课堂,网址是www.wizcourse.com'),
    );
  }
  return $form;
}


再来调用hook_block_save():
 

function blocktest_block_save($delta = '', $edit = array()) {
  if ($delta == 'YOUR_BLOCK_ABC') {
    variable_set('blocktest_custom_block_setting', $edit['setting']);
  }
}

然后我们改改函数_blocltest_BLOCK_ABC_CONTENT()如下:
 

function _blocltest_BLOCK_ABC_CONTENT() {
  $output = variable_get('blocktest_custom_block_setting',  t('Hello world'));
  return $output;
}


清空缓存,然后在后台区块页找到YOUR_BLOCK_ABC,点击配置:

看到箭头的三个地方了吗?第一个是我们自定义的区块设置,第二个是默认的区域设置,第三个是默认在什么页面显示。
前台的效果如下:

首页:

其他页面:

前台的区块内容是读取后台设置的内容,当我们在后台区块页修改内容后,前台也会相应改变。

评论

北极狐的头像

好文,不过我这样定义好模块后,直接在page.tpl.php等模板页里用方法调用的,绕过了后台的UI界面。。这样可行不呢?

ssiufoo的头像

有个问题问一下这里, 就是官网的这句没看懂

pages: (optional) See 'visibility' above. A string that contains one or more page paths separated by '\n', '\r', or '\r\n' when 'visibility' is set to BLOCK_VISIBILITY_NOTLISTED or BLOCK_VISIBILITY_LISTED

 

如果是我想默认显示到比如,,node/1 和node/2 这两个页面的话怎么写pages啊

分隔符是\n?  还是\r 还是 \r\n啊?  我试了下\r竟然直接搞出一行node/1\rnode/2

问当

'visibility' => BLOCK_VISIBILITY_LISTED,

    'pages' =>'这里怎么写?',

 

 

期待诗人讲一下 为block 在modle里自定义一个tpl

function blocktest_theme($existing, $type, $theme, $path) {
  return array(
    'blocktest => array(
          'template' => 'template/blocktest',
       'variables' => array(),
     
    )
  );
}