Skip to Content
RSSGrab the RSS feed! ->

How to create a panels style plugin

Creating panels styles can be very powerful. You can define certain styles for your client to choose from, so they can choose what type of display the panel pane will be like. This way you keep the workflow clean, your code under revision control, your themer gets to keep his sanity, and your concious stays clear.

This article assumes you know about running panels, and more or less what the nomenclature is. You should know also that panels now uses ctools, which is is primarily a set of APIs and tools to improve the developer experience.

So, what we'll be doing here is actually creating a ctools plugin, to implement a new panels style. Sorry if I'm confusing you already, don't worry, it's actually quite straight forward, we want to be able to do this:

... and then this:

OK, now to the meat of it. We'll call our module ctoolsplugins.

1. Create a new module, and tell ctools about our plugins

What you need is very basic, an info file and a module file. So far, nothing new.

1.1 Declare our dependencies

So we obviously need ctools module on our site, and well, the plugin wouldn't make much sense without panels and page_manager, so:

; $Id:
name = Ctools Plugins
description = Our custom ctools plugins
core = 6.x
dependencies[] = ctools
dependencies[] = panels
dependencies[] = page_manager
package = Chaos tool suite

1.2 Implement hook_ctools_plugin_directory to tell ctools about our plugins

In our module file, of course, we'll implement this function, that will check if ctools if looking for style plugins, and lets if so, it will let it know where ours are:

  * Implementation of hook_ctools_plugin_directory().
function ctoolsplugins_ctools_plugin_directory($module, $plugin) {
  if (
$module == 'panels' && $plugin == 'styles') {
'plugins/' . $plugin;

2. Prepare our file structure for the plugins, and create our plugin file.

This image is pretty self explanatory:

We'll call our plugin 'collapsible', so we create inside ctoolsplugins/plugins/styles/ a file called

3. Implement our style plugin in

3.1 Define your style goals and necessities.

OK, Here you should think about what you are going to do with the plugin.

  • Is it just for markup?
  • Will you be offering different options?
  • Will you be implementing javascript on it?

In our case, we'll take the opportunity, to teach you another thing that ctools has, the collapsible div utility. So our style will basically convert any panels pane, into a collapsible panels pane:

And because we are friendly developers (or like not to be ever bothered after developing it), we'll give the user a chance to configure if they want the pane to start opened or closed. That means an extra settings form, so we can have this:

3.2 Imlement hook_panels_style_info

The naming is very important here, it should be modulename_stylename_panels_style. You basically return an array, defining your style:

* @file
* Definition of the 'collapsible' panel style.

* Implementation of hook_panels_style_info().
function ctoolsplugins_collapsible_panels_styles() {
  return array(
'title' => t('Collapsible div'),
'description' => t('Display the pane in a collapsible div.'),
'render pane' => 'ctoolsplugins_collapsible_style_render_pane',
'pane settings form' => 'ctoolsplugins_collapsible_style_settings_form',

'title' and 'description' are pretty self explanatory.
'render pane' specifies the theme function we'll be providing for rendering the pane. Watch the naming convention.
'pane settings form' specifies the callback function which provides the extra settings form, that we'll be using for our start up options. Watch the naming convention.

3.3 Define the settings form callback.

The name of the function will be what you specified in 'pane settings form' earlier. Just provide a new array inside $form, for each configuration you want the user to specify. See the FAPI documentation for reference.

* Settings form callback.
function ctoolsplugins_collapsible_style_settings_form($style_settings) {
$form['collapsed'] = array(
'#type' => 'select',
'#title' => t('Startup behaviour'),
'#options' => array(
0 => t('Start opened'),
1 => t('Start collapsed'),
'#default_value' => (isset($style_settings['collapsed'])) ? $style_settings['collapsed'] : 'opened',
'#description' => t('Choose whether you want the pane to start collapsed or opened'),


This is pretty straight forward, in our case we provide two options, one to start opened and one to start collapsed. If collapsed is chosen, the value will be 1.

3.4 Define the render callback function.

The name of the function will be what you previously specified in 'render pane'. This is just a theme function, and where you have the chance of altering what will be shown to the user when viewing the page.

* Render callback.
* @ingroup themeable
function theme_ctoolsplugins_collapsible_style_render_pane($content, $pane, $display) {
$style_settings = $pane->style['settings']; // good idea for readability of code if you have a ton of settings
$start_settings = $style_settings['collapsed']; // we can do this be cause the only values possible are 0 or 1

$pane_content = $content->content;

  if (
$content->title) {
$pane_title = '<h2 class="pane-title">'. $content->title .'</h2>';

// theme('ctools_collapsible', $handle, $content, $collapsed);
$result = theme('ctools_collapsible', $pane_title, $pane_content, $start_settings);

// if we don't have a pane title, we just print out the content as normaly, since there's no handle
else {
$result = $pane_content;


Important to note here, is that our user's specified settings are inside $pane->style['settings']. In this example we check if there's a title available, and if so we implement the ctools_collapsible theme function to get our collapsible panes. Other wise we don't have a handle, and we just return the content as normal.

And that is it. Hope you found the article useful, and if you'd like me to write up some more articles about writing plugins for panels/ctools, drop a comment with your question/suggestion!

UPDATE:You can also provide a style plugin in your theme, as shown in this fine tutorial.

ctoolsplugins.tar.gz1.3 KB

73 responses to this article.


Funciona de maravilla!

Funciona de maravilla! Gracias por hacer este post tan claro, brindando el paso a una goleada para los nuevitos! Peter de b&b Venecia


Thank you for writing this,

Thank you for writing this, it's saved me a ton of time in figuring this out myself. One minor correction, in step 1.2, I think you're if statement shoudl be the following, to prevent loading the plugin for some other module who might also use plugins names 'styles'

if ($plugin == 'styles') {

should be

if ('panels' == $module && 'styles' == $plugin) {


Excelent point Oscar, I have

Excelent point Oscar, I have updated the code in the post, thanks for pointing this out, and glad to hear it saved you time!


I was recommended this

I was recommended this website by my cousin. I am
not sure whether this post is written by him as nobody else know such detailed about my
problem. You are wonderful! Thanks!


Thanks for your marvelous

Thanks for your marvelous posting! I certainly enjoyed reading it, you
happen to be a great author. I will be sure to bookmark your blog and definitely will come back very soon.
I want to encourage you to definitely continue your great writing, have a nice holiday


One thing I learned, is for

One thing I learned, is for your style to be available as a region style, you need to define a 'render panel' function, for it to be available as a style for a single pane, defined a 'render pane' function.


Fantastic goods from you,

Fantastic goods from you, man. I've understand your stuff previous tto and you are just too great.
I really like what you have acquired here, really like what you arre saying and the way in which you
say it. You make it entertaining and you still care
for too keep it sensible. I can't wait to read far more from you.
Thiss is actually a terrific web site.


I just tried this and now I

I just tried this and now I can't access the panels dashboard. I get the WSOD.


The WSOD is most likely an

The WSOD is most likely an indication that php is runing out of memory on your server. This has nothing to do with what is explained here, but rather a problem with your server's configuration.
Check out this link about what could be causing this: , but I find that most of the cases this is fixed by increasing memory_limit in your server's php.ini file.


Hi, i think that i noticed

Hi, i think that i noticed you visited my web site thus i came to return the favor?.I
am trying to to find things to enhance my site!I assume its good enough to use a few of
your ideas!!


Hey there! Do you use

Hey there! Do you use Twitter? I'd like to follow you if that
would be ok. I'm definitely enjoying your blog and look forward to
new posts.


A set of substandard quality

A set of substandard quality might cause several other eye issues to some extent.

The best better you can provide your spectacles could be the
special washing fabric which keeps your spectacles in ideal condition.


The truth is that the job

The truth is that the job isn't as predictable as it may sound.

Perhaps you want to do landscaping on the side
and go full-time when you already have a steady list of clients.
- Large sized projects where a single person is working dedicatedly on single tasks.


Tried the above module in D7,

Tried the above module in D7, but no dice. It shows up in the styles menu, but the field never gets collapsed upon viewing it.


This post ranks high in

This post ranks high in Google for Drupal Panels Tabs, but it applies to D6. The following patch at d.o will get you tabs in Panels for Drupal 7 - vertical tabs by default, but also horizontal tabs will be enabled as an option if you also have the field group module enabled.

Tabs style plugin: Vertical Tabs in core! (for Drupal 7)

Field Group Module:


Everyone loves it whenever

Everyone loves it whenever people come together
and share views. Great blog, keep it up!


This allows for a boundary to

This allows for a boundary to be set between school and the rest of the house to
encourage a school mindset. There are several beautiful and sturdy office upholstery almost
anywhere, too a staple look once and for all buy and sell.
The clock can be simple and basic, which is perfect if you are trying to teach a child to tell time.

Use containers in your drawers to keep everything
together and organized. These small crafts can be made quickly and are perfect to
use as stocking stuffers or add-on gifts.


It looks like this hook has

It looks like this hook has changed in Drupal 7. It now passes one array with the three variables contacted, ie:

function theme_style_render_pane($x) {
$content = $x['content'];
$pane = $x['pane'];
$display = $x['display'];


return $output;


This paragraph wil assist the

This paragraph wil assist the internet users for settinhg up new website or
even a webhlog from start to end.


Thank you for another

Thank you for another excellent article. Where else may anybody get that type oof informkation in such an ideal approach of writing?
I have a presentation next week, and I am on the look for such


Oh my goodness! Incredible

Oh my goodness! Incredible article dude! Thank you so much, However I am having problems with your RSS.

I don't understand why I can't subscribe to it.
Is there anyone else having identical RSS issues? Anybody who knows
the answer can you kindly respond? Thanx!!


Louis, there are numerous law

Louis, there are numerous law firms that deal with accidental cases
that subjugate the ill-fated persons to fatal brain injury.

But when he is represented by a Minneapolis car accident lawyer
things turn different. Basically, three most important things like
insurance representatives work for the company and they will not
be friends.


Great site. Lots of useful

Great site. Lots of useful info here. I'm sending it to a few friends
ans also sharing in delicious. And certainly, thanks
for your effort!


Yoou have made some decent

Yoou have made some decent points there. I looked on thhe net to learn more abbout the issue and found most people will
ggo alokng with your views on thios web site.


I think the admin of this web

I think the admin of this web page is in fact working hard
in favor of his website, for the reason that here every
data is quality based material.


Thank you for sharing

Thank you for sharing excellent informations. Your web-site is very cool.


This is a fantastic website

This is a fantastic website and I can not recommend you guys enough. I really appreciate your post. It is very helpful for all the people on the web.


I am really very happy to

I am really very happy to find this particular site. I just wanted to say thank you for this huge read!! I absolutely enjoying every petite bit of it and I have you bookmarked to test out new substance you post.


This blog is very interesting

This blog is very interesting and too informative. I enjoyed to visiting your blog. You have done a really nice job. Keep it up!


Fine way of describing, and

Fine way of describing, and pleasant piece of writing to obtain information concerning my presentation focus,
which i am going to deliver in university.


Roadside assistance is also a

Roadside assistance is also a assistance that you should also be prepared, because paying for somebody who can assist you whilst working on the engine of your vehicle is a waste of dollars.


I visited various websites

I visited various websites however the audio feature for
audio songs current at this web page is really


This is a wonderful post. I

This is a wonderful post. I enjoyed the information lot. I will bookmark this page. Thanks for sharing this important information


It's actually a great and

It's actually a great and helpful piece of info.

I'm glad that you simply shared this useful info with us.
Please stay us up to date like this. Thanks for sharing.


Excellent blog here! Also

Excellent blog here! Also your site loads up very fast!
What web host are you using? Can I get your affiliate link to your host?
I wish my web site loaded up as fast as yours lol


Admiring the commitment you

Admiring the commitment you put into your site and in depth information you provide.
It's nice to come across a blog every once in a while that isn't the same
old rehashed information. Wonderful read! I've saved your site and
I'm including your RSS feeds to my Google account.


If you are prone to blisters,

If you are prone to blisters, then taping your feet
in troublesome areas with zinc oxide tape is advisable.
Doing these physical exercises will help reduce your cravings and the stress associated with them by
refocusing your consideration on the breathing exercise, not your cravings.
You need to find a way to change the way you think about food, in order
to avoid the bad habit of overeating.


I read a lot of interesting

I read a lot of interesting content here. Probably you
spend a lot of time writing, i know how to save you a
lot of time, there is an online tool that creates unique, google friendly articles in minutes, just type in google - k2seotips unlimited content


It's actually a great and

It's actually a great and useful piece of information. I am
satisfied that you just shared this helpful info with us.
Please keep us informed like this. Thanks for sharing.


It's a pity you don't have a

It's a pity you don't have a donate button! I'd most certainly donate to this superb blog!
I suppose for now i'll settle for book-marking and adding your RSS feed to my Google account.
I look forward to new updates and will share this blog with my Facebook group.
Chat soon!


Hello there, You've done a

Hello there, You've done a fantastic job. I'll certainly digg it and personally
suggest to my friends. I am sure they'll be benefited from this web site.


Thank you for this great I

Thank you for this great I definitely loved every little bit of it.


This is my first time pay a

This is my first time pay a visit at here and i am really
happy to read all at single place.


It's hard to come by

It's hard to come by experienced people on this topic,
but you seem like you know what you're talking about!


Hi there! Someone in my

Hi there! Someone in my Facebook group shared this website
with us so I came to look it over. I'm definitely loving the information.
I'm bookmarking and will be tweeting this to my followers!

Excellent blog and excellent design and style.


you're really a good

you're really a good webmaster. The site loading velocity is incredible.
It kind of feels that you're doing any distinctive
trick. In addition, The contents are masterwork.
you have done a great job on this topic!


You should be a part of a

You should be a part of a contest for one of the most
useful websites on the web. I am going to recommend this website!


Greetings from Carolina! I'm

Greetings from Carolina! I'm bored to death at work so I decided to browse your website on my
iphone during lunch break. I love the information you present here and can't wait to take a
look when I get home. I'm amazed at how quick your blog
loaded on my cell phone .. I'm not even using WIFI, just 3G
.. Anyhow, wonderful site!


Wow, fantastic blog layout!

Wow, fantastic blog layout! How long have you been blogging
for? you make blogging look easy. The overall look of your web
site is magnificent, let alone the content!


Je vois dе suitе que vous

Je vois dе suitе que vous maîtriseƶ très bien ce thème

Feel frеe to surf too my web Ьlog baise interraciale

Post new comment

The content of this field is kept private and will not be shown publicly.
By submitting this form, you accept the Mollom privacy policy.