Hooks

Hooks是module定义的特殊名称的funcion。通常用来修改core module的行为或数据。

php方式理解hook

为了完成某项任务定义函数,随着时间的推移,业务的变化,你想要修改这个函数,可是有些人已经使用了这个函数,这个时候该怎么办?
答案是:”永远不要修改既存代码”,hook就是用来解决这个问题的。

drupal的方式理解hook

我们想对drupal core module的功能进行修改,又不修改core module的代码,这个时候就需要用到hook。
当drupal core module中的hook被调用时,drupal会做以下3件事:

  1. 取得所有可用的module列表
  2. 询问每一个模块是否实现了对应的hook
  3. 如果模块回答“是”,drupal就会调用模块中的hook实现

Hooks vs. Event/Observers

Event/Observers say

Hey, just so you know, this happened

Hooks say

Hey, we’re doing this thing, do you want to be part of it?

怎样实现hook

  1. 去*.api.php中找hook函数定义和对应的示例
  2. 拷贝1中hook函数到你的module’s .module文件
  3. 修改hook函数名,替换hook为自定义module名
  4. 编辑注释为”Implements hook函数名”
  5. 修改hook函数内容

怎样定义hook

  1. 给hook函数起个唯一的名字
  2. 在module’s文件加下创建*.api.php文件,并记述怎样使用这个hook
  3. 在module’s 代码中调用hook

Types of hooks

  1. Hooks that answer a question
  2. Hooks that alter existing data
  3. Hooks that react to an action

hooks

form系

修改form时,首先想到的是hook_form_alter和hook_form_FORM_ID_alter
也有特殊情况,比如修改register form中password字段label时,就需要用到hook_element_info_alter

hook_form_alter()

1
2
3
4
5
function hooks_example_form_alter(&$form, FormStateInterface $form_state, $form_id) {
if ($form_id === 'user_login_form') {
$form['name']['#description'] = t('This text has been altered by hooks_example_form_alter().');
}
}

hook_form_FORM_ID_alter()

1
2
3
4
5
6
7
8
9
10
function hooks_example_form_node_form_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id) {
if (isset($form['promote'])) {
$form['promote']['#access'] = FALSE;
}
// hide sticky at top of lists option
if (isset($form['sticky'])) {
$form['sticky']['#access'] = FALSE;
}
}

hook_element_info_alter()

修改register form中password字段label

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function hooks_example_element_info_alter(&$type) {
if (isset($type['password_confirm'])) {
$type['password_confirm']['#process'][] = 'hooks_example_process_password_confirm';
}
}
function hooks_example_process_password_confirm($element) {
if ($_ENV['REQUEST_URI'] == '/user/register') {
if ($element['#array_parents'][0] == 'account') {
$element['pass1']['#title'] = 'New password'; //Set the title as per your needs
$element['pass1']['#attributes']['placeholder'] = t('Password');
$element['pass2']['#title'] = 'Password again';
$element['pass2']['#attributes']['placeholder'] = t('Confirm password');
}
}
return $element;
}

views系

hook_views_pre_render()

在views表示前,修改字段的值

1
2
3
4
5
6
7
8
9
function hooks_example_views_pre_render(\Drupal\views\ViewExecutable $view) {
$results = $view->result;
foreach ($results as $key => $result) {
if ($view->element['#view_id'] == 'article_list') {
$field_title = $result->_entity->title->value;
$result->_entity->title->value = $field_title . ' alter by hook_views_pre_render' ;
}
}
}

参考资料

core hook list
good article discussing how Drupal module/hook system works
Understanding the hook system for Drupal modules
the overview of module hooks
What Are Hooks?
hook_element_info_alter
hook_form_FORM_ID_alter
hook_views_pre_render