Community Documentation

node_example.module

  1. examples
    1. 6 node_example.module
    2. 7 node_example.module
    3. 8 node_example.module
  2. drupal
    1. 4.6 node_example.module
    2. 4.7 node_example.module
    3. 5 node_example.module

This is an example outlining how a module can be used to define a new node type.

(Note that custom node types are most often created with CCK in recent versions of Drupal.)

Our example node type will allow users to specify a "color" and a "quantity" for their nodes; some kind of rudimentary inventory-tracking system, perhaps? To store this extra information, we need an auxiliary database table as defined in node_example_schema().

Functions & methods

NameDescription
node_example_accessImplementation of hook_access().
node_example_deleteImplementation of hook_delete().
node_example_formImplementation of hook_form().
node_example_infoExplain how the module demonstrates a new node type.node_example.test
node_example_insertImplementation of hook_insert().
node_example_loadImplementation of hook_load().
node_example_menuImplementation of hook_menu().
node_example_nodeapiImplementation of hook_nodeapi().
node_example_node_infoImplementation of hook_node_info().
node_example_permImplementation of hook_perm().
node_example_themeImplementation of hook_theme().
node_example_updateImplementation of hook_update().
node_example_validateImplementation of hook_validate().
node_example_viewImplementation of hook_view().
theme_node_example_order_infoA custom theme function.
View source
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
<?php

/**
 * @file
 * This is an example outlining how a module can be used to define a new
 * node type.
 *
 * (Note that custom node types are most often created with CCK in recent
 * versions of Drupal.)
 *
 * Our example node type will allow users to specify a "color" and a "quantity"
 * for their nodes; some kind of rudimentary inventory-tracking system, perhaps?
 * To store this extra information, we need an auxiliary database table as
 * defined in node_example_schema().
 */

/**
 * @defgroup node_example Example: Node
 * @ingroup examples
 * @{
 * Creating a new content type in a module. (drupal 6)
 *
 * This is an example outlining how a module can be used to define a new
 * node type.
 *
 * (Note that custom node types are most often created with CCK in recent
 * versions of Drupal.)
 *
 * Our example node type will allow users to specify a "color" and a "quantity"
 * for their nodes; some kind of rudimentary inventory-tracking system, perhaps?
 * To store this extra information, we need an auxiliary database table as
 * defined in node_example_schema().
 *
 * This example is part of the Examples for Developers Project which you can download
 * and experiment with here: http://drupal.org/project/examples
 */

/**
 * Implementation of hook_menu().
 */
function node_example_menu() {
  $items['examples/node_example'] = array(
    'title' => 'Node Example',
    'page callback' => 'node_example_info',
    'access callback' => TRUE,
  );
  return $items;
}

/**
 * Explain how the module demonstrates a new node type.node_example.test
 */
function node_example_info() {
	return t('The node example defines a new node type, "Example node type 1", which can be created at !link.', array('!link' => l(t('node/add/example-node-type-1'), 'node/add/example-node-type-1')));
}
/**
 * Implementation of hook_node_info().
 *
 * This is a required node hook. This function describes the nodes provided by
 * this module.
 *
 * The required attributes are:
 * - "name" provides a human readable name for the node,
 * - "module" tells Drupal how the module's functions map to hooks (i.e. if the
 *   module is node_example_foo then node_example_foo_insert will be called
 *   when inserting the node).
 * - "description" provides a brief description of the node type, which is
 *   shown when a user accesses the "Create content" page for that node type.
 *
 * The other optional, attributes:
 * - "has_title" boolean that indicates whether or not this node type has a
 *   title field.
 * - "title_label": the label for the title field of this content type.
 * - "has_body": boolean that indicates whether or not this node type has a
 *   body field.
 * - "body_label": the label for the body field of this content type.
 * - "min_word_count": the minimum number of words for the body field to be
 *   considered valid for this content type.
 *
 * The key in this example, "example_node_type_1", is the "machine name" of the
 * node type and is stored in {node}.type. The node's type value cannot be
 * changed through the admin interface.
 *
 */
function node_example_node_info() {
  return array(
    'example_node_type_1' => array(
      'name' => t('Example node type 1'),
      'module' => 'node_example',
      'description' => t("An example node type with a few fields."),
      'has_title' => TRUE,
      'title_label' => t('Example Node Type 1 Title'),
      'has_body' => TRUE,
      'body_label' => t('Example Node Type 1 Body'),
    )
  );
}

/**
 * Implementation of hook_access().
 *
 * Node modules may implement node_access() to determine the operations
 * users may perform on nodes. This example uses a very common access pattern.
 */
function node_example_access($op, $node, $account) {
  if ($op == 'create') {
    return user_access('create example content', $account);
  }

  if ($op == 'update') {
    if (user_access('edit any example content', $account) || (user_access('edit own example content', $account) && ($account->uid == $node->uid))) {
      return TRUE;
    }
  }

  if ($op == 'delete') {
    if (user_access('delete any example content', $account) || (user_access('delete own example content', $account) && ($account->uid == $node->uid))) {
      return TRUE;
    }
  }
}

/**
 * Implementation of hook_perm().
 *
 * Since we are limiting the ability to create new nodes to certain users,
 * we need to define what those permissions are here. We also define a permission
 * to allow users to edit the nodes they created.
 */
function node_example_perm() {
  return array(
    'create example content',
    'delete own example content',
    'delete any example content',
    'edit own example content',
    'edit any example content',
  );
}

/**
 * Implementation of hook_form().
 *
 * Now it's time to describe the form for collecting the information
 * specific to this node type. This hook requires us to return an array with
 * a sub array containing information for each element in the form.
 */
function node_example_form(&$node, $form_state) {
  // The site admin can decide if this node type has a title and body, and how
  // the fields should be labeled. We need to load these settings so we can
  // build the node form correctly.
  $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 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);
  }

  // Now we define the form elements specific to our node type.
  $form['color'] = array(
    '#type' => 'textfield',
    '#title' => t('Color'),
    '#default_value' => isset($node->color) ? $node->color : '',
  );
  $form['quantity'] = array(
    '#type' => 'textfield',
    '#title' => t('Quantity'),
    '#default_value' => isset($node->quantity) ? $node->quantity : 0,
    '#size' => 10,
    '#maxlength' => 10
  );

  return $form;
}

/**
 * Implementation of hook_validate().
 *
 * Our "quantity" field requires a number to be entered. This hook lets
 * us ensure that the user entered an appropriate value before we try
 * inserting anything into the database.
 *
 * Errors should be signaled with form_set_error().
 */
function node_example_validate($node, &$form) {
  if ($node->quantity) {
    if (!is_numeric($node->quantity)) {
      form_set_error('quantity', t('The quantity must be a number.'));
    }
  }
}

/**
 * Implementation of hook_insert().
 *
 * As a new node is being inserted into the database, we need to do our own
 * database inserts.
 */
function node_example_insert($node) {
  db_query("INSERT INTO {node_example} (vid, nid, color, quantity) VALUES (%d, %d, '%s', %d)", $node->vid, $node->nid, $node->color, $node->quantity);
}

/**
 * Implementation of hook_update().
 *
 * As an existing node is being updated in the database, we need to do our own
 * database updates.
 */
function node_example_update($node) {
  // if this is a new node or we're adding a new revision,
  if ($node->revision) {
    node_example_insert($node);
  }
  else {
    db_query("UPDATE {node_example} SET color = '%s', quantity = %d WHERE vid = %d", $node->color, $node->quantity, $node->vid);
  }
}

/**
 * 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_example_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_example} WHERE vid = %d', $node->vid);
      break;
  }
}

/**
 * Implementation of hook_delete().
 *
 * When a node is deleted, we need to remove all related records from our table.
 */
function node_example_delete($node) {
  // Notice that we're matching all revision, by using the node's nid.
  db_query('DELETE FROM {node_example} WHERE nid = %d', $node->nid);
}

/**
 * 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_example_load($node) {
  $additions = db_fetch_object(db_query('SELECT color, quantity FROM {node_example} WHERE vid = %d', $node->vid));
  return $additions;
}

/**
 * Implementation of hook_view().
 *
 * This is a typical implementation that simply runs the node text through
 * the output filters.
 */
function node_example_view($node, $teaser = FALSE, $page = FALSE) {
  $node = node_prepare($node, $teaser);
  $node->content['myfield'] = array(
    '#value' => theme('node_example_order_info', $node),
    '#weight' => 1,
  );

  return $node;
}

/**
 * Implementation of hook_theme().
 *
 * This lets us tell Drupal about our theme functions and their arguments.
 */
function node_example_theme() {
  return array(
    'node_example_order_info' => array(
      'arguments' => array('node'),
    ),
  );
}

/**
 * A custom theme function.
 *
 * By using this function to format our node-specific information, themes
 * can override this presentation if they wish. We also wrap the default
 * presentation in a CSS class that is prefixed by the module name. This
 * way, style sheets can modify the output without requiring theme code.
 */
function theme_node_example_order_info($node) {
  $output = '<div class="node_example_order_info">';
  $output .= t('The order is for %quantity %color items.', array('%quantity' => check_plain($node->quantity), '%color' => check_plain($node->color)));
  $output .= '</div>';
  return $output;
}

/**
 * @} End of "defgroup node_example".
 */
Login or register to post comments