Modulo Drupal per nuovo tipo di contenuto

In Drupal è molto semplice sviluppare un modulo che permeta di avere a disposizione un nuovo tipo di contenuto che estenda il classico nodo.

Vediamo come sviluppare un modulo che aggiunga il tipo di contenuto libro.

Creiamo la cartella node_book che andremo a mettere nella cartella modules del nostro sito.
Dentro questa cartella mettiamo il file node_book.info con le specifiche del nodo:
<br /> ; $Id$<br /> name = node book<br /> description = "nodo libro"<br /> core = 6.x<br />

e il file node_book.module con il codice vero e proprio.

Ecco i vari hook che si devono implementare:
Hook menu
<br /> function node_book_menu()<br /> {<br /> $items[] = array( 'path' => 'node_book', 'callback' => 'node_book_page', 'access' => true, 'type' => MENU_CALLBACK );<br /> return $items;<br /> }<br />

hook perm
<br /> function node_book_perm()<br /> {<br /> return array('create book node', 'edit own book nodes');<br /> }<br />
hook access
function node_book_access($op, $node, $account) {<br /> if ($op == 'create') {<br /> // Only users with permission to do so may create this node type.<br /> return user_access('create nameofnodetype', $account);<br /> }<br /> // Users who create a node may edit or delete it later, assuming they have the<br /> // necessary permissions.<br /> if ($op == 'update' || $op == 'delete') {<br /> if (user_access('edit own nameofnodetype', $account) &#038;&#038; ($account->uid == $node->uid)) {<br /> return TRUE;<br /> }<br /> }<br /> }

hook help
`function node_book_help($path, $arg) {
switch ($path) {
case ‘admin/help#block’:
return ‘

'. t('Blocks are boxes of content that may be rendered into certain regions of your web pages, for example, into sidebars. Blocks are usually generated automatically by modules (e.g., Recent Forum Topics), but administrators can also define custom blocks.') .'

';

case 'admin/build/block':
return t('

Blocks are boxes of content that may be rendered into certain regions of your web pages, for example, into sidebars. They are usually generated automatically by modules, but administrators can create blocks manually.

If you want certain blocks to disable themselves temporarily during high server loads, check the "Throttle" box. You can configure the auto-throttle on the throttle configuration page after having enabled the throttle module.

You can configure the behaviour of each block (for example, specifying on which pages and for what users it will appear) by clicking the "configure" link for each block.

', array('@throttle' => url('admin/settings/throttle')));
}
}` Ora passiamo agli hook che implementano veramente il nostro modulo: **hook form** `
function node_book_form(&$node) {
$type = node_get_types('type', $node);
if ($type->has_title) {
$form['title'] = array(
'#type' => 'textfield',
'#title' => check_plain($type->title_label),
'#required' => TRUE,
'#default_value' => $node->title,
'#weight' => -5
);
}
if ($type->has_body) {
// In Drupal 6, we can use node_body_field() to get the body and filter
// elements. This replaces the old textarea + filter_form() method of
// setting this up. It will also ensure the teaser splitter gets set up
// properly.
$form['body_field'] = node_body_field($node, $type->body_label, $type->min_word_count);
}
// NOTE in node_example there is some addition code here not needed for this simple node-type
// Now we define the form elements specific to our node type.
$form['editor'] = array(
'#type' => 'textfield',
'#title' => t('Editore'),
'#default_value' => isset($node->editor) ? $node->editor : '',
);
$form['book_author'] = array(
'#type' => 'textfield',
'#title' => t('Autore'),
'#default_value' => isset($node->book_author) ? $node->book_author : '',
);
$form['place'] = array(
'#type' => 'textfield',
'#title' => t('Luogo'),
'#default_value' => isset($node->place) ? $node->place : '',
);
$form['year'] = array(
'#type' => 'textfield',
'#title' => t('Anno'),
'#default_value' => isset($node->year) ? $node->year : '',
);
$form['book_type'] = array(
'#type' => 'textfield',
'#title' => t('Tipo'),
'#default_value' => isset($node->book_type) ? $node->book_type : '',
);
$form['magazine'] = array(
'#type' => 'textfield',
'#title' => t('Rivista'),
'#default_value' => isset($node->magazine) ? $node->magazine : '',
);
return $form;
}` **hook insert** /** * Implementation of hook_insert(). * * As a new node is being inserted into the database, we need to do our own * database inserts. */ `function node_book_insert($node) {
db_query("INSERT INTO {node_book} (vid, nid, editor, book_author, place, year, book_type, magazine) VALUES (%d, %d, '%s', '%s', '%s', '%s', '%s', '%s')", $node->vid, $node->nid,$node->editor,$node->book_author,$node->place,$node->year,$node->book_type,$node->magazine);
}` **hook update** `/**
* Implementation of hook_update().
*
* As an existing node is being updated in the database, we need to do our own
* database updates.
*/
function node_book_update($node) {
// if this is a new node or we're adding a new revision,
if ($node->revision) {
node_book_insert($node);
}
else {
db_query("UPDATE {node_book} SET editor='%s', book_author='%s', place='%s', year='%s', book_type='%s', magazine='%s' WHERE vid = %d", $node->editor, $node->book_author, $node->place, $node->year, $node->book_type, $node->magazine, $node->vid);
}
}
` **hook nodeapi** `/**
* Implementation of hook_nodeapi().
*
* When a node revision is deleted, we need to remove the corresponding record
* from our table. The only way to handle revision deletion is by implementing
* hook_nodeapi().
*/
function node_book_nodeapi(&$node, $op, $teaser, $page) {
switch ($op) {
case 'delete revision':
// Notice that we're matching a single revision based on the node's vid.
db_query('DELETE FROM {node_book} WHERE vid = %d', $node->vid);
break;
}
}` **hook_delete** /** * Implementation of hook_delete(). * * When a node is deleted, we need to remove all related records from out table. */ function node\_book\_delete($node) { // Notice that we’re matching all revision, by using the node’s nid. db\_query(‘DELETE FROM {node\_book} WHERE nid = %d’, $node->nid); } **hook load** `/**
* Implementation of hook_load().
*
* Now that we've defined how to manage the node data in the database, we
* need to tell Drupal how to get the node back out. This hook is called
* every time a node is loaded, and allows us to do some loading of our own.
*/
function node_book_load($node) {
$additions = db_fetch_object(db_query('SELECT editor,book_author,place,year,book_type,magazine FROM {node_book} WHERE vid = %d', $node->vid));
return $additions;
}
` **hook view** `/**
* Implementation of hook_view().
*
* This is a typical implementation that simply runs the node text through
* the output filters.
*/
function node_book_view($node, $teaser = FALSE, $page = FALSE) {
$node = node_prepare($node, $page);
$node->content['myfield'] = array(
'#value' => 'Editore: '.$node->editor.'
'.'Autore: '.$node->book_author.'
'.'Luogo: '.$node->place.'
'.'Anno: '.$node->year.'
'.'Tipologia: '.$node->book_type.'
',
'#weight' => 1,
);
return $node;
}
` Ora manca solo il DB, ecco la tabella per i campi in più del nostro nodo CREATE TABLE node_book ( vid int(10) unsigned NOT NULL default ’0′, nid int(10) unsigned NOT NULL default ’0′, editor varchar(255) NOT NULL default ”, book_author varchar(255) NOT NULL default ”, place varchar(255), year varchar(255), book_type varchar(255), magazine varchar(255), PRIMARY KEY (vid, nid), KEY \`node\_type\_book_nid\` (nid) ) Dopo aver creato la tabella e attivato il modulo avrete un nuovo tipo di contenuto disponibile.