2

I need only processed content of particular theme file (mytheme.tpl.php) using the theme() function. How do I get rid off header, footer and other stuff on the page? And it will be good not to touch main theme page.tpl.php or anything else except module internals.

Probably there is something like:

return DRUPAL_CLEAN_OUTPUT(theme('my_theme',array('html' => $html))); ?

4 Answers 4

3

Just print it from your page callback rather than return it. Drupal will only invoke the theme wrappers for the html/page when you return something from your callback.

function MYMODULE_some_page_callback() {
  print theme('my_theme', array('html' => $html);
}

The other method is to set an explicit delivery callback for your menu item, to be used in place of the standard drupal_deliver_html_page() method. See the hook_menu() docs for more details.

1
  • 1
    In case of using 'print', CSS not added with drupal_add_css()
    – Alex
    Aug 21, 2012 at 13:23
2

Also used the delivery callback like this:

function HOOK_menu() {
  $items['mymodule/blah.xml'] = array(
    'title' => 'RSS Feed',
    'description' => 'RSS feed of blah blah',
    'page callback' => 'rss_feed',
    'delivery callback' => 'deliver_plain',
    'access arguments' => array('access content'),
    'file' => 'blah.inc',
  );
}

Then my callback looked like this, so it could skip calling drupal_render_page:

function deliver_plain($page_callback_result) {
  print $page_callback_result;
}
1
  • 2
    This seems to be the most simple and elegant solution. Cheers. Jul 31, 2015 at 19:04
1

If you want to remove all regions except the Content one from some of your pages page, you can use hook_page_alter() to hide them:

function MODULE_hook_page_alter($page) {
  if (some_condition()) {
    foreach (element_children($page) as $region) {
      $page[$region]['#access'] = ($region == 'content');    
    }
  }
}

The removed regions' contents will still be build, with any side effect they may have. But the content of the regions will not be rendered. So, for instance, hook_block_view() implementations for enabled blocks in the hidden regions will be called. Any CSS or JavaScript files added with drupal_add_css() or drupal_add_js() will be included in the page. But any CSS or JavaScript files added through the #attached property in their content (if returned as renderable arrays) will not be included in the page.

2
  • +1, but i think OP wanted to know how to print the HTML and do nothing else than that. This works just nicely for popup-like stuff anyway.
    – AKS
    Aug 21, 2012 at 20:36
  • I added my answer because OP commented about missing CSS added with drupal_add_css() when using print. Aug 22, 2012 at 14:14
1

I was trying to create a custom menu callback without other regions for a splash page that would be viewed via an iframe for new site visitors, but I still wanted the theming for the site. Pierre's suggestion is perfectly fine, and easy to implement, but wanted to try another approach that would avoid having to loop over every region of every page for every page request. So instead I implemented my own "delivery callback" for my menu router item (https://api.drupal.org/api/drupal/modules%21system%21system.api.php/function/hook_menu/7), which was basically a straight copy of drupal_deliver_html_page() https://api.drupal.org/api/drupal/includes%21common.inc/function/drupal_deliver_html_page/7, with the exception of a single line

 elseif (isset($page_callback_result)) {
    // Print anything besides a menu constant, assuming it's not NULL or
    // undefined.
    print drupal_render_page($page_callback_result);
  }

Became...

 elseif (isset($page_callback_result)) {
    // Print anything besides a menu constant, assuming it's not NULL or
    // undefined.
    print my_custom_render_page_function($page_callback_result);
  }

My custom function pretty much stayed the same, except I added Pierre's foreach loop just before the return statement:

  // Hide all but the content area for a splash calback.
  foreach (element_children($page) as $region) {
    $page[$region]['#access'] = ($region == 'content');
  }

  return drupal_render($page);

This way I'm not repeating the same unnecessary logic on every page to support a use case for ~1% of page requests. Whether this is worth it is up to debate, it is a lot of re-implemented core code that would now have to be maintained outside of the Drupal community.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.