Panels Everywhere - taking the leap, getting it going

You've heard about the advantages of Panels Everywhere. Now its time to actually get it going. A drush makefile, a few configuration steps, and we should have a starter site up and going and never have to look back on ugly, deficient and crippled admin/build/block.

In a recent Buenos Aires Drupal Dojo online virtual lab, we did just that, so I shall lay out a series of simple steps here on the basis of what we learned together that night.

Let's summarize the advantages of Panels Everywhere, take the steps to get it going, and think about next steps.

Here's our menu (as usual skip to the part you are most interested in):

Summary of the advantages of Panels Everywhere

You may have learned of the advantages of Panels Everywhere by watching Earl Miles and Sam Boyer's presentations at SFDrupalCon:

More recently you might have listened to the Lullabot Podcast #88 "Panels vs Context, The Cage Match", with Earl Miles (CTools, Views, Nodequeue, Panels, Panels Everywhere...) and Young Hahn (Context, Features, Spaces...) which contrasted the two approaches (after reading David Burns article on the same site, which explains a lot of the semantics involved).
In a nutshell, the advantages, with just a couple of nuances from my own background, are as follows:
• Mainstream designers think in terms of whole pages and a particular layout in the context of required functionality expressed in a wireframe, but are forced into the "Drupal Page" paradigm with its regions, blocks and content in the middle. Now these arbitrary limitations can be removed and you can go back to thinking in terms of the page, the whole page and nothing but the page. "non-crazy way of doing things" they call it.
• Mainstream web application engineers think in terms of routing: given a list of URLs invoked in a set of design wireframes, these are mapped to a list of controllers, one per page, and one per pane, which marshal the data and then hand it over to a presentation layer. Now you can.
• Now you can abandon the crippled Drupal blocks system and interface, which renders all enabled blocks on all pages and then decides which ones should be visible, and visible only once, and which gives the individual blocks the responsibility of knowing which context they live in (is this a node (what type?) page (display or edit?) or a view?). So, as Sam Boyer expresses it in his talk, instead of having a bunch of dumb blocks pushed on you indiscriminately, blocks of content are pulled in by smart controllers who know what they are doing and what the context is.
• Negligible performance costs: Panels adds overhead, it's true, but you lose the fat from all blocks being rendered on every page.
∘ Comparing the Panels Everywhere Page Manager to the standard Drupal node view  by running the ab command on a simple node content example (not taking block bulge into consideration), Sam Boyer found that Panels Everywhere adds only 4 queries, no joins, all simple WHERE's; mem usage difference is small (3.08 MB vs 3.51 MB _peak_ usage), with a 16% slower transactions per second (CPU).
∘ However, performance is very efficient and modular, only loads what it needs for each scenario.
∘ Panels is also a caching framework, so the options are many and flexible, far superior to stock Drupal caching options.
• There will not be the hugely long wait for Panels to be working with Drupal 7, as there was for Panels to adjust to the completely new menu system in Drupal 6.
• More and more themes appearing for Panels Everywhere.
• You don't have to use a theme at all, just CSS, if you wish.
• Exciting features appearing, like panels stylizer, and in place edit.

Steps to getting it going

Starting off with a drush makefile

First I headed over to the Panels Everywhere site we got running the other evening, and I generated a drush makefile using the following command from the Drupal document root:

$ drush generate-makefile pandora.make

At the present time it doesn't detect project versions or other package info such as git or other version control remotes (see ) but it's a great start. See attached pft.make.ori.txt to see it. I then edited it and added the module versions, for documentation purposes more than anything since they are all the latest versions. Here is the makefile I finally came up with for my new project:

core = 6.19
projects[] = drupal

; Modules
projects[admin_menu] = 1.6
projects[adminrole][version] = 1.3
projects[advanced_help][version] = 1.2
projects[token][version] = 1.13
projects[vertical_tabs][version] = 1.0-beta7
projects[devel][version] = 1.22

projects[cck][version] = 2.8
projects[date][version] = 2.6
projects[filefield][version] = 3.7
projects[imageapi][version] = 1.8
projects[imagefield][version] = 3.7

projects[views][version] = 2.11

projects[ctools][version] = 1.7
projects[panels][version] = 3.7
projects[panels_everywhere][version] = 1.1

; Themes
projects[] = "precision"

I place my drush makefiles into a build directory, so to create the new project, I ran drush make:

$ drush make build/pft_staging.make pft_staging

I have also attached a log of the drush make run pft-drush-make-run.txt if you would like to take a look at what you can expect to see on the screen after executing the makefile.
So the end result is a copy of Drupal with all the modules downloaded and unpacked into the specified directory.

$ cd pft_staging
$ ls
CHANGELOG.txt  INSTALL.mysql.txt  MAINTAINERS.txt  scripts      xmlrpc.php
COPYRIGHT.txt  INSTALL.pgsql.txt  misc             sites
cron.php       install.php        modules          themes
includes       INSTALL.txt        profiles         update.php
index.php      LICENSE.txt        robots.txt       UPGRADE.txt
$ ls sites/all/modules
admin_menu  advanced_help  ctools  devel      imageapi    panels             token          views
adminrole   cck            date    filefield  imagefield  panels_everywhere  vertical_tabs

Site's up

After creating a database and a virtual host, I installed Drupal as I would normally. pft_staging is now a reality. I then enabled the following modules:

$ drush pm-list | grep Enabled
Administration Admin Role (adminrole) 6.x-1.3
Administration Administration menu (admin_menu) 6.x-1.6
CCK Content (content) 6.x-2.8
CCK Content Copy (content_copy) 6.x-2.8
CCK Fieldgroup (fieldgroup) 6.x-2.8
CCK FileField (filefield) 6.x-3.7
CCK ImageField (imagefield) 6.x-3.7
CCK Node Reference (nodereference) 6.x-2.8
CCK Number (number) 6.x-2.8
CCK Option Widgets (optionwidgets) 6.x-2.8
CCK Text (text) 6.x-2.8
CCK User Reference (userreference) 6.x-2.8
Chaos tool suite Bulk Export (bulk_export) 6.x-1.7
Chaos tool suite Chaos tools (ctools) 6.x-1.7
Chaos tool suite Custom content panes (ctools_custom_content) 6.x-1.7
Chaos tool suite Page manager (page_manager) 6.x-1.7
Chaos tool suite Stylizer (stylizer) 6.x-1.7
Chaos tool suite Views content panes (views_content) 6.x-1.7
Core - optional Color (color) 6.19
Core - optional Comment (comment) 6.19
Core - optional Database logging (dblog) 6.19
Core - optional Help (help) 6.19
Core - optional Menu (menu) 6.19
Core - optional Taxonomy (taxonomy) 6.19
Core - optional Update status (update) 6.19
Core - required Block (block) 6.19
Core - required Filter (filter) 6.19
Core - required Node (node) 6.19
Core - required System (system) 6.19
Core - required User (user) 6.19
Date/Time Date (date) 6.x-2.6
Date/Time Date API (date_api) 6.x-2.6
Date/Time Date Timezone (date_timezone) 6.x-2.6
Development Devel (devel) 6.x-1.22
ImageCache ImageAPI (imageapi) 6.x-1.8
ImageCache ImageAPI GD2 (imageapi_gd) 6.x-1.8
Other Advanced help (advanced_help) 6.x-1.2
Other Token (token) 6.x-1.13
Other Vertical Tabs (vertical_tabs) 6.x-1.0-beta7
Panels Mini panels (panels_mini) 6.x-3.7
Panels Panels (panels) 6.x-3.7
Panels Panels everywhere (panels_everywhere) 6.x-1.1
Views Views (views) 6.x-2.11
Views Views exporter (views_export) 6.x-2.11
Views Views UI (views_ui) 6.x-2.11

I then created five stories and a view with default, block and page displays (very simple, but attached here as for the curious). The site was a typical neo-site, with story nodes promoted to the front page so you don't lose your stuff.

Taking the leap to panels everywhere

Let's just follow the README.txt instructions and see where that gets us (pretty far!):
1. Backup database

I took that a step further and actually made a public github repo so you can follow along with these stages, and over the next few months between now and Chicago, as the new PFT gets dev'd (no, really; sshhh!):


2. Configure Panels Everywhere
I went to Administer > Site building > Panels > Everywhere
I selected the Panels Everywhere, Provide a sample variant for the site template, and even Override the page template checkboxes:

Administer > Site building > Panels > Everywhere

And the home page now looks like this, bereft of template.php and theme preprocess functions!:
Home page right after panels everywhere takes over
Now we will see that even node pages work on their own in a similar way. How come? What's going on?
3. Navigated to Administer >> Site Building >> Pages and edit the site_template
(Default site template) page.
It's the The "Page content" pane of the site_template! From the README:

 "The 'Page content' pane is absolutely critical. That is the pane that
    will hold the actual content of the page you are looking at. If this
    pane does not exist, *no content will be rendered*, only the page
    template. Think of this as being the $content variable in your
    page.tpl.php -- you need that and cannot live without it."

From Administer > Site Building > Pages click on the edit link for the System Default site template which we enabled earlier. It contains a sample variant which is why things are working as they are. This sample variant handles all tasks for the whole site in the absence of being overridden by other variants on this or any other page.
Click on the Content tab and you will immediately see why things are as they are; why there is a right-hand sidebar, and things just work (ahh, so that's what a variant is, a page manager task (request) handler):

Ah, so that's what a variant is

So why is there a left-hand sidebar when you are editing the page? Because even though we opted to override the page template (i.e. page.tpl.php in your current theme), "note that for safety reasons, editing the site_template page will always happen in the default page.tpl.php just in case your site template is not valid."

Doing away with Garland

Now we are going to do away with the current theme altogether. So long, Garland! We are going to implement the blank theme, a "non-theme". From the README file:

You might also consider creating a completely blank theme, because existing 
themes will have CSS that expects different markup. To create a blank theme:
1) mkdir sites/all/themes/blank
2) Create the following five lines in a file named
name = Blank
description = Blank
core = 6.x
stylesheets[all][] = blank.css
engine = phptemplate
3) Visit Administer >> Site building >> Themes and change your theme to the
   blank theme.

Now look what we got (looking at a single node):
Panels Everywhere with the blank theme
Just break out the old CSS and we got ourselves a site!

Hey, how come the browser title knows about the node (it's context aware!)? Because when we were editing the sample variante content section, Title type "From pane" was selected. Cool!

How come the breadcrumb is there twice? God knows. Someone tell me please.

Two, three ... many Variants

There is such a lot of stuff we can do now! Go to Admin > Site building > Pages and click on the Enable link associated with the node_view Node template. Mouse over and read all about it. As an example, we'll just create a special layout for a specific node. Edit the Node template and click on the Add a new variant link. For an administrative title, enter "Ut venenatis convallis tortor" or whatever (on our site, corresponding to node 4). Under Optional features, select Contexts. Click on the Create variant button. Now we need to set up the context as node nid == 4. With "node" selected from the Context drop down list, click on the Add context operation button. Under Identifier, we enter Node_4, and node_4 for the keyword. In the Enter the title or NID of a node field, we type in Ut venenatis convallis tortor, and select from the autocomplete widget (it selects nid 4). Having created the Node_4 context (ah, so that's what a context is!), we click on Continue. We choose a straight up three column layout and click on Continue. The wizard takes us to the Panel settings. We don't check Disable Drupal blocks/regions because... they already are! We are using Panels Everywhere! We click on Continue again. We set Title type to "From pane". The Left side, Middle column and Right side panes show up! Let's go ahead and click on "Create variant" already, before we lose our work :)
Now we have to specify how we want the node layout to be:

Two, three, many variants!

Click on the the little gray gear in the Left side pane, and then "Add content".  Click on the Node option on the left hand side, and then Node created date. Choose the date format you wish and click on Finish. Repeat for Node last updated date. And also add Node title. Drag the latter above the two date fields so it stays at the top of the Left side pane. Then, add content to the Middle column pane: body, and then author. Add links and terms (choose "unordered list formatting) to the Right side pane. Then click on the Update and save button.

The result of our labors when we view a node page (there are no links or taxonomy terms yet, otherwise they would appear in the blank space in the third column on the node page):

Our own little node variant
Since this is the only variant for node view, actually all nodes will now take it on. Cool (or not: make another variant for all nodes and then this Node_4 one will only be for node/4):

Hey, why does it say "Created date on the title bar of the browser? God knows.
To end our example, let's add the block display of the list stories view we made earlier, to the system default site template sample variant, on the right hand side pane (left as an exercise to the gentle reader).


Here's the answer: Edit the page, click on Content, click on the little gray gear to the left of the Sidebar label on the right-hand side pane, and click on Add content. Views is an option because we enabled the CTools based Views content panes module. Click on Views and select the block display (or any of them, actually, but we could link the block to the page, so we'll choose that), and click on Continue. And then Finish. Finally, save the panel page by clicking on update and save.
Now any page, whether a node view or not, will have the list of stories block in the right-hand side pane, under the navigation block. Cool.

Next steps

Design my website application in a non-crazy way, implement the pages, and I'm done!

pft-drush-make-run.txt3.55 KB
pft-view-list-stories.txt2.42 KB
pft.make_.ori_.txt480 bytes


How is this better/different or compared to using Context and Context layouts?

I like to base development on the Panels Everywhere Page Manager

And completely override the whole regions based approach to block assignment, which fragments the unitary view of the page.

The context layout options are much more flexible than the Context layout options, it's just much more dynamic and developed.

Finally, many more options are left to the end user.

I came to my conclusions after using both, and also after listening to the Lullabot "Cage fight" podcast.

Both systems are exciting and serve to bring a wealth of solutions to the table.

Contexts vs Selection Rules

Thanks for this intro to Panels Everywhere. One thing that I'm still uncertain of (this is a standard Panels thing) is adding custom contexts. I'm uncertain about the purpose. In your example, I believe it actually only functions to provide additional content to the Panel, but does nothing to limit when the pane is selected.

Following your suggestion, I created one variant that has a context of node_2, then created another variant with no added context. At this point, the node_2 variant was still in effect on both nodes 2 and 3. When reordering them so that the node_2 variant was second in the list of variants, the other variant controlled the layout of both nodes.

Would you want to use Selection Rules in this example? Unfortunately, there is no "if node is specific ID" selection rule, but I do have a simple snippet that does that, if entered into a PHP Code selection rule:

if ($contexts['argument_nid_1']->argument == '2') {
return TRUE;

It would be really nifty if setting a Context could also activate a specific panel layout, but I'm not seeing it actually happen for me yet. If you have any further tips on that, I'd definitely appreciate them.


use path selection criteria for node is specific nid

Good old: This panel will be selected if Current path is "node/3"

Select "String: URL path" and click add
Allow access on the following pages: node/3


Thanks for that tip.

Thanks for that tip. Sometimes the simplest and best answer is staring me right in the face.


I would love to abandon admin/settings/block for panels everywhere, but,asfaik, there's still the nagging problem of panels pages (not panel nodes) not being searchable as 'pages'.

A panels page isn't content

A panels page, as I understand it, is a url associated with the variants (request handlers) that will be handling the request according to various criteria. As such, it contains no searchable content in and of itself.

Content is included in the various panes containing elements assigned to them, and those elements may be blocks ("unassigned" in the standard Drupal regions way), nodes, views, etc., etc., etc.

Now, what might be the relationship between the standard Drupal search and these elements?

More Importantly

What is the relation to Solr, or the Lucene API module? I think I may have found the topic for my next blog post. Off to investigate ...


blocks myth

You are now repeating obsolete info that Sam said in his talk. In Drupal 5, we did render blocks that were not going to show up on the page. That was fixed in 6 AFAICT.

Still, I'm no fan of block module. My patch made it optional in D7. I'm still cool with hook_block() though.

So the block rendering question may in fact be as Sam says?

Is there any way we can find out for sure?

Thanks so much for shedding light on the subject. Unfortunately you showed up as "Anonymous"... who are you?

Thanks again,


Blocks that do not pass block

Blocks that do not pass block visibility tests do not get rendered (I verified this recently).

Blocks in regions that are not in the template will still get rendered if they do not have block visibility tests to prevent it.

Thanks so much for clearing up the block rendering mystery

Could you share your method of testing that?

In any case, the replacement of the whole routing system with the page manager which routes tasks to handlers is not only more efficient but is what web application engineers expect of a framework, and lends context to the child entities.


Drupal maintainer Angie Byron

Drupal maintainer Angie Byron mentions in an article called Drupal Performance Tip: Block Visibility that only blocks with the appropriate visibility settings get rendered.

She also mentions the block_list function as being responsible for fetching all the blocks in a certain reason, which suggests a way to perform the tests that you seem to want to perform so eagerly.

Setting the block visibility rules for each block is too tedious

People just aren't going to do that.

Extra breadcrumb

It looks like the 'page header elements' block has a breadcrumb in it along with the navigation and breadcrumb block. I'm not actually sure why this would be unless it was done in the theme (for example, the 'tinsel' theme has the breadcrumb in a different place). But by default the breadcrumb does not appear in the pane-header block so I'm not sure why you're seeing it there.

-- Merlin

Extra breadcrumb problem gone now :)

I had grab title from pane on the node template, which I took off now. I can checkout the original that had the extra breadcrumb, and try to see when exactly it went away.

Thanks so much for pointing that out. And thanks for all your hard work!