Skip to main content

Theme Drupal Content as an Overlay

Front-end Development
Back-end Development
Drupal

What if you want to have forms display as overlays on your Drupal 7 installation? Perhaps you want to give your users a way to add nodes without leaving the current page (like adding reference nodes to the node being edited). There are a few ways to accomplish this task, but this approach will add this functionality without requiring specific template changes within the active theme. Instead, all code can reside within your custom module. This is handy if you want your functionality to remain independent of what theme is used, which seems ideal to me.

Drupal 7 includes the Overlay module; which, when enabled does a nice job of displaying the admin pages in an overlay. It would be great to tap into what drupal is using here in this module, but unfortunately the code is tailored pretty specifically, and isn't very extensible. This approach will also provide the form without the irrelevant regions of a page like the header, footer, sidebars, etc.

For the overlay functionality we usually use Colorbox, which is our library of choice for implementing light-box like functionality with jQuery. There is a module with help facilitates this integration with Drupal. But there are a number of jQuery libraries that accomplish the same thing. The installation of one of these libraries is outside the scope of this example.

So here is how accomplish this...

First we create the menu callback and it's corresponding function, which will need to also reside in your *.module file unless you specify otherwise in the menu hook. This callback will be responsible for providing what ever it is you want to display in your overlay. In this example I am providing a form.

function mymodule_menu() {
  $items = array();

  $items['mymodule/popup'] = array(
    'title' => 'Popup Overlay',
    'page callback' => '_mymodule_callback',
    'access arguments' => array('access content'),
   'type' => MENU_CALLBACK,
  );

  return $items;
}

function _mymodule_callback() {
  module_invoke('admin_menu', 'suppress');
  $form = drupal_get_form('_mymodule_form');
  $form['#popup'] = true;
  return $form;
}

So here is what we are doing with this callback. We are invoking the suppress function of the admin_menu in order to prevent this menu from appearing along the top of the overlay. You don't need to do this if you are not using this module, however because we are using module_invoke we won't receive an error if the module doesn't exist on this Drupal installation.

Next we are grabbing the form render array to pass back from this callback. This can be any render array you want.

Finally, we add an element to our render array that we will be using later to indicate that we want to only show the main content of this page.

Next we are going to implement hook_theme to define a new theme element in the registry.

function mymodule_theme() {

  $items['mymodule_popup'] = array(
    'render element' => 'page',
    'template' => 'mymodule_popup',
  );

  return $items;
}

This function defines a new theme called mymodule_popup. It indicates it will be theming the page element and will be using a template named mymodule_popup (.tpl.php). This tpl file should reside in the base directory of your custom module unless you specify a path in the theme definition.

Next let's create our tpl.php file. All we want this to do is show our main content, wrapped in minimal html. Simply copying the innermost portion of your standard page.tpl.php file will give you a good start.

Lastly we implement hook_page_alter. This is what tells Drupal to use our new stripped down theme file when displaying a page with the attribute of '#popup'. This attribute corresponds to the line of code we included in the callback function.

function mymodule_page_alter(&$page) {
  if (isset($page['content']['system_main']['#popup'])) {
    $page['#theme'] = 'mymodule_popup';
  }
}

That does it, after refreshing the theme cache, when invoking an ajax callback (using colorbox or comparable library) you should see your overlay displaying the content returned from the callback function. Hope this helps, feel free to ask questions in the comments.

Need a fresh perspective on a tough project?

Let’s talk about how RDG can help.

Contact Us