contextual_links_example.module

  1. examples
    1. 7 contextual_links_example/contextual_links_example.module
    2. 8 contextual_links_example/contextual_links_example.module

Shows how to use Drupal's contextual links functionality.

See also

http://drupal.org/node/1089922

Functions & methods

NameDescription
contextual_links_example_block_infoImplements hook_block_info().
contextual_links_example_block_viewImplements hook_block_view().
contextual_links_example_menuImplements hook_menu().
contextual_links_example_node_action_formForm callback; display the form for performing an example action on a node.
contextual_links_example_node_action_form_submitSubmit handler for contextual_links_example_node_action_form().
contextual_links_example_object_edit_formForm callback; display the form for editing our module's content.
contextual_links_example_object_edit_form_submitSubmit handler for contextual_links_example_object_edit_form().
contextual_links_example_object_loadMenu loader callback for the object defined by this module.
contextual_links_example_object_pageMenu callback; displays an object defined by this module on its own page.
contextual_links_example_themeImplements hook_theme().
contextual_links_overview_pageMenu callback; displays a listing of objects defined by this module.
template_preprocess_contextual_links_example_objectProcess variables for contextual-links-example-object.tpl.php.

File

contextual_links_example/contextual_links_example.module
View source
  1. <?php
  2. /**
  3. * @file
  4. * Shows how to use Drupal's contextual links functionality.
  5. *
  6. * @see http://drupal.org/node/1089922
  7. */
  8. /**
  9. * Implements hook_menu().
  10. *
  11. * Drupal's menu system allows you to indicate that particular menu items
  12. * should be displayed as contextual links. If you hover over a block or node
  13. * while logged in as an administrator (and with the Contextual Links module
  14. * enabled) you'll see a small gear icon appear. Click on this icon, and the
  15. * list of items that appears in the exposed menu are what Drupal calls
  16. * "contextual links".
  17. *
  18. * Contextual links allow site administrators to quickly perform actions
  19. * related to elements on a page, without having to hunt through the
  20. * administrative interface. As such, you should usually attach them to objects
  21. * that appear on the main part of a Drupal site and limit them to a few common
  22. * tasks that are frequently performed (for example, "edit" or "configure").
  23. * Do not rely on contextual links being present for your module to work
  24. * correctly, since they are a convenience feature only. Within Drupal core,
  25. * the Contextual Links module must be enabled (and the user viewing the page
  26. * must have the "access contextual links" permission) in order for the
  27. * contextual links corresponding to actions that the user can perform to
  28. * actually be injected into the page's HTML.
  29. *
  30. * Three examples of contextual links are provided here. Although none are
  31. * difficult to implement, they are presented in order of increasing
  32. * complexity:
  33. * - Attaching contextual links to a node.
  34. * - Attaching contextual links to a block.
  35. * - Attaching contextual links to an arbitrary piece of content defined by
  36. * your module.
  37. *
  38. * @see contextual_links_example_block_info()
  39. * @see contextual_links_example_block_view()
  40. * @see contextual_links_overview_page()
  41. */
  42. function contextual_links_example_menu() {
  43. // First example (attaching contextual links to a node):
  44. //
  45. // Many modules add tabs to nodes underneath the node/<nid> path. If the path
  46. // you are adding corresponds to a commonly performed action on the node, you
  47. // can choose to expose it as a contextual link. Since the Node module
  48. // already has code to display all contextual links underneath the node/<nid>
  49. // path (such as "Edit" and "Delete") when a node is being rendered outside
  50. // of its own page (for example, when a teaser of the node is being displayed
  51. // on the front page of the site), you only need to inform Drupal's menu
  52. // system that your path is a contextual link also, and it will automatically
  53. // appear with the others. In the example below, we add a contextual link
  54. // named "Example action" to the list.
  55. $items['node/%node/example-action'] = array(
  56. 'title' => 'Example action',
  57. 'page callback' => 'drupal_get_form',
  58. 'page arguments' => array('contextual_links_example_node_action_form', 1),
  59. 'access callback' => TRUE,
  60. // To be displayed as a contextual link, a menu item should be defined as
  61. // one of the node's local tasks.
  62. 'type' => MENU_LOCAL_TASK,
  63. // To make the local task display as a contextual link, specify the
  64. // optional 'context' argument. The most common method is to set both
  65. // MENU_CONTEXT_PAGE and MENU_CONTEXT_INLINE (shown below), which causes
  66. // the link to display as both a tab on the node page and as an entry in
  67. // the contextual links dropdown. This is recommended for most cases
  68. // because not all users who have permission to visit the "Example action"
  69. // page will necessarily have access to contextual links, and they still
  70. // need a way to get to the page via the user interface.
  71. 'context' => MENU_CONTEXT_PAGE | MENU_CONTEXT_INLINE,
  72. // If we give the item a large weight, we can make it display as the last
  73. // tab on the page, as well as the last item inside the contextual links
  74. // dropdown.
  75. 'weight' => 80,
  76. );
  77. // Second example (attaching contextual links to a block):
  78. //
  79. // If your module provides content that is displayed in a block, you can
  80. // attach contextual links to the block that allow actions to be performed on
  81. // it. This is useful for administrative pages that affect the content
  82. // wherever it is displayed or used on the site. For configuration options
  83. // that only affect the appearance of the content in the block itself, it is
  84. // better to implement hook_block_configure() rather than creating a separate
  85. // administrative page (this allows your options to appear when an
  86. // administrator clicks the existing "Configure block" contextual link
  87. // already provided by the Block module).
  88. //
  89. // In the code below, we assume that your module has a type of object
  90. // ("contextual links example object") that will be displayed in a block. The
  91. // code below defines menu items for this object using a standard pattern,
  92. // with "View" and "Edit object" as the object's local tasks, and makes the
  93. // "Edit object" item display as a contextual link in addition to a tab. Once
  94. // the contextual links are defined here, additional steps are required to
  95. // actually display the content in a block and attach the contextual links to
  96. // the block itself. This occurs in contextual_links_example_block_info() and
  97. // contextual_links_example_block_view().
  98. $items['examples/contextual-links/%contextual_links_example_object'] = array(
  99. 'title' => 'Contextual links example object',
  100. 'page callback' => 'contextual_links_example_object_page',
  101. 'page arguments' => array(2),
  102. 'access callback' => TRUE,
  103. );
  104. $items['examples/contextual-links/%contextual_links_example_object/view'] = array(
  105. 'title' => 'View',
  106. 'type' => MENU_DEFAULT_LOCAL_TASK,
  107. 'weight' => -10,
  108. );
  109. $items['examples/contextual-links/%contextual_links_example_object/edit'] = array(
  110. 'title' => 'Edit object',
  111. 'page callback' => 'drupal_get_form',
  112. 'page arguments' => array('contextual_links_example_object_edit_form', 2),
  113. 'access callback' => TRUE,
  114. 'type' => MENU_LOCAL_TASK,
  115. // As in our first example, this is the line of code that makes "Edit
  116. // "object" display as a contextual link in addition to as a tab.
  117. 'context' => MENU_CONTEXT_PAGE | MENU_CONTEXT_INLINE,
  118. );
  119. // Third example (attaching contextual links directly to your module's
  120. // content):
  121. //
  122. // Sometimes your module may want to display its content in an arbitrary
  123. // location and attach contextual links there. For example, you might
  124. // display your content in a listing on its own page and then attach the
  125. // contextual links directly to each piece of content in the listing. Here,
  126. // we will reuse the menu items and contextual links that were defined for
  127. // our example object above, and display them in a listing in
  128. // contextual_links_overview_page().
  129. $items['examples/contextual-links'] = array(
  130. 'title' => 'Contextual Links Example',
  131. 'page callback' => 'contextual_links_overview_page',
  132. 'access callback' => TRUE,
  133. );
  134. return $items;
  135. }
  136. /**
  137. * Menu loader callback for the object defined by this module.
  138. *
  139. * @param $id
  140. * The ID of the object to load.
  141. *
  142. * @return
  143. * A fully loaded object, or FALSE if the object does not exist.
  144. */
  145. function contextual_links_example_object_load($id) {
  146. // In a real use case, this function might load an object from the database.
  147. // For the sake of this example, we just define a stub object with a basic
  148. // title and content for any numeric ID that is passed in.
  149. if (is_numeric($id)) {
  150. $object = new stdClass();
  151. $object->id = $id;
  152. $object->title = t('Title for example object @id', array('@id' => $id));
  153. $object->content = t('This is the content of example object @id.', array('@id' => $id));
  154. return $object;
  155. }
  156. else {
  157. return FALSE;
  158. }
  159. }
  160. /**
  161. * Implements hook_block_info().
  162. */
  163. function contextual_links_example_block_info() {
  164. // Define the block that will display our module's content.
  165. $blocks['example']['info'] = t('Contextual links example block');
  166. return $blocks;
  167. }
  168. /**
  169. * Implements hook_block_view().
  170. */
  171. function contextual_links_example_block_view($delta = '') {
  172. if ($delta == 'example') {
  173. // Display our module's content inside a block. In a real use case, we
  174. // might define a new block for each object that exists. For the sake of
  175. // this example, though, we only define one block and hardcode it to always
  176. // display object #1.
  177. $id = 1;
  178. $object = contextual_links_example_object_load($id);
  179. $block['subject'] = t('Contextual links example block for object @id', array('@id' => $id));
  180. $block['content'] = array(
  181. // In order to attach contextual links, the block's content must be a
  182. // renderable array. (Normally this would involve themed output using
  183. // #theme, but for simplicity we just use HTML markup directly here.)
  184. '#type' => 'markup',
  185. '#markup' => filter_xss($object->content),
  186. // Contextual links are attached to the block array using the special
  187. // #contextual_links property. The #contextual_links property contains an
  188. // array, keyed by the name of each module that is attaching contextual
  189. // links to it.
  190. '#contextual_links' => array(
  191. 'contextual_links_example' => array(
  192. // Each element is itself an array, containing two elements which are
  193. // combined together to form the base path whose contextual links
  194. // should be attached. The two elements are split such that the first
  195. // is the static part of the path and the second is the dynamic part.
  196. // (This split is for performance reasons.) For example, the code
  197. // below tells Drupal to load the menu item corresponding to the path
  198. // "examples/contextual-links/$id" and attach all this item's
  199. // contextual links (which were defined in hook_menu()) to the object
  200. // when it is rendered. If the contextual links you are attaching
  201. // don't have any dynamic elements in their path, you can pass an
  202. // empty array as the second element.
  203. 'examples/contextual-links',
  204. array($id),
  205. ),
  206. ),
  207. );
  208. // Since we are attaching our contextual links to a block, and the Block
  209. // module takes care of rendering the block in such a way that contextual
  210. // links are supported, we do not need to do anything else here. When the
  211. // appropriate conditions are met, the contextual links we have defined
  212. // will automatically appear attached to the block, next to the "Configure
  213. // block" link that the Block module itself provides.
  214. return $block;
  215. }
  216. }
  217. /**
  218. * Menu callback; displays a listing of objects defined by this module.
  219. *
  220. * @see contextual_links_example_theme()
  221. * @see contextual-links-example-object.tpl.php
  222. * @see contextual_links_example_block_view()
  223. */
  224. function contextual_links_overview_page() {
  225. $build = array();
  226. // For simplicity, we will hardcode this example page to list five of our
  227. // module's objects.
  228. for ($id = 1; $id <= 5; $id++) {
  229. $object = contextual_links_example_object_load($id);
  230. $build[$id] = array(
  231. // To support attaching contextual links to an object that we are
  232. // displaying on our own, the object must be themed in a particular way.
  233. // See contextual_links_example_theme() and
  234. // contextual-links-example-object.tpl.php for more discussion.
  235. '#theme' => 'contextual_links_example_object',
  236. '#object' => $object,
  237. // Contextual links are attached to the block using the special
  238. // #contextual_links property. See contextual_links_example_block_view()
  239. // for discussion of the syntax used here.
  240. '#contextual_links' => array(
  241. 'contextual_links_example' => array(
  242. 'examples/contextual-links',
  243. array($id),
  244. ),
  245. ),
  246. );
  247. }
  248. return $build;
  249. }
  250. /**
  251. * Implements hook_theme().
  252. *
  253. * @see template_preprocess_contextual_links_example_object()
  254. */
  255. function contextual_links_example_theme() {
  256. // The core Contextual Links module imposes two restrictions on how an object
  257. // must be themed in order for it to display the object's contextual links in
  258. // the user interface:
  259. // - The object must use a template file rather than a theme function. See
  260. // contextual-links-example-object.tpl.php for more information on how the
  261. // template file should be structured.
  262. // - The first variable passed to the template must be a renderable array. In
  263. // this case, we accomplish that via the most common method, by passing a
  264. // single renderable element.
  265. return array(
  266. 'contextual_links_example_object' => array(
  267. 'template' => 'contextual-links-example-object',
  268. 'render element' => 'element',
  269. ),
  270. );
  271. }
  272. /**
  273. * Process variables for contextual-links-example-object.tpl.php.
  274. *
  275. * @see contextual_links_overview_page()
  276. */
  277. function template_preprocess_contextual_links_example_object(&$variables) {
  278. // Here we take the object that is being themed and define some useful
  279. // variables that we will print in the template file.
  280. $variables['title'] = filter_xss($variables['element']['#object']->title);
  281. $variables['content'] = filter_xss($variables['element']['#object']->content);
  282. }
  283. /**
  284. * Menu callback; displays an object defined by this module on its own page.
  285. *
  286. * @see contextual_links_overview_page()
  287. */
  288. function contextual_links_example_object_page($object) {
  289. // Here we render the object but without the #contextual_links property,
  290. // since we don't want contextual links to appear when the object is already
  291. // being displayed on its own page.
  292. $build = array(
  293. '#theme' => 'contextual_links_example_object',
  294. '#object' => $object,
  295. );
  296. return $build;
  297. }
  298. /**
  299. * Form callback; display the form for editing our module's content.
  300. *
  301. * @ingroup forms
  302. * @see contextual_links_example_object_edit_form_submit()
  303. */
  304. function contextual_links_example_object_edit_form($form, &$form_state, $object) {
  305. $form['text'] = array(
  306. '#markup' => t('This is the page that would allow you to edit object @id.', array('@id' => $object->id)),
  307. '#prefix' => '<p>',
  308. '#suffix' => '</p>',
  309. );
  310. $form['object_id'] = array(
  311. '#type' => 'value',
  312. '#value' => $object->id,
  313. );
  314. $form['actions'] = array('#type' => 'actions');
  315. $form['actions']['submit'] = array(
  316. '#type' => 'submit',
  317. '#value' => t('Submit'),
  318. );
  319. return $form;
  320. }
  321. /**
  322. * Submit handler for contextual_links_example_object_edit_form().
  323. */
  324. function contextual_links_example_object_edit_form_submit($form, &$form_state) {
  325. drupal_set_message(t('Object @id was edited.', array('@id' => $form_state['values']['object_id'])));
  326. }
  327. /**
  328. * Form callback; display the form for performing an example action on a node.
  329. *
  330. * @ingroup forms
  331. * @see contextual_links_example_node_action_form_submit()
  332. */
  333. function contextual_links_example_node_action_form($form, &$form_state, $node) {
  334. $form['text'] = array(
  335. '#markup' => t('This is the page that would allow you to perform an example action on node @nid.', array('@nid' => $node->nid)),
  336. '#prefix' => '<p>',
  337. '#suffix' => '</p>',
  338. );
  339. $form['nid'] = array(
  340. '#type' => 'value',
  341. '#value' => $node->nid,
  342. );
  343. $form['actions'] = array('#type' => 'actions');
  344. $form['actions']['submit'] = array(
  345. '#type' => 'submit',
  346. '#value' => t('Submit'),
  347. );
  348. return $form;
  349. }
  350. /**
  351. * Submit handler for contextual_links_example_node_action_form().
  352. */
  353. function contextual_links_example_node_action_form_submit($form, &$form_state) {
  354. drupal_set_message(t('The example action was performed on node @nid.', array('@nid' => $form_state['values']['nid'])));
  355. }
Login or register to post comments