node_example.module 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377
  1. <?php
  2. /**
  3. * @file
  4. * Module file for Node Example module.
  5. *
  6. * Part of the Examples for Developers project.
  7. */
  8. /**
  9. * @defgroup node_example Example: Node
  10. * @ingroup examples
  11. * @{
  12. * Example defining a node type in code.
  13. *
  14. * This is an example outlining how a module can be used to define a new
  15. * node type. Our example node type will allow users to specify multiple
  16. * "colors", a "quantity" and an "image" for their nodes; some kind of
  17. * rudimentary inventory-tracking system, perhaps?
  18. *
  19. * The basic pattern for defining a node type is to tell Drupal about the
  20. * node's fields and view modes. Drupal will then take over and manage
  21. * the storage for this node type. This differs from Drupal 6, where we
  22. * would have to handle all the database storage ourselves in the module.
  23. *
  24. * Remember that most node types do not require any custom code, as one
  25. * simply creates them using the Drupal user interface. Creating a node like
  26. * this in code is a special case.
  27. *
  28. * At absolute minimum, in order to provide a content type for
  29. * node, you have to implement hook_node_info() and hook_form().
  30. * Node can take care of the rest, if you want it to.
  31. *
  32. * First and foremost, defining a node type happens in
  33. * hook_node_info(). Our implementation of this hook gives
  34. * Drupal an array of information about the content type
  35. * we want to create.
  36. *
  37. * Next, since we want to add fields to our content type, we
  38. * implement hook_node_type_insert(), which gives us a chance
  39. * to modify recently-created content types.
  40. *
  41. * Drupal is able to handle deletion of our content, including
  42. * dependencies based on re-use of our field instances, so we don't
  43. * have to manage any of it.
  44. *
  45. * In previous versions of Drupal, "teaser" and "page" were node view modes.
  46. * In Drupal 7 we can define custom view modes to let the node know how it
  47. * should return it's data. This module declares a custom view mode called
  48. * "example_node_list".
  49. *
  50. * Consult the @link http://drupal.org/node/707832 Field API Tutorial @endlink
  51. * and @link http://drupal.org/node/443536 Field API Handbook Page @endlink
  52. * and @link field Field API documentation @endlink.
  53. *
  54. * @see field_example.module
  55. */
  56. /**
  57. * Implements hook_menu().
  58. *
  59. * We are providing a default page to illustrate the use of our custom node view
  60. * mode that will live at http://example.com/?q=examples/node_example
  61. */
  62. function node_example_menu() {
  63. $items['examples/node_example'] = array(
  64. 'page callback' => 'node_example_page',
  65. 'access arguments' => array('access content'),
  66. 'title' => 'Node Example',
  67. );
  68. return $items;
  69. }
  70. /**
  71. * Implements hook_node_info().
  72. *
  73. * We use hook_node_info() to define our node content type.
  74. */
  75. function node_example_node_info() {
  76. // We define the node type as an associative array.
  77. return array(
  78. 'node_example' => array(
  79. 'name' => t('Example Node Type'),
  80. // 'base' tells Drupal the base string for hook functions.
  81. // This is often the module name; if base is set to 'mymodule',
  82. // Drupal would call mymodule_insert() or similar for node
  83. // hooks. In our case, the base is 'node_example'.
  84. 'base' => 'node_example',
  85. 'description' => t('This is an example node type with a few fields.'),
  86. 'title_label' => t('Example Title'),
  87. // We'll set the 'locked' attribute to TRUE, so users won't be
  88. // able to change the machine name of our content type.
  89. 'locked' => TRUE,
  90. ),
  91. );
  92. }
  93. /**
  94. * Implements hook_node_type_insert().
  95. *
  96. * Much like hook_node_insert() lets us know that a node is being
  97. * inserted into the database, hook_node_type_insert() lets us know
  98. * that a new content type has been inserted.
  99. *
  100. * Since Drupal will at some point insert our new content type,
  101. * this gives us a chance to add the fields we want.
  102. *
  103. * It is called for all inserts to the content type database, so
  104. * we have to make sure we're only modifying the type we're
  105. * concerned with.
  106. */
  107. function node_example_node_type_insert($content_type) {
  108. if ($content_type->type == 'node_example') {
  109. // First we add the body field. Node API helpfully gives us
  110. // node_add_body_field().
  111. // We'll set the body label now, although we could also set
  112. // it along with our other instance properties later.
  113. $body_instance = node_add_body_field($content_type, t('Example Description'));
  114. // Add our example_node_list view mode to the body instance
  115. // display by instructing the body to display as a summary.
  116. $body_instance['display']['example_node_list'] = array(
  117. 'label' => 'hidden',
  118. 'type' => 'text_summary_or_trimmed',
  119. );
  120. // Save our changes to the body field instance.
  121. field_update_instance($body_instance);
  122. // Create all the fields we are adding to our content type.
  123. foreach (_node_example_installed_fields() as $field) {
  124. field_create_field($field);
  125. }
  126. // Create all the instances for our fields.
  127. foreach (_node_example_installed_instances() as $instance) {
  128. $instance['entity_type'] = 'node';
  129. $instance['bundle'] = 'node_example';
  130. field_create_instance($instance);
  131. }
  132. }
  133. }
  134. /**
  135. * Implements hook_form().
  136. *
  137. * Drupal needs for us to provide a form that lets the user
  138. * add content. This is the form that the user will see if
  139. * they go to node/add/node-example.
  140. *
  141. * You can get fancy with this form, or you can just punt
  142. * and return the default form that node_content will provide.
  143. */
  144. function node_example_form($node, $form_state) {
  145. return node_content_form($node, $form_state);
  146. }
  147. /**
  148. * Callback that builds our content and returns it to the browser.
  149. *
  150. * This callback comes from hook_menu().
  151. *
  152. * @return array
  153. * A renderable array showing a list of our nodes.
  154. *
  155. * @see node_load()
  156. * @see node_view()
  157. * @see node_example_field_formatter_view()
  158. */
  159. function node_example_page() {
  160. // We'll start building a renderable array that will be our page.
  161. // For now we just declare the array.
  162. $renderable_array = array();
  163. // We query the database and find all of the nodes for the type we defined.
  164. $sql = 'SELECT nid FROM {node} n WHERE n.type = :type AND n.status = :status';
  165. $result = db_query($sql,
  166. array(
  167. ':type' => 'node_example',
  168. ':status' => 1,
  169. )
  170. );
  171. $renderable_array['explanation'] = array(
  172. '#markup' => t("Node Example nodes you've created will be displayed here. Note that the color fields will be displayed differently in this list, than if you view the node normally. Click on the node title to see the difference. This is a result of using our 'example_node_list' node view type."),
  173. );
  174. // Loop through each of our node_example nodes and instruct node_view
  175. // to use our "example_node_list" view.
  176. // http://api.drupal.org/api/function/node_load/7
  177. // http://api.drupal.org/api/function/node_view/7
  178. foreach ($result as $row) {
  179. $node = node_load($row->nid);
  180. $renderable_array['node_list'][] = node_view($node, 'example_node_list');
  181. }
  182. return $renderable_array;
  183. }
  184. /**
  185. * Implements hook_entity_info_alter().
  186. *
  187. * We need to modify the default node entity info by adding a new view mode to
  188. * be used in functions like node_view() or node_build_content().
  189. */
  190. function node_example_entity_info_alter(&$entity_info) {
  191. // Add our new view mode to the list of view modes...
  192. $entity_info['node']['view modes']['example_node_list'] = array(
  193. 'label' => t('Example Node List'),
  194. 'custom settings' => TRUE,
  195. );
  196. }
  197. /**
  198. * Implements hook_field_formatter_info().
  199. */
  200. function node_example_field_formatter_info() {
  201. return array(
  202. 'node_example_colors' => array(
  203. 'label' => t('Node Example Color Handle'),
  204. 'field types' => array('text'),
  205. ),
  206. );
  207. }
  208. /**
  209. * Implements hook_field_formatter_view().
  210. *
  211. * @todo: We need to provide a formatter for the colors that a user is allowed
  212. * to enter during node creation.
  213. */
  214. function node_example_field_formatter_view($object_type, $object, $field, $instance, $langcode, $items, $display) {
  215. $element = array();
  216. switch ($display['type']) {
  217. case 'node_example_colors':
  218. foreach ($items as $delta => $item) {
  219. $element[$delta]['#type'] = 'markup';
  220. $color = $item['safe_value'];
  221. $element[$delta]['#markup'] = theme('example_node_color', array('color' => $color));
  222. }
  223. break;
  224. }
  225. return $element;
  226. }
  227. /**
  228. * Implements hook_theme().
  229. *
  230. * This lets us tell Drupal about our theme functions and their arguments.
  231. */
  232. function node_example_theme($existing, $type, $theme, $path) {
  233. return array(
  234. 'example_node_color' => array(
  235. 'variables' => array('color' => NULL),
  236. ),
  237. );
  238. }
  239. /**
  240. * Implements hook_help().
  241. */
  242. function node_example_help($path, $arg) {
  243. switch ($path) {
  244. case 'examples/node_example':
  245. return "<p>" . t("The Node Example module provides a custom node type.
  246. You can create new Example Node nodes using the <a href='!nodeadd'>node add form</a>.",
  247. array('!nodeadd' => url('node/add/node-example'))) . "</p>";
  248. }
  249. }
  250. /**
  251. * A custom theme function.
  252. *
  253. * By using this function to format our node-specific information, themes
  254. * can override this presentation if they wish. This is a simplifed theme
  255. * function purely for illustrative purposes.
  256. */
  257. function theme_example_node_color($variables) {
  258. $output = '<span style="background-color: #ccc; padding: 1em; margin-bottom: 1em; float: left; color: ' . $variables['color'] . '">' . $variables['color'] . '</span>';
  259. return $output;
  260. }
  261. /**
  262. * Define the fields for our content type.
  263. *
  264. * This big array is factored into this function for readability.
  265. *
  266. * @return array
  267. * An associative array specifying the fields we wish to add to our
  268. * new node type.
  269. */
  270. function _node_example_installed_fields() {
  271. return array(
  272. 'node_example_color' => array(
  273. 'field_name' => 'node_example_color',
  274. 'cardinality' => 3,
  275. 'type' => 'text',
  276. 'settings' => array(
  277. 'max_length' => 60,
  278. ),
  279. ),
  280. 'node_example_quantity' => array(
  281. 'field_name' => 'node_example_quantity',
  282. 'cardinality' => 1,
  283. 'type' => 'text',
  284. ),
  285. 'node_example_image' => array(
  286. 'field_name' => 'node_example_image',
  287. 'type' => 'image',
  288. 'cardinality' => 1,
  289. ),
  290. );
  291. }
  292. /**
  293. * Define the field instances for our content type.
  294. *
  295. * The instance lets Drupal know which widget to use to allow the user to enter
  296. * data and how to react in different view modes. We are going to display a
  297. * page that uses a custom "node_example_list" view mode. We will set a
  298. * cardinality of three allowing our content type to give the user three color
  299. * fields.
  300. *
  301. * This big array is factored into this function for readability.
  302. *
  303. * @return array
  304. * An associative array specifying the instances we wish to add to our new
  305. * node type.
  306. */
  307. function _node_example_installed_instances() {
  308. return array(
  309. 'node_example_color' => array(
  310. 'field_name' => 'node_example_color',
  311. 'label' => t('The colors available for this object.'),
  312. 'widget' => array(
  313. 'type' => 'text_textfield',
  314. ),
  315. 'display' => array(
  316. 'example_node_list' => array(
  317. 'label' => 'hidden',
  318. 'type' => 'node_example_colors',
  319. ),
  320. ),
  321. ),
  322. 'node_example_quantity' => array(
  323. 'field_name' => 'node_example_quantity',
  324. 'label' => t('Quantity required'),
  325. 'type' => 'text',
  326. 'widget' => array(
  327. 'type' => 'text_textfield',
  328. ),
  329. 'display' => array(
  330. 'example_node_list' => array(
  331. 'label' => 'hidden',
  332. 'type' => 'hidden',
  333. ),
  334. ),
  335. ),
  336. 'node_example_image' => array(
  337. 'field_name' => 'node_example_image',
  338. 'label' => t('Upload an image:'),
  339. 'required' => FALSE,
  340. 'widget' => array(
  341. 'type' => 'image_image',
  342. 'weight' => 2.10,
  343. ),
  344. 'display' => array(
  345. 'example_node_list' => array(
  346. 'label' => 'hidden',
  347. 'type' => 'image_link_content__thumbnail',
  348. ),
  349. ),
  350. ),
  351. );
  352. }
  353. /**
  354. * @} End of "defgroup node_example".
  355. */