Saturday, February 25, 2017

Panels: custom style plugin

Panels style plugins are made for wrapping panel panes and panel regions into extra markup. 99% of your needs are covered by a "Panels Extra Styles" module. Please look at that module if you need extra styles for panels. But if you need some specific style you can easily implement it.

In this tutorial we will create plugin style for region or pane. It will allow site builders to wrap region or pane into a custom markup entered in settings form.

1. Create a directory example_panels_module and put there a file example_panels_module.info:
name = Example panels module
description = Provides example implementation of panels plugins
core = 7.x

; Since we're using panels for creating
; plugins we have to define this
; dependency.
dependencies[] = panels
2. Tell ctools where it has to search plugins (file example_panels_module.module):
<?php

/**
 * Implements hook_ctools_plugin_directory().
 *
 * Integrate our module with Ctools. Tell where
 * Ctools has to search plugins. Please note that
 * we should return path to plugins directory only
 * if $module equals 'panels'.
 */
function example_panels_module_ctools_plugin_directory($module, $plugin) {
  if ($module == 'panels' && !empty($plugin)) {
    return "plugins/$plugin";
  }
}
3. Create directory plugins/styles and put there a file example_panels_module.style_plugin.inc:
<?php
/**
 * @file
 * 'Example panel style' style.
 */

$plugin = [
  // Plugin title.
  'title' => t('Example panel style'),
  // Plugin description.
  'description' => t('Raw HTML wrapper.'),
  // Render region callback.
  'render region' => 'example_panels_module_raw_wrapper_render_region',
  // Render pane callback
  'render pane' => 'example_panels_module_raw_wrapper_render_pane',
  // Region settings form.
  'settings form' => 'example_panels_module_raw_wrapper_region_settings_form',
  // Pane settings form.
  'pane settings form' => 'example_panels_module_raw_wrapper_pane_settings_form',
];

/**
 * Region settings form callback.
 */
function example_panels_module_raw_wrapper_region_settings_form($settings) {
  // Define a settings form with prefix and suffix text areas
  // for region style.
  $form['wrapper_region_prefix'] = [
    '#type' => 'textarea',
    '#title' => t('Region wrapper prefix'),
    '#default_value' => !empty($settings['wrapper_region_prefix']) ? $settings['wrapper_region_prefix'] : '',
  ];

  $form['wrapper_region_suffix'] = [
    '#type' => 'textarea',
    '#title' => t('Region wrapper suffix'),
    '#default_value' => !empty($settings['wrapper_region_suffix']) ? $settings['wrapper_region_suffix'] : '',
  ];

  return $form;
}

/**
 * Region render callback.
 *
 * Please note that it's a theme function
 * and has to start with 'theme_' prefix.
 */
function theme_example_panels_module_raw_wrapper_render_region($vars) {
  $output = '';

  // Variable $vars['panes'] contains an array of all
  // panel panes in current region. Collect them into
  // variable.
  foreach ($vars['panes'] as $pane) {
    $output .= $pane;
  }

  // Variable $vars['settings'] contains settings
  // entered in settings form. Wrap region content
  // into custom markup.
  return $vars['settings']['wrapper_region_prefix'] . $output . $vars['settings']['wrapper_region_suffix'];
}

/**
 * Pane settings form callback.
 */
function example_panels_module_raw_wrapper_pane_settings_form($settings) {
  // Define a settings form with prefix and suffix text areas
  // for pane style.
  $form['wrapper_pane_prefix'] = [
    '#type' => 'textarea',
    '#title' => t('Pane wrapper prefix'),
    '#default_value' => !empty($settings['wrapper_pane_prefix']) ? $settings['wrapper_pane_prefix'] : '',
  ];

  $form['wrapper_pane_suffix'] = [
    '#type' => 'textarea',
    '#title' => t('Pane wrapper suffix'),
    '#default_value' => !empty($settings['wrapper_pane_suffix']) ? $settings['wrapper_pane_suffix'] : '',
  ];

  return $form;
}

/**
 * Pane render callback.
 *
 * Please note that it's a theme function
 * and has to start with 'theme_' prefix.
 */
function theme_example_panels_module_raw_wrapper_render_pane($vars) {
  // Variable $vars['settings'] contains settings
  // entered in settings form. Variable
  // $vars['content']->content is a renderable array
  // of a current pane. Wrap pane content
  // into custom markup.
  return $vars['settings']['wrapper_pane_prefix'] . render($vars['content']->content) . $vars['settings']['wrapper_pane_suffix'];
}
For now we have a module with next structure:
example_panels_module
  |__ plugins
  |  |__ styles
  |  |  |__ example_panels_module.styles_plugin.inc
  |__ example_panels_module.info
  |__ example_panels_module.module
When it's enabled you will be able to setup style for a region or a pane. We've created style for both of them but you can define style only for region or only for pane.

Let's test our style. I want to edit node/%node page: wrap content region into div tag with a class "content-region-wrapper". And wrap node_beind_viewed pane into span tag with id "pane-node-view-wrapper". That's how can I do that:

Change style for a region

Select newly created style

Set up prefix and suffix for a region

The same way I've set up prefix and suffix for a panel pane and that's what I've got:

Result markup


No comments:

Post a Comment