Drupal Panels setup for clean markup
It’s a fact that you get a hideous amount of markup with the Panels module straight out-of-the box, even if you use it to create a single column page without changing any of the options.
This is because each layer of the rendering process brings its own markup to the party.
Panels and layers
Panels are structured in layers, which is what makes them so flexible for any given requirement. Within a layout sit the regions and inside these are panes.
Each of these panes are configurable by providing CTools plugins. You can render panes and regions with style plugins and the layout with a layout plugin.
Each of these layers have their own wrapping markup and things can get excessive quickly.
Help is at hand
Luckily for us, there’s quite a lot of help for Panels straight out-of the-box. Firstly, there’s a ‘naked’ style plugin which drops all the wrapping markup and can be applied to your panes and regions. While this is a good start, the layout will still need markup specific to the site’s theme.
You can override each Panels layout as it’s presented by a theme hook. It’s literally as simple as copying a template to your site.
For most simple panels, it’s just a case of copying the panels-onecol.tpl.php file into the theme and customising it.
If you’re using a CSS framework or grid system (we use Bootstrap at Deeson) then this file is where you can re-work the markup to be specific to the system you are using.
My Panels page
Keeping all this in mind, I’ve created a simple Panels page which lists recent content to authenticated users. It’s built from a bean, a view (with an access rule) and some custom markup. It uses the one col layout.
Here’s my oh-so-simple panels-onecol.tpl.php file in my theme:
<div class="panel-display panel-1col clearfix" <?php if (!empty($css_id)) { print "id=\"$css_id\""; } ?>> <?php print $content['middle']; ?> </div>
And here’s the markup you’ll get when viewed as an unauthenticated user:
<section id="block-system-main"> <div class="panel-display panel-1col clearfix"> <div class="panel-pane pane-block pane-bean-recent-content-header"> <h2 class="pane-title">Recent content</h2> <div typeof="" about="/block/recent-content-header" class="entity entity-bean bean-editable clearfix">[...]</div> </div> <div class="panel-pane pane-custom pane-1"> <p>Login or create an account to view this content...</p> </div> </div> </section>
Let me know what you think!