Exporting Panelizer Defaults to Code

Perhaps you already know Panelizer, the new-ish module that lets you turn any content type into a Panel, allowing a content editor to customize the layout of individual pieces of content as they are created.

Panelizer is a pretty cool tool that I've only recently started to explore on a new project. One of the tasks this new project needed was for the default Panelizer settings and configuration to be put into code and enabled as part of the site install process.

Brian McMurray, Software Architect
#Drupal | Posted

Perhaps you already know Panelizer, the new-ish module that lets you turn any content type into a Panel, allowing a content editor to customize the layout of individual pieces of content as they are created.

Panelizer is a pretty cool tool that I've only recently started to explore on a new project. One of the tasks this new project needed was for the default Panelizer settings and configuration to be put into code and enabled as part of the site install process.

Panelizer defaults are a combination of CTools exportables and a handful of variables, which means if your site is already using Features and Strongarm, you can just bundle up those defaults into a custom Feature and you should be good to go. On this particular project, however, we aren't using Strongarm, so we needed to do this the "old fashioned" way.

In case you do, too, whether its because you just love using just Drupal core functionality or because for whatever reason you aren't or can't use Strongarm and Features, here's how to export your default Panelizer configuration into a simple custom module:

To get started let's create our own custom module for Drupal 7: my_panelizer

Create a my_panelizer.info file and enter the following into the file:

  1. name = My Panelizer Defaults
  2. description = Default settings for Panelizer customizations
  3. dependencies[] = panelizer
  4. package = custom
  5. core = 7.x
  6.  
  7. files[] = my_panelizer.panelizer.inc

 

If you notice in the installation instructions for Panelizer it says the following:

"Visit the Page Manager administer pages page and enable the node template system page (node_view) if it is not already enabled. Panelizer won't work without this enabled!"

Well, we don't want to have to have such a manual step when installing these defaults, so let's do this in code instead.

Create my_panelizer.install with the following:

  1. <?php
  2. /**
  3.  * Imlpements hook_install().
  4.  */
  5. function my_panelizer_install() {
  6.  
  7. // Set up variables and actions for Panelizer configuration
  8. my_panelizer_setup_panelizer();
  9. }
  10.  
  11. function my_panelizer_setup_panelizer() {
  12. // Enable the node/%node page manager plugin
  13. variable_set('page_manager_node_view_disabled', FALSE);
  14. }

Now, when this module gets installed it will enable the <span class="kw5">node_view</span> template in Page Manager for us.

Let's move on to the actual Panelizer defaults. After configuring your default panelizer settings via the admin UI for a content type, we can export the panelizers.

Enable the Bulk Export module that is part of CTools, go to its administration page at Administration -> Structure -> Bulk Exporter and select the Panelizer defaults you'd like to export. Enter my_panelizer into the Module Name field and press Export.

You'll now need to create two new files: my_panelizer.module and my_panelizer.panelizer.inc Copy and paste from the textareas on the Bulk Exporter page into those respective files and you've now captured a good portion of your default Panelizer settings.

What's still missing, however, are four variables for each content type for which you've enabled Panelizer. To get these values you can either head into MySQL or use a handy tool like Drush to help you. I prefer Drush so that's what these instructions will use.

The first variable that we need to get is panelizer_defaults_node_<span class="sy0"><</span>content-type<span class="sy0">></span> where <span class="sy0"><</span>content-type<span class="sy0">></span> is the machine name of the content type.

For the remainder of this example, we will assume that your content type's machine name is <span class="st0">'page'</span>

In your command line get to your Drupal docroot and then type:

drush vget panelizer_defaults

You should get back something like this:

  1. panelizer_defaults_node_page: Array
  2. (
  3. [status] => 1
  4. [php] => 1
  5. [choice] =>
  6. )

Now, in your my_panelizer_setup_panelizer function in my_panelizer.install add the following:

  1. // Enable Panelizer on Basic Pages
  2. variable_set('panelizer_defaults_node_page', array('status' => TRUE, 'default' => TRUE, 'choice' => FALSE));

At this point, you have enough to install this module and set up this content type with a Panelizer default that will allow all layout choices and all content options. If you don't need to restrict layouts or content options, you can stop here.

If, however, you do need to restrict those things, we have a bit more work to do. There are three more variables that we need to set to restrict layouts and content options. One of these variables, however, stores an Object of type panels_allowed_layouts so setting it with <span class="kw5">variable_set</span><span class="br0">(</span><span class="br0">)</span> is not as easy as it could be.

If you go to your Panelizer default settings and configure the Allowed Layouts to only allow the built in "Flexible" layout and then save the settings, we can find the variable with Drush:

drush vget panelizer_node:page_allowed_layouts

Drush should return something like:

[sh]panelizer_node:page_allowed_layouts: "O:22:"panels_allowed_layouts":4:{s:9:"allow_new";b:1;s:11:"module_name";s:19:"panelizer_node:page";s:23:"allowed_layout_settings";a:10:{s:8:"flexible";b:1;s:14:"twocol_stacked";b:0;s:13:"twocol_bricks";b:0;s:6:"twocol";b:0;s:25:"threecol_33_34_33_stacked";b:0;s:17:"threecol_33_34_33";b:0;s:25:"threecol_25_50_25_stacked";b:0;s:17:"threecol_25_50_25";b:0;s:6:"onecol";b:0;s:8:"flexgrid";b:1;}s:10:"form_state";N;}"[/sh]

This isn't super useful -- it's a serialized object and is hardly legible. Moreover, when I was attempting to just take this serialized string and set it during the install process, it wasn't working. The trick lies in that this is a special type of object from Panels, and luckily there is still a way we can create it programatically.

Add the following into my_panelizer_setup_panelizer<span class="br0">(</span><span class="br0">)</span>:

  1. ctools_include('common', 'panels');
  2. $allowed_layouts = new panels_allowed_layouts();
  3. $allowed_layouts->allow_new = TRUE;
  4. $allowed_layouts->module_name = 'panelizer_node:page';
  5. $allowed_layouts->allowed_layout_settings = array(
  6. 'flexible' => TRUE,
  7. 'twocol_stacked' => FALSE,
  8. 'twocol_bricks' => FALSE,
  9. 'twocol' => FALSE,
  10. 'threecol_33_34_33_stacked' => FALSE,
  11. 'threecol_33_34_33' => FALSE,
  12. 'threecol_25_50_25_stacked' => FALSE,
  13. 'threecol_25_50_25' => FALSE,
  14. 'onecol' => FALSE,
  15. 'flexgrid' => FALSE,
  16. );
  17. $allowed_layouts->save();

The above code includes a file from Panels which allows us to create a new object of type panels_allowed_layouts set some values to it and then call its save<span class="br0">(</span><span class="br0">)</span> method, which does the job of saving this to the variables table for us.

Last, but not least, is how to configure whether your Panelizer will allow all new content options or only specific values. The variable panelizer_node:page_default stores an array of which content option types allow all items added after this configuration is set and you'll set it in my_panelizer_setup_panelizer<span class="br0">(</span><span class="br0">)</span> like so:

  1. variable_set('panelizer_node:page_default', array(
  2. "token" => FALSE,
  3. "entity_form_field" => FALSE,
  4. "entity_field" => FALSE,
  5. "entity_field_extra" => FALSE,
  6. "custom" => FALSE,
  7. "block" => FALSE,
  8. "entity_view" => FALSE,
  9. "other" => FALSE,
  10. ));

Then, if you've allowed only specific content options, you need to set panelizer_node:page_allowed_types. This is a very large array of options and you'll set it something like this (array snipped for brevity):

  1. variable_set('panelizer_node:page_allowed_types', array(
  2. ...
  3. "node_form_author-node_form_author" => 0,
  4. "node_form_buttons-node_form_buttons" => 0,
  5. "node_form_comment-node_form_comment" => 0,
  6. "node_form_log-node_form_log" => 0,
  7. "node_form_menu-node_form_menu" => 0,
  8. "node_form_path-node_form_path" => 0,
  9. "node_form_publishing-node_form_publishing" => 0,
  10. "node_form_title-node_form_title" => 0,
  11. "node_attachments-node_attachments" => 0,
  12. "node_author-node_author" => 0,
  13. "node_body-node_body" => "node_body-node_body",
  14. "node_comment_form-node_comment_form" => 0,
  15. "node_comments-node_comments" => 0,
  16. "node_content-node_content" => 0,
  17. "node_created-node_created" => 0,
  18. "node_links-node_links" => 0,
  19. "node_terms-node_terms" => 0,
  20. "node_title-node_title" => 0,
  21. "node_type_desc-node_type_desc" => 0,
  22. "node_updated-node_updated" => 0,
  23. "node-node" => "node-node",
  24. "form-form" => 0,
  25. "panelizer_form_default-panelizer_form_default" => 0,
  26. ));

And that's it! With these four variables and your exported Panelizers, you should now be able to enable this module (perhaps as part of your install profile) and your content type should be set up with your configured Panelizer defaults.

One last final note: I was having some trouble getting Panelizer 7.x-2.0 to read the defaults from code, however when I updated to Panelizer 7.x-2.x-dev everything started working just fine.

Happy coding!

Brian McMurray

Software Architect