Often on Drupal sites you need the ability to create re-usable panel panes for use on the site. Each panel pane would need custom configuration, and could even be context aware (aware of were they are placed on the site).
This is where ctools content types comes in. Ctools content types are one type of plugin that the ctools module provides. Out of the box, the ctools module provides a few content types to support core modules. These can be found in the git repository.
Advantages of ctools content types versus blocks
- You do not need administer blocks permission (which is very risky for content authors to have)
- Tight integration with panels and other panelizer. Using panelizer affords you the option of not giving away the 'administer panels' permission
- Custom configuration edit forms to allow the panes to be re-usable and to make sense for your content authors
- Developers can abstract away any complexity in code, leaving the content authors with only the job of adding the pane and configuring it
Unfortunately there is not a lot of documentation around content types, so I will go through a simple example with you.
Example implementation of ctools content type plugin
In this example I will go through creating a custom twitter timeline widget that can be configured to pull through a selected user's tweets, and with an option for limiting the number displayed.
Step 1: Create a new custom module with this in the .module file:
Where the name of my custom module is 'examplemodule'.
This lets ctools know that any file in the folder 'plugins/content_types/' should be parsed for content type plugins. This also keeps your code really nice.
Step 2: Create the include file for the plugin
mkdir -p plugins/content_types cd plugins/content_types vim twitter_timeline.inc
Notice the directory structure matches what was declared in the .module file.
Step 3: Declare the plugin to ctools
This piece of code lets ctools know what functions to call, what argument defaults there are and so fourth. It should be largely self explanatory. It also means that your pane will show up in panels now, as we can see from this picture:
Step 4: Implementing admin_info
Admin information is an optional function to implement that helps describe the pane when it is included on a panel. I would recomment always implementing it so your content authors can always see at a glance what configuration a particular pane has.
This is what the pane will look like after being configured
Step 5: Implementing the edit form
The heart of ctools content types is the ability to create simple configuration forms for your content authors so they can easily create and edit panes. Edit forms use standard form API, so they are really easy to make
In order to save the configuration back to the $conf storage for the pane, you will also need a submit handler
There you have it, now you can configure the pane username, and the amount of tweets to show, all of which have sane defaults and helpful descriptions for your content authors. This is what this step looks like:
Step 6: Implemeting the render callback
This is the guts of the pane, and is responsible for producing markup to be rendered on the page. I have taken a simplitest approach to this and have not used a theme function (and template), in reality I would encourage this as well.
Here is a sample panel page, with the twitter timelien pane on the right hand side
And as you can imagine, it is relatively easy to add more panes onto the panel, here is another on the same page
Full module download
I thought this post might be a bit code heavy, so I decided to include the full source of the module in case you want to download and install it yourself. Feel free to rename it, extend it, do what you want with it.
In this tutorial you have seen how easy it is to make a fully custom ctools content type plugin, from scratch. And hopefully begin to see how this is more powerful then traditional blocks.
What are your experiences with ctools content types, and helpful advice for others? Did this tutorial help you at all? Let me know in the comments.