Drupal Page manager: Can I provide a variant in my module?

3.1k views Asked by At

I have a module that provides a number of pages to the Page Manager module using hook_default_page_manager_pages(). This works out fine. But now I would also like to provide a variant for the system included node/%node page. But I can't find any hooks for providing variants.

My problem is, that I can not create my own page to overwrite node/%node, since this is already provided by the Page Manager module itself, so only way I can create pages that takes over the normal node view, is to provide a variant (from my understanding). But how can I do this programmatically? I can see that it's possible to export the variant, and therefore I guess that it would also be possible to provide it through a hook?

Is this possible in any way?

2

There are 2 answers

4
mtrolle On BEST ANSWER

I found what I was looking for.

To provide variants for pages build with page manager in code, in your module file call hook_ctools_plugin_api(), to let Page Manager know, that it should listen to your module:

/**
 * Implement hook_ctools_plugin_api().
 *
 * Tells ctools, page manager and panels, that we have a template ready
 */
function mtvideo_ctools_plugin_api($module, $api) {
  // @todo -- this example should explain how to put it in a different file.
  if ($module == 'panels_mini' && $api == 'panels_default') {
    return array('version' => 1);
  }
  if ($module == 'page_manager' && $api == 'pages_default') {
    return array('version' => 1);
  }
}

Now create a new file in your module root folder called MODULE_NAME.pages_default.inc. In this file you can now include the following functions:

hook_default_page_manager_pages()
/**
 * If you want to put an entire page including its variants in code.
 * With the export module from ctools, you can export your whole page to code.
 * Paste that into this function.
 * (Be aware that the export gives you $page, but you need to return an array,
 * So let the function return array('page name' => $page);
 */

and/or

hook_default_page_manager_handlers()
/**
 * This will provide a variant of an existing page, e.g. a variant of the system
 * page node/%node
 * Again, use the export function in Page Manager to export the needed code,
 * and paste that into the body of this function.
 * The export gives you $handler, but again you want to return an array, so use:
 * return array('handler name' => $handler);
 *
 * Notice, that if you export a complete page, it will include your variants.
 * So this function is only to provide variants of e.g. system pages or pages
 * added by other modules.
 */

I hope this helps another in need one day :o) Only thing I have left to discover is how my module programmatically can enable the node/%node page in Page Manager. If any one has a clue feel free to share it with me :)

1
Clive On

Apologies if I've misunderstood but I think there are two ways you could attack this:

Firstly you could implement hook_menu_alter() to override the page callback for the path:

function mymodule_menu_alter(&$items) {
  $items['node/%node']['page callback'] = 'mymodule_node_page_callback';
}

function mymodule_node_page_callback($node) {
  // Build up the content and return
}

In this case you'd need to make sure that in the system table your module has a higher value in the weight column than the Page Manager module (so your hook will be called later on and will have the final say as it were).

Secondly you could implement hook_node_view() and just override the content altogether:

function hook_node_view($node, $view_mode, $langcode) {
  if ($view_mode == 'full') {
    $node->content = array();
    $node->content['title'] = array('#markup' => '<h1>' . $node->title . '</h1>';

    // Build up the rest of the content
  }
}

In this case you'll need to build up the content as a render array (see the drupal_render() function).

Hope that helps