Drupal 7 中文教程 代码部分,
这里面包含了教程中所有的代码部分,包括模块的实例代码,菜单的实例代码,用户的实例代码,各个部分的实例代码。
所有的代码,都是原创的,源自于多年的实践经验。
<?php
/**
* @file
* isbn validation
*/
Drupal info文件:
name = ISBN Validation
description = "Add ISBN validation to text field"
core = 7.x
dependencies[] = field
dependencies[] = field_ui
module文件:
/**
* Implements hook_field_attach_validate().
*/
function isbn_validation_field_attach_validate($entity_type, $entity, &$errors) {
list($id, $vid, $bundle) = entity_extract_ids($entity_type, $entity);
if($entity_type =='node' && $bundle == 'book'){
$field_isbn_length = strlen($entity->field_isbn['und'][0]['value']);
if(($field_isbn_length != 10) && ($field_isbn_length != 13)){
$errors['field_isbn']['und'][0][] = array(
'error' => 'field_isbn',
'message' => t('无效的ISBN号.'),
);
}
}
}
<?php
/**
* @file
* 省市县三级联动实例代码,
*/
/**
* 实现钩子hook_menu().
*/
function shengshixian_menu() {
$items['ssx'] = array(
'title' => '省市县',
'page callback' => 'shengshixian_test_page',
'access callback' => TRUE,
'type' => MENU_CALLBACK,
);
return $items;
}
/**
* 路径“ssx”页面的回调函数
*/
function shengshixian_test_page(){
$render_array = array();
//我们为这个页面设置标题
drupal_set_title('省市县三级联动');
//页面的正文为一个表单,注意drupal_get_form返回的不是html,需要使用drupal_render呈现一下。
$render_array['#markup'] .= drupal_render(drupal_get_form('shengshixian_test_form'));
//Drupal7的页面回调,返回的应该是一个数组,只有在退化形式下,才返回字符串。
return $render_array;
}
/**
* 表单shengshixian_test_form的构建函数
*/
function shengshixian_test_form($form, &$form_state){
//设置省市县对应元素的默认值
$default_sheng = !empty($form_state['values']['sheng']) ? $form_state['values']['sheng'] : '';
$default_shi = !empty($form_state['values']['shi']) ? $form_state['values']['shi'] : '';
$default_xian = !empty($form_state['values']['xian']) ? $form_state['values']['xian'] : '';
//构建省份的选项数组,首先设置了一个提示语
$sheng_options = array(
'' => '请选择省份',
);
//向数据库中查询省份信息,
$query_sheng = db_select('taxonomy_term_data','ttd')
->fields('ttd', array('tid', 'name'));
//因为省份是第一级术语,分类术语的父亲为0
$query_sheng->leftJoin('taxonomy_term_hierarchy', 'tth', 'ttd.tid = tth.tid ');
$query_sheng->condition('tth.parent', 0);
//需要确定术语所在的词汇表,就是我们在前面创建的地区
$query_sheng->leftJoin('taxonomy_vocabulary', 'tv', 'ttd.vid = tv.vid ');
$query_sheng->condition('tv.machine_name', 'diqu');
//按照tid排序,并执行
$result_sheng = $query_sheng->orderBy('tid')->execute();
//将返回的结果,进行迭代,为$sheng_options赋值。
foreach ($result_sheng as $record) {
$sheng_options[$record->tid] = $record->name;
}
//省份表单元素
$form['sheng'] = array(
'#title' => t('请选择您所在的省份?'),
'#type' => 'select',
'#options' => $sheng_options,
'#default_value' => $default_sheng,
//#ajax属性数组
'#ajax' => array(
'callback' => 'shengshixian_sheng_callback',
'wrapper' => 'shi-wrapper-div',
'method' => 'replace',
'effect' => 'fade',
),
);
//构建市的选项数组,首先设置了一个提示语
$shi_options = array(
'' => '请选择市',
);
//在省份不为空的情况下,取该省份下的所有的市
if(!empty($default_sheng)){
//向数据库中查询术语信息,
$query_shi = db_select('taxonomy_term_data','ttd')
->fields('ttd', array('tid', 'name'));
//将其父术语限定在前面的省份的具体值上
$query_shi->leftJoin('taxonomy_term_hierarchy', 'tth', 'ttd.tid = tth.tid ');
$query_shi->condition('tth.parent', $default_sheng);
//由于省份信息里面,已经包含了词汇表信息,所以我们不再需要关联这个taxonomy_vocabulary表。
//$query_sheng->leftJoin('taxonomy_vocabulary', 'tv', 'ttd.vid = tv.vid AND tv.machine_name = :machine_name', array(':machine_name' => 'diqu'));
//按照tid排序,并执行
$result_shi = $query_shi->orderBy('tid')->execute();
//将返回的结果,进行迭代,为$shi_options赋值。
foreach ($result_shi as $record) {
$shi_options[$record->tid] = $record->name;
}
}
/*
//测试代码,中间测试的时候用的,这里保留了,开发模块所用到的测试代码很多,多数都已删除。
$form['test'] = array(
'#markup' => '123456:'.$default_sheng
);
*/
//表单元素市
$form['shi'] = array(
'#title' => t('请选择您所在的市?'),
'#prefix' => '<div id="shi-wrapper-div">',
'#suffix' => '</div>',
'#type' => 'select',
'#options' => $shi_options,
'#default_value' => $default_shi,
'#ajax' => array(
'callback' => 'shengshixian_shi_callback',
'wrapper' => 'xian-wrapper-div',
'method' => 'replace',
'effect' => 'fade',
),
);
//构建县的选项数组,首先设置了一个提示语
$xian_options = array(
'' => '请选择县',
);
//在市不为空的情况下,取该市下的所有的县
if(!empty($form_state['values']['shi'])){
//向数据库中查询术语信息,
$query_xian = db_select('taxonomy_term_data','ttd')
->fields('ttd', array('tid', 'name'));
//将其父术语限定在前面的市的具体值上
$query_xian->leftJoin('taxonomy_term_hierarchy', 'tth', 'ttd.tid = tth.tid AND tth.parent = :parent', array(':parent' => $form_state['values']['shi']));
$query_xian->condition('tth.parent', $default_shi);
//由于最前面省份信息里面,已经包含了词汇表信息,所以我们不再需要关联这个taxonomy_vocabulary表。
//$query_sheng->leftJoin('taxonomy_vocabulary', 'tv', 'ttd.vid = tv.vid AND tv.machine_name = :machine_name', array(':machine_name' => 'diqu'));
//按照tid排序,并执行
$result_xian = $query_xian->orderBy('tid')->execute();
//将返回的结果,进行迭代,为$xian_options赋值。
foreach ($result_xian as $record) {
$xian_options[$record->tid] = $record->name;
}
}
//表单元素县
$form['xian'] = array(
'#title' => t('请选择您所在的县/区?'),
'#prefix' => '<div id="xian-wrapper-div">',
'#suffix' => '</div>',
'#type' => 'select',
'#options' => $xian_options,
'#default_value' => $default_xian,
);
//提交按钮
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('提交'),
);
return $form;
}
/**
* 表单元素sheng,它的值变更时,对应的Ajax回调函数。
*/
function shengshixian_sheng_callback($form,&$form_state){
//根据当前省份,重新确定市的可选项。返回重新构建的表单元素shi
return $form['shi'];
}
/**
* 表单元素sheng,它的值变更时,对应的Ajax回调函数。
*/
function shengshixian_shi_callback($form,&$form_state){
//根据当前所选的市,重新确定县的可选项。返回重新构建的表单元素xian
return $form['xian'];
}
<?php
/**
* @file
* 当登录Drupal7站点时,检查是否在drupal6站点存在这个帐户,
* 如果存在,将其保存到新的站点.
*/
/**
* 实现钩子hook_form_FORMID_alter().
*/
function d6user_form_alter(&$form, &$form_state, $form_id){
//这里我们对于表单user_login,user_login_block同时添加了一个验证器
if($form_id == 'user_login' || $form_id == 'user_login_block'){
$form['#validate'] = d6user_login_default_validators();
}
}
/**
* 我们自己的登录验证函数集合,.
*/
function d6user_login_default_validators(){
//注意这里面保留了Drupal自带的验证器,只是在中间加上了一个自定义的验证器。这些验证器的执行存在先后顺序的
return array('user_login_name_validate', 'd6user_user_form_validate', 'user_login_authenticate_validate', 'user_login_final_validate');
}
/**
* 我们自己定义的登录验证函数,它在user_login_authenticate_validate前面执行.
*/
function d6user_user_form_validate($form, &$form_state){
//form_set_error('name',t('用户名,密码不匹配.')); 这里保留了调试信息
$name = $form_state['values']['name'];
$pass = $form_state['values']['pass'];
if (!empty($name) && !empty($pass)) {
//drupal_set_message('123'); 这里保留了调试信息,用户调试代码,方便大家测试
$account = db_query("SELECT * FROM {users} WHERE name = :name ", array(':name' => $name))->fetchObject();
//如果用户名存在,则返回.
if ($account) {
return;
}else{
// $sql = "SELECT * FROM {users} WHERE name = :name AND pass = :pass";
//drupal_set_message('123456');
//我们向Drupal6站点的用户表进行查询,检查该用户是否存在。
db_set_active('d6user');
$account = db_query("SELECT * FROM users WHERE name = :name AND pass = :pass", array(':name' => $name, ':pass' => md5($pass)))->fetchObject();
db_set_active('default');
if($account){
// drupal_set_message('1234567');
//此时,用户帐号在Drupal6中存在,并且用户名密码正确
$userinfo = array(
'name' => $name,
'pass' => $pass,
'mail' => $account->mail,
'init' => $name,
'status' => 1,
'access' => REQUEST_TIME
);
//我们将查询到的信息保存到Drupal7的用户表中
$account = user_save(drupal_anonymous_user(), $userinfo);
}
}
}
}
<?php
/**
* @file
* 方便用户联系我们.
*/
/**
* 实现钩子hook_menu().
*/
function contactus_menu() {
$items = array();
//联系我们菜单项
$items['contactus'] = array(
'tilte' => '联系我们',
'page callback' => 'contactus_page',
'type' => MENU_CALLBACK,
'access callback' =>TRUE,
'file' => 'contactus.pages.inc',
);
//确认页面菜单项
$items['contactus/confirm'] = array(
'page callback' => 'contactus_confirm_page',
'type' => MENU_CALLBACK,
'access callback' =>TRUE,
'file' => 'contactus.pages.inc',
);
//致谢页面菜单项
$items['contactus/thanks'] = array(
'page callback' => 'contactus_thanks_page',
'type' => MENU_CALLBACK,
'access callback' =>TRUE,
'file' => 'contactus.pages.inc',
);
return $items;
}
/**
* 实现钩子hook_mail().
*/
function contactus_mail($key, &$message, $params){
$language = $message['language'];
switch ($key) {
case 'contact':
//邮件的标题
$message['subject'] = '联系我们';
//邮件正文,这里面包含:姓名、单位名称、电子邮件、电话号码、邮件正文、访问来源
$message['body'][] = '姓名:'.$params['name'];
$message['body'][] = '单位名称:'.$params['company_name'];
$message['body'][] = '电子邮件:'.$params['mail'];
$message['body'][] = '电话号码:'.$params['phone'];
$message['body'][] = '邮件正文:'.$params['contact'];
//对于访问来源,如果visit的值我们选择了“其它”,那么此时我们取$params['other'],否则取$params['visit']
$visit = "";
if($params['visit'] == 'other'){
$visit = $params['other'];
}else{
$visit = $params['visit'];
}
$message['body'][] = '访问来源:'. $visit;
}
}
/**
* “确认”页面的回调函数
*/
function contactus_confirm_page(){
//我们为这个页面设置标题
drupal_set_title('联系我们');
//这里首先作了判断,如果会话中没有设置contactus_form,返回contactus
if(empty($_SESSION['contactus_form'])){
drupal_goto('contactus');
}else{
}
$render_array = array(
'#markup' => '',
);
//该页面的正文为一个表单,注意对于表单,这里需要使用drupal_render呈现一下。
$render_array['#markup'] .= drupal_render(drupal_get_form('contactus_confirm_form'));
//Drupal7的页面回调,返回的应该是一个数组
return $render_array;
}
/**
* “确认”表单的构建函数
*/
function contactus_confirm_form(){
//添加我们自己的CSS,用来控制表单的样式
drupal_add_css(drupal_get_path('module', 'contactus').'/contactus.css');
//drupal_set_message(print_r($_SESSION['contactus_form']));
//表单元素“姓名”
$form['name'] = array(
'#title' => t('姓名'),
//表单元素的类型,这里为item
'#type' => 'item',
//'#default_value' => $_SESSION['contactus_form']['name'],
//表单元素的#markup,在Drupal6下面,我用的是#value,在7下面就无法工作,改为了#default_value,还是不行,
//最后改为#markup,才可以了
'#markup' => isset($_SESSION['contactus_form']['name'])?$_SESSION['contactus_form']['name']:"",
);
//表单元素“单位名称”
$form['company_name'] = array(
'#title' => t('单位名称'),
'#type' => 'item',
//这是我在调试的时候,使用#value、#default_value、#description分别测试时的代码,这里保留了。
//'#value' => $_SESSION['contactus_form']['company_name'],
//'#value' => '123456',
'#markup' => isset($_SESSION['contactus_form']['company_name'])?$_SESSION['contactus_form']['company_name']:"",
//'#description' => '123456',
);
//表单元素“电子邮件”
$form['mail'] = array(
'#title' => t('电子邮件'),
'#type' => 'item',
'#markup' => isset($_SESSION['contactus_form']['mail'])?$_SESSION['contactus_form']['mail']:"",
);
//表单元素“电话号码”
$form['phone'] = array(
'#title' => t('电话号码'),
'#type' => 'item',
'#markup' => isset($_SESSION['contactus_form']['phone'])?$_SESSION['contactus_form']['phone']:"",
);
//表单元素“邮件正文”
$form['contact'] = array(
'#title' => t('邮件正文'),
'#type' => 'item',
'#markup' => isset($_SESSION['contactus_form']['contact'])?$_SESSION['contactus_form']['contact']:"",
);
//表单元素“访问来源”
$form['visit'] = array(
'#title' => t('访问来源'),
'#type' => 'item',
'#markup' => isset($_SESSION['contactus_form']['visit'])?$_SESSION['contactus_form']['visit']:"",
);
//如果访问来源,我们选择了“其它”,此时使用other表单元素的值来替换$form['visit']['#markup']。
if( isset($_SESSION['contactus_form']['visit']) && $_SESSION['contactus_form']['visit'] == 'other'){
$form['visit']['#markup'] = isset($_SESSION['contactus_form']['other'])?$_SESSION['contactus_form']['other']:"";
}
/*
//表单元素“返回”按钮
$form['back'] = array(
'#type' => 'submit',
'#value' => t('返回'),
'#submit' => array('contactus_confirm_form_back'),
);
//表单元素“提交”按钮
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('提交'),
);
*/
//表单元素“返回”图片按钮
$form['image_back'] = array(
'#type' => 'image_button',
'#src' => drupal_get_path('module','contactus').'/images/button2-1.jpg',
//使用这个按钮提交时,对应的提交处理函数为contactus_confirm_form_back
'#submit' => array('contactus_confirm_form_back'),
'#executes_submit_callback' => TRUE,
//为表单元素添加两个属性,onmouseout、onmouseover,为了在鼠标移到按钮上时,显示不同的图片效果
'#attributes' =>array(
'onmouseout' => "this.src='".base_path().drupal_get_path('module','contactus')."/images/button2-1.jpg'",
'onmouseover' => "this.src='".base_path().drupal_get_path('module','contactus')."/images/button2-2.jpg'",
),
);
//表单元素“提交”图片按钮
$form['image_submit'] = array(
'#type' => 'image_button',
'#src' => drupal_get_path('module','contactus').'/images/button3-1.jpg',
'#executes_submit_callback' => TRUE,
//使用这个按钮提交时,对应的提交处理函数为contactus_confirm_form_submit
'#submit' => array('contactus_confirm_form_submit'),
'#attributes' =>array(
'onmouseout' => "this.src='".base_path().drupal_get_path('module','contactus')."/images/button3-1.jpg'",
'onmouseover' => "this.src='".base_path().drupal_get_path('module','contactus')."/images/button3-2.jpg'",
),
);
return $form;
}
/**
* 返回按钮对应的提交函数
*/
function contactus_confirm_form_back($form, &$form_state){
//简单的重定向到contactus页面
$form_state['redirect'] = 'contactus';
}
/**
* 提交按钮对应的提交函数
*/
function contactus_confirm_form_submit($form, &$form_state){
$values = NULL;
//从会话中获取用户最初提交的值,并将$_SESSION['contactus_form']置为空。
if(empty($_SESSION['contactus_form'])){
drupal_goto('contact');
}else{
$values = $_SESSION['contactus_form'];
unset($_SESSION['contactus_form']);
}
//收件人地址,这里为作者的邮箱
$to = 'g089h515r806@gmail.com';
//用户填写的邮箱地址
$from = $values['mail'];
//发送邮件
drupal_mail('contactus', 'contact', $to, language_default(), $values, $from);
//简单的重定向到致谢页面
$form_state['redirect'] = 'contactus/thanks';
}
/**
* “致谢”页面的回调函数
*/
function contactus_thanks_page(){
//我们为这个页面设置标题
drupal_set_title('联系我们');
$render_array = array(
'#markup' => '',
);
//Drupal7的页面回调,返回的应该是一个数组
$render_array['#markup'] .= '<div id="contactus-thanks">';
$render_array['#markup'] .= t('感谢您的来信,我们会在第一时间给您回复。');
$render_array['#markup'] .= '</div>';
return $render_array;
}
<?php
/**
* @file
* 各种页面的回调函数.
*/
/**
* “联系我们”页面的回调函数
*/
function contactus_page(){
//我们为这个页面设置标题
drupal_set_title('联系我们');
$render_array = array(
'#markup' => '',
);
//该页面的正文为一个表单,注意对于表单,这里需要使用drupal_render呈现一下。
$render_array['#markup'] .= drupal_render(drupal_get_form('contactus_form'));
//Drupal7的页面回调,返回的应该是一个数组
return $render_array;
}
/**
* “联系我们”表单的构建函数
*/
function contactus_form(){
//添加我们自己的CSS,用来控制表单的样式
drupal_add_css(drupal_get_path('module', 'contactus').'/contactus.css');
//提示信息,默认为markup类型。
$form['tips'] = array(
'#prefix' =>'<div id="tips">',
'#markup' => t('<span class="form-required">*</span> 号为必填项。'),
'#suffix' =>'</div>',
);
//表单元素“姓名”
$form['name'] = array(
//表单元素的#title属性,对应于实际输出中的label
'#title' => t('姓名'),
//表单元素的类型,这里为textfield
'#type' => 'textfield',
//这个表单元素是必填的
'#required' => TRUE,
//表单元素的默认值,这里使用了三位运算符和isset进行判定
'#default_value' =>isset($_SESSION['contactus_form']['name'])?$_SESSION['contactus_form']['name']:"",
//表单元素的描述,
'#description' => t('例如:周星驰'),
);
//表单元素“单位名称”
$form['company_name'] = array(
'#title' => t('单位名称'),
'#type' => 'textfield',
'#required' => TRUE,
'#default_value' =>isset($_SESSION['contactus_form']['company_name'])?$_SESSION['contactus_form']['company_name']:"",
'#description' => t('例如:北京无名信息技术公司'),
);
//表单元素“电子邮件”
$form['mail'] = array(
'#title' => t('电子邮件'),
'#type' => 'textfield',
'#required' => TRUE,
'#default_value' =>isset($_SESSION['contactus_form']['mail'])?$_SESSION['contactus_form']['mail']:"",
'#description' => t('例如:info@example.com'),
);
//表单元素“电话号码”
$form['phone'] = array(
'#title' => t('电话号码'),
'#type' => 'textfield',
'#required' => TRUE,
'#default_value' =>isset($_SESSION['contactus_form']['phone'])?$_SESSION['contactus_form']['phone']:"",
'#description' => t('例如:010-88888888'),
);
//表单元素“邮件正文”
$form['contact'] = array(
'#title' => t('邮件正文'),
//表单元素的类型,这里为textarea
'#type' => 'textarea',
'#required' => TRUE,
'#default_value' =>isset($_SESSION['contactus_form']['contact'])?$_SESSION['contactus_form']['contact']:"",
);
//访问来源的可选项
$visit_options = array(
'baidu' =>t('百度'),
'google' =>t('谷歌'),
'sohu' =>t('搜狐'),
'other' =>t('其它'),
);
//表单元素“访问来源”
$form['visit'] = array(
'#title' => t('访问来源'),
//表单元素的类型,这里为radios
'#type' => 'radios',
//单选按钮的可选项。
'#options' => $visit_options,
'#default_value' =>isset($_SESSION['contactus_form']['visit'])?$_SESSION['contactus_form']['visit']:"",
//为了便于控制radios的外观,我们使用#prefix、#suffix为其添加了一个带有ID的div
'#prefix' => '<div id="visit-radios">',
'#suffix' => '</div>',
);
//表单元素“其它”,它依赖于表单元素“访问来源”
$form['other'] = array(
'#title' => t('其它'),
'#type' => 'textfield',
'#default_value' =>isset($_SESSION['contactus_form']['other'])?$_SESSION['contactus_form']['other']:"",
//这里的意思是,当表单元素“访问来源”的值为“other”时,这个表单元素才显示出来
'#states' => array(
'visible' => array(
':input[name="visit"]' => array('value' => 'other'),
),
),
);
/*
//表单元素“确认”提交按钮
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('确认'),
);
*/
//表单元素“确认”提交按钮,这里采用了图片的形式
$form['image_submit'] = array(
//表单元素的类型,这里为image_button
'#type' => 'image_button',
//图片按钮特有的#src属性,
'#src' => drupal_get_path('module','contactus').'/images/button1-1.jpg',
'#value' => 'image_sub',
//为表单元素添加两个属性,onmouseout、onmouseover,为了在鼠标移到按钮上时,显示不同的图片效果
'#attributes' =>array(
'onmouseout' => "this.src='".base_path().drupal_get_path('module','contactus')."/images/button1-1.jpg'",
'onmouseover' => "this.src='".base_path().drupal_get_path('module','contactus')."/images/button1-2.jpg'",
),
//为了便于控制image_button的外观,我们使用#prefix、#suffix为其添加了一个带有ID的div
'#prefix' => '<div id="image-submit">',
'#suffix' => '</div>',
);
return $form;
}
/**
* contactus_form表单的验证函数
*/
function contactus_form_validate($form, &$form_state){
//这里使用正则表达式,来验证邮箱的有效性,注意,这里的正则表达式,包围在"/...../"之间。
if(!preg_match("/^[\w\-\.]+@[\w\-\.]+(\.\w+)+$/", $form_state['values']['mail'])){
form_set_error('mail',t('您输入的电子邮件地址格式不正确'));
}
}
/**
* contactus_form表单的提交函数
*/
function contactus_form_submit($form, &$form_state){
//把表单的值存放在会话中去,由于这里涉及到了两个不同的表单之间传值。
$_SESSION['contactus_form'] = $form_state['values'];
//表单重定向到确认页面
$form_state['redirect'] = 'contactus/confirm';
}
在自定义一个字段模块时,为节点类型添加一个这个类型的字段实例时,报了以下错误信息:
info文件:
name = Block More Link
description = Provide a more link for all blocks.
package = Other
version = VERSION
core = 7.x
configure = admin/config/block/morelink
install文件:
<?php
/**
* @file
* Install, update and uninstall functions for the block_morelink module.
*/
/**
* Implements hook_schema().
*/
function block_morelink_schema() {
$schema['block_morelink'] = array(
'description' => 'Stores more link path.',
'fields' => array(
'module' => array(
'type' => 'varchar',
'length' => 64,
'not null' => TRUE,
'description' => "The block's origin module, from {block}.module.",
),
'delta' => array(
'type' => 'varchar',
'length' => 32,
'not null' => TRUE,
'description' => "The block's unique delta within module, from {block}.delta.",
),
'url' => array(
'type' => 'varchar',
'length' => 255,
'not null' => TRUE,
'description' => "The more link url of a block.",
),
'title' => array(
'type' => 'varchar',
'length' => 255,
'not null' => TRUE,
'description' => "The more link title of a block.",
),
),
'primary key' => array('module', 'delta'),
'indexes' => array(
'url' => array('url'),
),
);
return $schema;
}
/**
* change 'primary key' to array('module', 'delta').
*/
function block_morelink_update_7000(&$sandbox) {
db_drop_primary_key('block_morelink');
db_add_primary_key('block_morelink', array('module', 'delta'));
}
module文件中的代码,你可以在drupal.org上下载最新的模块代码:
http://drupal.org/project/block_morelink
<?php
/**
* Implements hook_form_FORMID_alter().
*
* Adds more link path textfield to add block form.
*/
function block_morelink_form_block_add_block_form_alter(&$form, &$form_state) {
block_morelink_form_block_admin_configure_alter($form, $form_state);
}
function block_morelink_form_block_admin_configure_alter(&$form, &$form_state){
$result = db_query("SELECT url, title FROM {block_morelink} WHERE module = :module AND delta = :delta", array(
':module' => $form['module']['#value'],
':delta' => $form['delta']['#value'],
))->fetch();
$default_morelink_url = empty($result)?'':$result->url;
$default_morelink_title = empty($result)?'':$result->title;
//$default_value = '';
// More link settings.
$form['settings']['morelink'] = array(
'#type' => 'fieldset',
'#title' => t('More link settings'),
'#collapsible' => FALSE,
//'#description' => t('Specify more link url and title.'),
'#weight' => -1,
);
$form['settings']['morelink']['morelink_url'] = array(
'#type' => 'textfield',
'#title' => t('More Link url'),
'#maxlength' => 255,
'#description' => t('The More Link url of the block as shown to the user.') ,
'#default_value' => $default_morelink_url,
'#weight' => 0,
);
$form['settings']['morelink']['morelink_title'] = array(
'#type' => 'textfield',
'#title' => t('More Link title'),
'#maxlength' => 255,
'#description' => t('The More Link title of the block as shown to the user.') ,
'#default_value' => $default_morelink_title,
'#weight' => 1,
);
$form['#submit'][] = 'block_morelink_block_admin_configure_submit';
}
/**
* Form submit handler for block configuration form.
*/
function block_morelink_block_admin_configure_submit($form, &$form_state){
db_delete('block_morelink')
->condition('module', $form_state['values']['module'])
->condition('delta', $form_state['values']['delta'])
->execute();
if(!empty($form_state['values']['morelink_url'])){
$query = db_insert('block_morelink')->fields(array('url', 'title', 'module', 'delta'));
//foreach (array_filter($form_state['values']['types']) as $type) {
$query->values(array(
'url' => $form_state['values']['morelink_url'],
'title' => $form_state['values']['morelink_title'],
'module' => $form_state['values']['module'],
'delta' => $form_state['values']['delta'],
));
//}
$query->execute();
}
}
/**
* Process variables for block.tpl.php
*
* The $variables array contains the following arguments:
* - $block
*
* @see block.tpl.php
*/
function block_morelink_preprocess_block(&$variables) {
$result = db_query("SELECT url, title FROM {block_morelink} WHERE module = :module AND delta = :delta", array(
':module' => $variables['block']->module,
':delta' => $variables['block']->delta,
))->fetch();
$morelink_url = empty($result)?'':$result->url;
$morelink_title = empty($result)?'':$result->title;
$variables['block']->more = theme('block_more_link',array('url'=>$morelink_url,'title'=>$morelink_title));
}
/**
* Implements hook_menu().
*/
function block_morelink_menu() {
// Block settings.
$items['admin/config/block'] = array(
'title' => 'Block',
'description' => 'Block configuration.',
'position' => 'left',
'weight' => -10,
'page callback' => 'system_admin_menu_block_page',
'access arguments' => array('access administration pages'),
'file' => 'system.admin.inc',
'file path' => drupal_get_path('module', 'system'),
);
$items['admin/config/block/morelink'] = array(
'title' => 'More link',
'description' => 'the more link lable of block.',
'page callback' => 'drupal_get_form',
'page arguments' => array('block_morelink_label_settings'),
'access arguments' => array('administer site configuration'),
'weight' => -10,
// 'file' => 'system.admin.inc',
);
return $items;
}
function block_morelink_label_settings(){
$form['morelink_label'] = array(
'#type' => 'textfield',
'#title' => t('More Link lable'),
'#maxlength' => 40,
'#description' => t('The More Link lable of the block as shown to the user.') ,
'#default_value' => variable_get('morelink_label', 'more'),
'#weight' => -17,
);
return system_settings_form($form, TRUE);
}
function block_morelink_theme(){
return array(
'block_more_link' => array(
'variables' => array('url' => NULL,'title' => NULL,)
),
);
}
/**
* Returns HTML for a "more" link, like those used in blocks.
*
* @param $variables
* An associative array containing:
* - url: The url of the main page.
* - title: A descriptive verb for the link, like 'Read more'.
*/
function theme_block_more_link($variables) {
$output = "";
if(!empty($variables['url'])){
if (!empty($variables['title'])) {
$morelink_label = $variables['title'];
}
else {
$morelink_label = variable_get('morelink_label', 'more');
}
$output .= '<span class="block-more-link">' . l($morelink_label,$variables['url'],array('attributes'=>array('title'=>$variables['title']))). '</span>';
//$output .='<span class="block-more-link">' . t('<a href="@link" title="@title">More</a>', array('@link' => check_url($variables['url']), '@title' => $variables['title'])) . '</div>';
}
return $output;
}