In some cases, you may desire to use panels as the primary layout tool for your website.

Update: This tutorial is redundant especially for new projects. Panels 3 replaces Panels 2, and the module Panels Everywhere provides the same mechanism as this tutorial.

Why all panels?
A typical situation is where you are leaning on panels heavily to override nodes, suppressing blocks/regions on panels pages, and perhaps have a panels_page as a front page. You're at the stage where themer has developed page.tpl.php and css that matches the design specs, and the site looks hot.

Now, go to a page that is not a panel, like node/add, and you realize that the work has just begun for pages with the traditional sidebar_left, sidebar_right mentality - you have all the extra printing in your page.tpl.php, or you need to have a separate page.tpl.php for panels and non-panels. Wouldn't it be easier to just have everything as a panel? You'd be practically finished.

Why not % override?
The obvious option is to create a panels_page with the path '%' to be the default path override. However, the result is a panels page missing the original content. This is because when Panels overrides the menu path, it obliterates any previous callback information with it's own. In the case of node pages, this is ok, Panels figures out the context and calmly renders the node data. But this requires specific code for each context.

A great thing about Drupal 6, is that it will be possible for Panels to use the new hook_menu_alter() to store the callback information about the page it is overriding. So on node/add (for example), panels will know to call node_add() for the $content. This is not possible in Drupal 5. Update: Panels 2 can do node/add, but I'll use this example for simplicity - see here.

Steps to override any page with a panel
If you are happy to configure things on a site by site basis, the steps to achieve this are pretty straight-forward:

  1. Go into block configuration admin/build/block and create a new block. Call it CONTENT, and in the body type %CONTENT%. Make the block PHP format to avoid additional markup when it is displayed.
  2. Go into your Panels admin, and add a new Panels Page. Call it DEFAULT, add whatever content you desire, but in one of the areas, add the block you created in the previous step.
  3. Now open your template.php and put this code in _phptemplate_variables(), where $op = 'page'.
    <?php
      $current_panel = panels_page_get_current();
      if (!isset($current_panel->pid)) {
        // Load our default panel, call it by name.
        $panel = panels_page_view_page('DEFAULT', false);
        // Insert the actual content of the page using string replace.
        $panel = str_replace('%CONTENT%', $vars['content'], $panel);
        // Replace the page content with our altered panel.
        $vars['content'] = $panel;
      }
    ?>
    

Extra tweaks
It may be worth considering pushing extra $vars like $messages and $help into the panel as well - more information may follow.

Comments

iaminawe’s picture

Hi,

Thanks for this. it works as advertised but has an unfortunate side effect of making all other existing panels content areas unusable.

When you want to edit a panels content, the display shows only a thin line showing the collapsed areas but not allowing them to be opened or edited.

Have you experienced this?

I am using the Drupal 5.7 and the latest dev of cck, panels, advanced profile...

Thanks
Gregg

surge919’s picture

In step 2, I created a new panel with "Panel name:" DEFAULT

What should the "Path:" be?

Also, in Step 3, I'm not clear on where to put your code?

I open up template.php for my current theme, but I don't find
_phptemplate_variables(), where $op = 'page'.

Are you saying to your code (in the blue box) should be after the _phptemplate_variables(), where $op = 'page'. ?

thanks.

rodrigoclp’s picture

How can I use in Drupal 6 with Panels 2????

langworthy’s picture

I'm overriding my search results page in Drupal 6 with a flexible panel layout.

  if (!isset($current_panel->pid) && (arg(0) != 'admin')){
    
    // if path is search/apachesolr_search
    if (arg(0) == 'search' && arg(1) == 'apachesolr_search') {
      
      // the name of the search results panel
      $dpanel = 'search_results';
    }
    if ($dpanel) {
      // Load the search results panel
      $panel = panels_page_render_handler($dpanel);

      // Insert the actual content of the page using string replace.
      $panel = str_replace('%CONTENT%', $vars['content'], $panel);

      // Replace the page content with the altered panel.
      $vars['content'] = $panel;

      // Replace the page styles with any additional panels styles
      $vars['styles'] = drupal_get_css();
    }
  }

The remaining problem is that there is still missing css in $vars['head']specifying my panel widths. My current fix is pretty ugly. If anyone knows a Drupalish solution, please let me know.

langworthy’s picture

$vars['head'] = drupal_get_html_head();

mbria’s picture

Function panels_page_render (actually panels_page_*) does not exist on panels 6.X.3.2... thats the stable version.

Any clue about how to deal with this right now?