123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388 |
- <?php
- /**
- * @file
- * Shows how to use Drupal's contextual links functionality.
- *
- * @see http://drupal.org/node/1089922
- */
- /**
- * @defgroup contextual_links_example Example: Contextual Links
- * @ingroup examples
- * @{
- * Example of implementing contextual links.
- */
- /**
- * Implements hook_menu().
- *
- * Drupal's menu system allows you to indicate that particular menu items
- * should be displayed as contextual links. If you hover over a block or node
- * while logged in as an administrator (and with the Contextual Links module
- * enabled) you'll see a small gear icon appear. Click on this icon, and the
- * list of items that appears in the exposed menu are what Drupal calls
- * "contextual links".
- *
- * Contextual links allow site administrators to quickly perform actions
- * related to elements on a page, without having to hunt through the
- * administrative interface. As such, you should usually attach them to objects
- * that appear on the main part of a Drupal site and limit them to a few common
- * tasks that are frequently performed (for example, "edit" or "configure").
- * Do not rely on contextual links being present for your module to work
- * correctly, since they are a convenience feature only. Within Drupal core,
- * the Contextual Links module must be enabled (and the user viewing the page
- * must have the "access contextual links" permission) in order for the
- * contextual links corresponding to actions that the user can perform to
- * actually be injected into the page's HTML.
- *
- * Three examples of contextual links are provided here. Although none are
- * difficult to implement, they are presented in order of increasing
- * complexity:
- * - Attaching contextual links to a node.
- * - Attaching contextual links to a block.
- * - Attaching contextual links to an arbitrary piece of content defined by
- * your module.
- *
- * @see contextual_links_example_block_info()
- * @see contextual_links_example_block_view()
- * @see contextual_links_overview_page()
- */
- function contextual_links_example_menu() {
- // First example (attaching contextual links to a node):
- //
- // Many modules add tabs to nodes underneath the node/<nid> path. If the path
- // you are adding corresponds to a commonly performed action on the node, you
- // can choose to expose it as a contextual link. Since the Node module
- // already has code to display all contextual links underneath the node/<nid>
- // path (such as "Edit" and "Delete") when a node is being rendered outside
- // of its own page (for example, when a teaser of the node is being displayed
- // on the front page of the site), you only need to inform Drupal's menu
- // system that your path is a contextual link also, and it will automatically
- // appear with the others. In the example below, we add a contextual link
- // named "Example action" to the list.
- $items['node/%node/example-action'] = array(
- 'title' => 'Example action',
- 'page callback' => 'drupal_get_form',
- 'page arguments' => array('contextual_links_example_node_action_form', 1),
- 'access callback' => TRUE,
- // To be displayed as a contextual link, a menu item should be defined as
- // one of the node's local tasks.
- 'type' => MENU_LOCAL_TASK,
- // To make the local task display as a contextual link, specify the
- // optional 'context' argument. The most common method is to set both
- // MENU_CONTEXT_PAGE and MENU_CONTEXT_INLINE (shown below), which causes
- // the link to display as both a tab on the node page and as an entry in
- // the contextual links dropdown. This is recommended for most cases
- // because not all users who have permission to visit the "Example action"
- // page will necessarily have access to contextual links, and they still
- // need a way to get to the page via the user interface.
- 'context' => MENU_CONTEXT_PAGE | MENU_CONTEXT_INLINE,
- // If we give the item a large weight, we can make it display as the last
- // tab on the page, as well as the last item inside the contextual links
- // dropdown.
- 'weight' => 80,
- );
- // Second example (attaching contextual links to a block):
- //
- // If your module provides content that is displayed in a block, you can
- // attach contextual links to the block that allow actions to be performed on
- // it. This is useful for administrative pages that affect the content
- // wherever it is displayed or used on the site. For configuration options
- // that only affect the appearance of the content in the block itself, it is
- // better to implement hook_block_configure() rather than creating a separate
- // administrative page (this allows your options to appear when an
- // administrator clicks the existing "Configure block" contextual link
- // already provided by the Block module).
- //
- // In the code below, we assume that your module has a type of object
- // ("contextual links example object") that will be displayed in a block. The
- // code below defines menu items for this object using a standard pattern,
- // with "View" and "Edit object" as the object's local tasks, and makes the
- // "Edit object" item display as a contextual link in addition to a tab. Once
- // the contextual links are defined here, additional steps are required to
- // actually display the content in a block and attach the contextual links to
- // the block itself. This occurs in contextual_links_example_block_info() and
- // contextual_links_example_block_view().
- $items['examples/contextual-links/%contextual_links_example_object'] = array(
- 'title' => 'Contextual links example object',
- 'page callback' => 'contextual_links_example_object_page',
- 'page arguments' => array(2),
- 'access callback' => TRUE,
- );
- $items['examples/contextual-links/%contextual_links_example_object/view'] = array(
- 'title' => 'View',
- 'type' => MENU_DEFAULT_LOCAL_TASK,
- 'weight' => -10,
- );
- $items['examples/contextual-links/%contextual_links_example_object/edit'] = array(
- 'title' => 'Edit object',
- 'page callback' => 'drupal_get_form',
- 'page arguments' => array('contextual_links_example_object_edit_form', 2),
- 'access callback' => TRUE,
- 'type' => MENU_LOCAL_TASK,
- // As in our first example, this is the line of code that makes "Edit
- // "object" display as a contextual link in addition to as a tab.
- 'context' => MENU_CONTEXT_PAGE | MENU_CONTEXT_INLINE,
- );
- // Third example (attaching contextual links directly to your module's
- // content):
- //
- // Sometimes your module may want to display its content in an arbitrary
- // location and attach contextual links there. For example, you might
- // display your content in a listing on its own page and then attach the
- // contextual links directly to each piece of content in the listing. Here,
- // we will reuse the menu items and contextual links that were defined for
- // our example object above, and display them in a listing in
- // contextual_links_overview_page().
- $items['examples/contextual-links'] = array(
- 'title' => 'Contextual Links Example',
- 'page callback' => 'contextual_links_overview_page',
- 'access callback' => TRUE,
- );
- return $items;
- }
- /**
- * Menu loader callback for the object defined by this module.
- *
- * @param int $id
- * The ID of the object to load.
- *
- * @return object|FALSE
- * A fully loaded object, or FALSE if the object does not exist.
- */
- function contextual_links_example_object_load($id) {
- // In a real use case, this function might load an object from the database.
- // For the sake of this example, we just define a stub object with a basic
- // title and content for any numeric ID that is passed in.
- if (is_numeric($id)) {
- $object = new stdClass();
- $object->id = $id;
- $object->title = t('Title for example object @id', array('@id' => $id));
- $object->content = t('This is the content of example object @id.', array('@id' => $id));
- return $object;
- }
- else {
- return FALSE;
- }
- }
- /**
- * Implements hook_block_info().
- */
- function contextual_links_example_block_info() {
- // Define the block that will display our module's content.
- $blocks['example']['info'] = t('Contextual links example block');
- return $blocks;
- }
- /**
- * Implements hook_block_view().
- */
- function contextual_links_example_block_view($delta = '') {
- if ($delta == 'example') {
- // Display our module's content inside a block. In a real use case, we
- // might define a new block for each object that exists. For the sake of
- // this example, though, we only define one block and hardcode it to always
- // display object #1.
- $id = 1;
- $object = contextual_links_example_object_load($id);
- $block['subject'] = t('Contextual links example block for object @id', array('@id' => $id));
- $block['content'] = array(
- // In order to attach contextual links, the block's content must be a
- // renderable array. (Normally this would involve themed output using
- // #theme, but for simplicity we just use HTML markup directly here.)
- '#type' => 'markup',
- '#markup' => filter_xss($object->content),
- // Contextual links are attached to the block array using the special
- // #contextual_links property. The #contextual_links property contains an
- // array, keyed by the name of each module that is attaching contextual
- // links to it.
- '#contextual_links' => array(
- 'contextual_links_example' => array(
- // Each element is itself an array, containing two elements which are
- // combined together to form the base path whose contextual links
- // should be attached. The two elements are split such that the first
- // is the static part of the path and the second is the dynamic part.
- // (This split is for performance reasons.) For example, the code
- // below tells Drupal to load the menu item corresponding to the path
- // "examples/contextual-links/$id" and attach all this item's
- // contextual links (which were defined in hook_menu()) to the object
- // when it is rendered. If the contextual links you are attaching
- // don't have any dynamic elements in their path, you can pass an
- // empty array as the second element.
- 'examples/contextual-links',
- array($id),
- ),
- ),
- );
- // Since we are attaching our contextual links to a block, and the Block
- // module takes care of rendering the block in such a way that contextual
- // links are supported, we do not need to do anything else here. When the
- // appropriate conditions are met, the contextual links we have defined
- // will automatically appear attached to the block, next to the "Configure
- // block" link that the Block module itself provides.
- return $block;
- }
- }
- /**
- * Menu callback; displays a listing of objects defined by this module.
- *
- * @see contextual_links_example_theme()
- * @see contextual-links-example-object.tpl.php
- * @see contextual_links_example_block_view()
- */
- function contextual_links_overview_page() {
- $build = array();
- // For simplicity, we will hardcode this example page to list five of our
- // module's objects.
- for ($id = 1; $id <= 5; $id++) {
- $object = contextual_links_example_object_load($id);
- $build[$id] = array(
- // To support attaching contextual links to an object that we are
- // displaying on our own, the object must be themed in a particular way.
- // See contextual_links_example_theme() and
- // contextual-links-example-object.tpl.php for more discussion.
- '#theme' => 'contextual_links_example_object',
- '#object' => $object,
- // Contextual links are attached to the block using the special
- // #contextual_links property. See contextual_links_example_block_view()
- // for discussion of the syntax used here.
- '#contextual_links' => array(
- 'contextual_links_example' => array(
- 'examples/contextual-links',
- array($id),
- ),
- ),
- );
- }
- return $build;
- }
- /**
- * Implements hook_theme().
- *
- * @see template_preprocess_contextual_links_example_object()
- */
- function contextual_links_example_theme() {
- // The core Contextual Links module imposes two restrictions on how an object
- // must be themed in order for it to display the object's contextual links in
- // the user interface:
- // - The object must use a template file rather than a theme function. See
- // contextual-links-example-object.tpl.php for more information on how the
- // template file should be structured.
- // - The first variable passed to the template must be a renderable array. In
- // this case, we accomplish that via the most common method, by passing a
- // single renderable element.
- return array(
- 'contextual_links_example_object' => array(
- 'template' => 'contextual-links-example-object',
- 'render element' => 'element',
- ),
- );
- }
- /**
- * Process variables for contextual-links-example-object.tpl.php.
- *
- * @see contextual_links_overview_page()
- */
- function template_preprocess_contextual_links_example_object(&$variables) {
- // Here we take the object that is being themed and define some useful
- // variables that we will print in the template file.
- $variables['title'] = filter_xss($variables['element']['#object']->title);
- $variables['content'] = filter_xss($variables['element']['#object']->content);
- }
- /**
- * Menu callback; displays an object defined by this module on its own page.
- *
- * @see contextual_links_overview_page()
- */
- function contextual_links_example_object_page($object) {
- // Here we render the object but without the #contextual_links property,
- // since we don't want contextual links to appear when the object is already
- // being displayed on its own page.
- $build = array(
- '#theme' => 'contextual_links_example_object',
- '#object' => $object,
- );
- return $build;
- }
- /**
- * Form callback; display the form for editing our module's content.
- *
- * @ingroup forms
- * @see contextual_links_example_object_edit_form_submit()
- */
- function contextual_links_example_object_edit_form($form, &$form_state, $object) {
- $form['text'] = array(
- '#markup' => t('This is the page that would allow you to edit object @id.', array('@id' => $object->id)),
- '#prefix' => '<p>',
- '#suffix' => '</p>',
- );
- $form['object_id'] = array(
- '#type' => 'value',
- '#value' => $object->id,
- );
- $form['actions'] = array('#type' => 'actions');
- $form['actions']['submit'] = array(
- '#type' => 'submit',
- '#value' => t('Submit'),
- );
- return $form;
- }
- /**
- * Submit handler for contextual_links_example_object_edit_form().
- */
- function contextual_links_example_object_edit_form_submit($form, &$form_state) {
- drupal_set_message(t('Object @id was edited.', array('@id' => $form_state['values']['object_id'])));
- }
- /**
- * Form callback; display the form for performing an example action on a node.
- *
- * @ingroup forms
- * @see contextual_links_example_node_action_form_submit()
- */
- function contextual_links_example_node_action_form($form, &$form_state, $node) {
- $form['text'] = array(
- '#markup' => t('This is the page that would allow you to perform an example action on node @nid.', array('@nid' => $node->nid)),
- '#prefix' => '<p>',
- '#suffix' => '</p>',
- );
- $form['nid'] = array(
- '#type' => 'value',
- '#value' => $node->nid,
- );
- $form['actions'] = array('#type' => 'actions');
- $form['actions']['submit'] = array(
- '#type' => 'submit',
- '#value' => t('Submit'),
- );
- return $form;
- }
- /**
- * Submit handler for contextual_links_example_node_action_form().
- */
- function contextual_links_example_node_action_form_submit($form, &$form_state) {
- drupal_set_message(t('The example action was performed on node @nid.', array('@nid' => $form_state['values']['nid'])));
- }
- /**
- * @} End of "defgroup contextual_links_example".
- */
|