现在的位置: 首页 > 综合 > 正文

Drupal hook_block 使用模块显示区块

2018年02月07日 ⁄ 综合 ⁄ 共 5818字 ⁄ 字号 评论关闭

我们的模块
将在一个 Drupal 区块中显示信息。为了做到这一点,我们需要实现hook_block() 函数。

记住,我们现在所做的是提供一个 Drupal 将调用的函数。当 Drupal 调用hook_block() 函数时,Drupal 传给它三个参数:

* $op
* $delta
* $edit

$op 参数将包含 Drupal 期望模块
执行的操作的类型信息。虽然我们实现的只是单一的钩子,但它能够执行各种不同的操作。要模块
输出有关自身的基本信息吗?还是要显示区块?或者提供一些管理信息?$op 的值将明确操作的类型。

$op 的值可以是下列四个之一:

* list: 当模块
应该提供自身信息时传递这个值。例如,当模块
管理界面显示模块
列表时,$op 参数被设置为 list。
* view: 当 Drupal 期望区块钩子提供显示给用户的内容信息时,传递这个值。
* configure:当 Drupal 期望出现一个管理表单对区块进行配置时,传递这个值。稍后我们将看到这一点。
* save: 当需要保存来自配置表单的配置信息时,传递这个值。

当执行某个特殊操作时,设定 $delta 参数。当 $op 被设置为 "view",亦即显示区块的操作时,$delta
也将同时设定。$delta 包含有关被显示内容的额外信息。我们在第一例子中不使用这个参数,但本书稍后的例子中将会用到。可以看一下第 4
章的另一个 hook_block() 的实现示例。

注:使用 delta,你可以定义能显示几种不同区块的单个 hook_block() 函数。例如,我们也许可以定义两个
delta——一个用来显示我们的 Goodreads 书架,另一个显示我们的 Goodreads
账户信息。究竟显示哪一个,将取决于传递给goodread_block() 函数的 $delta 值是哪一个。本书的其它模块
将使用 delta.

最后,$edit 参数是配置过程中使用的(调用 save 操作时)。因为我们在第一个例子中不实现那个操作,我们不用这个参数。

注:Drupal 的文档十分细致,API文档在 http://api.drupal.org
. 更多关于hook_block() 参数的信息参见这个 URL: http://api.drupal.org/api/function/hook_block/6
.

所有的钩子方法都要遵守模块
命名惯例: <module name>_<hook name>。因此我们的命名为 goodreads_block()。

/**
* Implementation of hook_block()
*/
function goodreads_block($op='list', $delta=0, $edit=array()) {
switch ($op) {
case 'list':
$blocks[0]['info'] = t('Goodreads Bookshelf');
return $blocks;
case 'view':
$blocks['subject'] = t('On the Bookshelf');
$blocks['content'] = t('Temporary content');
return $blocks;
}
}

根据 Drupal 的惯例,我们在函数前加了一个文档块。对于钩子,习惯上在文档中指明它实现的是哪个钩子。

随后是我们的函数原型:

function goodreads_block($op='list',$delta=0, $edit=array())

$op, $delta, 和 $edit 参数上面解释过了。每个参数都有一个初始默认值。在这里,我们遵从默认惯例,但如果你愿意,可以把它们定义为其它值。

正如我前面提到的,$op 参数可以设定为几个不同值之一。

我们在这个函数中做什么,在很大程度上取决于 $op 设定为那 4 个值中的哪一个。因此,我们在函数中做的第一件事就是使用 switch 语句判断操作的种类。

在 switch 语句中,每个 case 处理一种不同的操作。目前,我们没有什么管理配置要执行,因此没有处理 configure 或 save 操作的 case。我们只需要处理list 和 view 操作。让我们仔细看看每种情况。

case 'list':
$blocks[0]['info'] = t('Goodreads Bookshelf');
return $blocks;

当 Drupal 调用这个钩子时,如果 $op 设为 'list',那么这个模块
将返回一个二维数组,内容如下所示:

array(
[0]=> (
'info' => 'Goodreads Bookshelf'
))

这个数组中的每个元素都是一个区块描述字,它提供了关于此区块所实现的功能的信息。对于这个函数能够识别的每个 $delta 值,在此都应有一个相应的项。我们的区块只返回一个值(我们没有使用 delta),因此在区块描述字数组中只有一项。

在关联数组中,一个区块描述字可以包含几个不同的域。有一个是必须的:我们上面设置的 'info' 域。但我们也可以提供有关缓存、默认权重、定位信息等。

注:有关 hook_block() 的方方面面的详细信息,参见API文档:http://api.drupal.org/api/function/hook_block/6

Drupal 使用 'info' 域在模块
管理列表上显示一个项,我们在本章的模块
安装一节将看到这个模块
管理列表。
<?php
/**
* 区块钩子实现
*/

function product_block($op = 'list', $delta = 0,$edit = array()) {
global $user;
switch($op){
case 'list':// 下面我定义了四个区块列表,这里主要是为首页显示信息定义的,定义了以后会在后台显示你帝国一的区块信息,不信你可以试试
$blocks[0]['info'] = t('最新公司动态');
$blocks[0]['cache'] = BLOCK_NO_CACHE;

$blocks[1]['info'] = t('公司公告区块');
$blocks[1]['cache'] = BLOCK_NO_CACHE;

$blocks[2]['info'] = t('推荐产品');
$blocks[2]['cache'] = BLOCK_NO_CACHE;

$blocks[3]['info'] =t('图片新闻');
$blocks[3]['cache']= BLOCK_NO_CACHE;
return $blocks;
case 'configure': // 这里就是定义区块的一些属性,比如新闻显示条数等,
$form = array();
if($delta == 0){ //如果是'最新公司动态' 那我来设置一下要显示的新闻条数
$form['product_block_news_count'] = array(
'#type' => 'select',
'#title' => t('最大数目'),
'#default_value' =>variable_get('product_block_news_count',6),// variable_get 来得到这个变量的值
'#options' => drupal_map_assoc(array(2, 4, 6, 8, 10, 16, 20, 24, 28, 30)),
);
}
else if($delta == 1){
$form['product_block_note_content'] = array(
'#type' => 'textarea',
'#title' => t('信息内容'),
'#default_value' =>variable_get('product_block_note_content',6),
);
}
else if($delta == 2){
$form['product_block_top_new_product'] = array(
'#type' => 'textfield',
'#title' => t('展示数量'),
'#default_value' => variable_get('product_block_top_new_product',6),
);
}
else if($delta == 3){
$form['product_block_images_news_count'] = array( // $from['表单变量'] 要和 variable_get['变量'] 一样 因为它就是get from 表单的一个名称
'#type' => 'select',
'#title' => t('图片新闻数量'),
'#default_value' => variable_get('product_block_images_news_count',2),
'#options' => drupal_map_assoc(array(2,3,4,6,8,10,12,14,16,18)),
);
}
return $form;
case 'save':// 这里主要是保存区块变量信息的操作 就等于是save事件,然后会激活下面的操作
if($delta == 0){
//注意这里是保持数据,用的是_set
variable_set('product_block_news_count',$edit['product_block_news_count']);
}
else if($delta == 1){
variable_set('product_block_note_content',$edit['product_block_note_content']);
}
else if($delta == 2){
variable_set('product_block_top_new_product',$edit['product_block_top_new_product']);
}
else if($delta ==3){
variable_set('product_block_images_news_count',$edit['product_block_images_news_count']);
}
break;
case 'view':// 这就是VIEW事件操作了。
if($delta == 0 && user_access('access content')){
$max_news_count = variable_get('product_block_news_count',1); //得到一个最新闻变量的值
$result = db_query_range(db_rewrite_sql("SELECT n.nid, n.title,
n.sticky,n.created FROM {node} n WHERE n.type = 'story' AND n.status =
1 ORDER BY n.sticky DESC, n.created DESC"), 0, $max_news_count);
if ($node_title_list = pnode_title_list($result)) {
$block['content'] = $node_title_list; // 给区块内容赋值
$block['content'] .= theme('more_link', url('taxonomy/term/8+9'),
t('Read the latest story entries.')); //加上一个更多衔接
$block['subject'] = t('最新公司动态'); // 区块内容显示的标题

return $block;
}
}

else if($delta == 1 && user_access('access content')){
$block['subject'] = t('公司公告');
$block['content'] =variable_get('product_block_note_content',0);// 我把公告直接作为变量保持在变量表里了
return $block;
}

else if($delta == 2 && user_access('view product')){//
这里使用了view product 权限,如果用access_content 权限不起作用 因为前面product_access
已经设置了一个view,所以不会继承上一级node权限.当时我就匿名看不到信息!
$max_top_new_product = variable_get('product_block_top_new_product',6);

$block['content'] = product_loadfiles($max_top_new_product,'product'); //这里主要是用于现实产品图片信息的函数调用
$block['subject'] = t('ff');
return $block;

}

else if($delta ==3 && user_access('access content')){
$max_images_news_count = variable_get('product_block_images_news_count',2);
$block['content'] =product_loadfiles($max_images_news_count,'story');
$block['subject'] = t('title');
return $block;
}

}
}
function product_loadfiles($count,$type) {//读取图片

$result = db_query_range(db_rewrite_sql("SELECT
u.fid,f.filepath,n.title,n.nid FROM {upload} u INNER JOIN {files} f ON
u.fid = f.fid INNER JOIN {node} n ON n.nid = u.nid WHERE n.type
='".$type."' ORDER BY n.sticky DESC, n.created DESC "), 0, $count);

while ($ff = db_fetch_object($result)) {

$output .= "<li><a href=node/".$ff->nid."><img
src=".$ff->filepath." width=80
height=60><span>".$ff->title."</span></a></li>";
//$output.=$ff->title;
}
return $output;

}
?>

抱歉!评论已关闭.