Drupal Hooks и как да си направим модул за Drupal

Posted by Stanislav Nedelchev on Wed, 06/02/2010 - 00:55

Тази статия е незвършена и иска подобрение!
Тя е подобна на презентацията , която направих на първата друпал среща в софия.

Drupаl hooks
Какво преставляват и как да си напишем собствен модул с тяхна помощ.

Основни куки:

Hook_menu
Дефинира елемент в менюто и обръщение към страница
Hook_perm
Дефинира правата на потребителите
Hook_help
Създава помощ за модула

Node API
Дава възможност да се променя съдържание създадено от други модули.
Form API
С помоща на form api могат да се създават всякакви форми.

function page_example_menu() {
  $items['example/foo'] = array(
    'title' => 'Page example: (foo)',
    'page callback' => 'page_example_foo',
    'access arguments' => array('access foo content'),
  );
  $items['example/baz/%/%'] = array(
    'title' => 'Baz',
    'page callback' => 'page_example_baz',
    'page arguments' => array(2, 3),
    'access arguments' => array('access baz content'),
    'type' => MENU_CALLBACK,
  );
  return $items;
}
 
<php>
<img src="/files/u1/hooks-menu1.jpg" width="700" height="67" alt="" />
<pre>page_example_foo() </pre>
<php>
<?php function page_example_foo() 
{ return '<p>' . 
	t('The quick brown fox jumps over the lazy dog.') . ' </p>'; 
} 
?> 
 
<php>
<img src="/files/u1/hook-menu2.jpg" width="700" height="99" alt="" />
<pre>
page_example_baz($alice, $bob) 
</pre>
<php>
<?php
function page_example_baz($alice, $bob) {
 
  if (!is_numeric($alice) || !is_numeric($bob)) {
  return drupal_access_denied();
  }
 
  $list[] = t("Alice's number was @number.", array('@number' => $alice));
  $list[] = t("Bob's number was @number.", array('@number' => $bob));
  $list[] = t('The total was @number.', array('@number' => $alice + $bob));
 
  return t("baz content") . theme('item_list', $list);
}
?>
 
<php>
<a href="http://domain.com">http://domain.com</a> example/baz/1/2
<img src="/files/u1/hook-menu3.jpg" width="700" height="152" alt="" />
<pre>
hook_perm()
</pre>
<php>
function page_example_perm() 
{  
	return array(    
	'access foo content',    
	'access baz content',  );
}
 
<php>
<img src="/files/u1/hook-perm1.jpg" width="700" height="79" alt="" />
<pre>
hook_help()
</pre>
<php>
function page_example_help($path, $arg) {
  switch ($path) {
    case 'example/foo':
   return 
t('This sentence contains all the letters in the English alphabet.');
  }
}
 
 
<php>
Добавя помощ на страницата на адрес //example/foo
<img src="/files/u1/hook-help1.jpg" width="700" height="88" alt="" />
<strong>Form API</strong>
С помоща на Form API могат да се създават словни форми от всякакъв тип.
Да им се прилага валидация преди да се запишат в базата дании 
Също така използшането на form api ви гарантира по добра защитеност на вашето приложение.
<php>
function form_example_menu() {
  $items = array();
  $items['form_example/tutorial'] = array(
    'title' => t('Form Example: Tutorial'),
    'page callback' => 'drupal_get_form',
    'page arguments' => array('form_example_tutorial_1'),
    'access callback' => TRUE,
    'description' => t('A set of ten tutorials'),
    'file' => 'form_example_tutorial.inc',
    'type' => MENU_NORMAL_ITEM,
  );
 
function form_example_tutorial_1($form_state) {
 
  $form['description'] = array(
    '#type' => 'item',
    '#title' => t('A form with nothing but a textfield'),
  );
  // This is the first form element. It's a textfield with a label, "Name"
  $form['name'] = array(
    '#type' => 'textfield',
    '#title' => t('Name'),
  );
  return $form;
}
 
<php>
<img src="/files/u1/hook-form-api1.jpg" width="700" height="328" alt="" />
Сега да добавим и един бутон
<php>
$form['name'] = array(
    '#type' => 'fieldset',
    '#title' => t('Name'),
  );
 
 $form['name']['last'] = array(
    '#type' => 'textfield',
    '#title' => t('Last name'),
  );
 
$form['submit'] = array(
    '#type' => 'submit',
    '#value' => 'Submit',
 
 
<php>
<img src="/files/u1/hook-form-api2.jpg" width="700" height="325" alt="" />
 
<strong>Node API</strong>
С помоща на node api можем да променим съществуващо вече съдържание.
 
Дадените примери променят типа съдържание example node
 
<php>
function nodeapi_example_form_alter(&$form, $form_state, $form_id) {
  if ($form_id == 'node_type_form' && isset($form['identity']['type'])) {
  //Проверка дали сме в конфигурацията на съдържанието
    $form['workflow']['nodeapi_example'] = array(
      '#type' => 'radios',
      '#title' => t('NodeAPI Example Rating'),
      '#default_value' => variable_get('nodeapi_example_'. $form['#node_type']->type, 0),
      '#options' => array(0 => t('Disabled'), 1 => t('Enabled')),
      '#description' => t('Should this node have a rating attached to it?'),
    );
 
<php>
Най лесно е да се използва print_r($form) за да се види цялата информация за дадения nod. 
Ако имате инсталиран devel модула може да се принтира с krumo($form)
<img src="/files/u1/hook-node-api1.jpg" width="700" height="349" alt="" />
<php>
// Проверка дали редактираме съдържанието.
  elseif (isset($form['type']) && isset($form['#node']) && $form['type']['#value'] .'_node_form' == $form_id) 
   / /Ако рейтинга е включен добавяме списъка за райтинг
    $node = $form['#node'];
	//Проверяваме дали е активен реитинга за този тип съдъжание
    if (variable_get('nodeapi_example_'. $form['type']['#value'], 0))
      $form['nodeapi_example_rating'] = array(
        '#type' => 'select',
        '#title' => t('Rating'),
        '#default_value' => isset($node->nodeapi_example_rating) ? $node->nodeapi_example_rating : '',
        '#options' => array(0 => t('Unrated'), 1, 2, 3, 4, 5),
        '#required' => TRUE,
        '#weight' => 0,
      );
 
<php>
<img src="/files/u1/hook-node-api2.jpg" width="700" height="423" alt="" />
<strong>Модули</strong>
<ul>
 <li>Example_module.info</li>
 <li>Example_module.install</li>
 <li>Example_module.module</li>
</ul>
 
<strong>Example_module.info</strong>
<php>
; $Id: example_module.info,v 1.1.2.1 2009/10/04 01:41:43 davereid Exp $
name = example_module
description = An example module showing how define a custom content type.
package = Example modules
version = VERSION
core = 6.x
 
; Information added by drupal.org packaging script on 2010-04-15
version = "6.x-1.x-dev"
core = "6.x"
project = "examples"
datestamp = "1271333186"
 
<php>
<strong>Example_module.install</strong>
<php>
<?php
// $Id: example_module.install,v 1.1.2.1 2009/10/14 23:51:34 jhodgdon Exp $
 
/**
 * @file
 * example_module  module's install and uninstall code.
 */
 
/**
 * Implementation of hook_install().
 */
function example_module_install() {
  drupal_install_schema('example_module');
}
 
/**
 * Implementation of hook_uninstall().
 */
function example_module_uninstall() {
  drupal_uninstall_schema('example_module');
}
 
/**
 * Implementation of hook_schema().
 */
function example_module_schema() {
  $schema[' example_module '] = array(
    'fields' => array(
      'vid'      => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0),
      'nid'      => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0),
      'color'    => array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => ''),
      'quantity' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0),
    ),
    'primary key' => array('vid', 'nid'),
  );
 
  return $schema;
}
 
<php>
<strong>Example_module.module</strong>
<php>
function example_module_info() {
  return array(
    'node_example' => array(
      'name' => t('Example node'),
      'module' => 'node_example',
      'description' => t("This is an example node type with a few fields."),
      'has_title' => TRUE,
      'title_label' => t('Example Title'),
      'has_body' => TRUE,
      'body_label' => t('Example Body'),
    )
  );
}
 
<php>

Comments

Изключително добър материал. Благодаря за него. Надявам се скоро да има още пояснения и примери по новите куки на Д7.

Add new comment

Refresh Type the characters you see in this picture. Type the characters you see in the picture; if you can't read them, submit the form and a new image will be generated. Not case sensitive.  Switch to audio verification.