Hero

Como crear un "Style Plugin" para Panels en Drupal 7

Abril 04, 2013

enzo
Drupal

Panels es uno de los módulos de Drupal que mas amor y odio generan, pero no se puede negar que panels brinda mucha flexibilidad y es posible extender esta flexibilidad aun man mediante la creación de plugins.

Permitanme mostrarles un caso de ejemplo en el cual aplicaremos un plugin personalizado.

  1. El problema.

Panels cuenta con una serie de layouts que vienen de fabrica y pero también ser permite la creación de layouts personalizados. Los layouts están formados por elementos Columns y dentro de estos se pueden agregar elementos Row y por último dentro de estos se puedes agregar múltiples Regions.

Las regiones pueden ser Fluid o Fixed para un ancho determinado.

Por ejemplo podríamos declarar una región Fixed por ejemplo a 600px, hasta aquí todo bien. Pero si nuestros editores de contenido quieren la opción de poder cambiar el ancho de 600px a otro valor arbitrario en cada región, esto no es posible por medio de la interfaz gráfica, aun utilizando el Inline Panel Editor.

  1. La solución.

Afortunadamente ctools permite la creación de plugins que pueden ser utilizados en panels.

Lo primero que debemos hacer es agregar un módulo custom que implemente el hook hook_ctools_plugin_directory como se muestra a continuación.

/**
 * Implementation of hook_ctools_plugin_directory().
 */
function MYMODULE_ctools_plugin_directory($module, $plugin) {
 if ($plugin == 'styles') {
 return 'plugins/' . $plugin;
 }
}

En donde indicamos donde estarán declarados los plugins de ctools, por tanto se puede declarar mas de un plugin por módulo, es el acaso anterior debemos crear dentro del módulo una carpeta llamada plugins.

2.1 Definir el plugin style de ctools.

Para nuestro ejemplo crearemos un archivo llamado fixed_width.inc el cual guardara la definición del plugin style.

En este archivo lo primero que debemos hacer es crear una variable llamada $plugin la que contendrá la definición, esta no estará dentro de ninguna función, sino simplemente declarada como se puede apreciar a continuación.

<?php

/**
 * @file
 * Definition of the style base for the fixed width.
 */
// Plugin definition
$plugin = array(
 'title' => t('Fixed Width'),
 'description' => t('Allow to configure a fixed width'),
 'settings form' => '_ctoolsplugins_fixed_width_style_settings_form',
 'settings form validate' => '_ctoolsplugins_fixed_width_style_settings_form_validate',
 'render region' => 'panels_region_fixed_width_region',
 'hook theme' => array(
 'panels_region_fixed_width' => array(
 'variables' => array('content' => NULL, 'width' => NULL),
 'path' => panels_get_path('plugins/styles/templates', '', 'MYMODULE'),
 'template' => 'panels-region-fixed-width',
 ),
 ),
);

Veamos un poco la definición, las propiedades title y description son mas que obvios sobre la función que cumplen 😛.

Las propiedades settings form y settings form validate son los nombres de las función que se llamara para construir el formulario y validar los valores provistos en el formulario respectivamente, posteriormente explicaremos estas funciones.

La propiedad render region define que función de tema sera llamada para aplicar el plugin a la región a la que se haya aplicado el plugin, ctools hará el registro de la función theme por nosotros.

La propiedad hook theme como se puede inferir registra una función theme con sus variables y la ubicación del template que será usado por el tema.

2.2 Definir formulario de configuración para el plugin style de ctools.

En la definición ya se declaro el nombre de la función _ctoolsplugins_fixed_width_style_settings_form que se ejecutara para crear la página de configuración del plugin style, como se muestra a continuación.

/**
 * Settings form callback.
 */
function _ctoolsplugins_fixed_width_style_settings_form($style_settings) {
 $form['width'] = array(
 '#type' => 'textfield',
 '#title' => t('Fixed Width'),
 '#default_value' => $style_settings['width'],
 '#description' => "Set the fixed width in pixels"
 );

 return $form;
}

La función es una implementación estándar del FAPI de Drupal para crear un formulario de la forma que deseemos, en este caso solo requerimos la recolección de un valor para el ancho fijo.

Adicionalmente en la definición también se se declaro la función de validación para el formulario llamada _ctoolsplugins_fixed_width_style_settings_form_validate y su implementación se muestra a continuación.

function _ctoolsplugins_fixed_width_style_settings_form_validate(&$form, &$form_state) {
 if ($form_state['width'] !== '' && (!is_numeric($form_state['width']) || intval($form_state['width']) != $form_state['width'] || $form_state['width'] <= 0)) {
 form_set_error('width', t('Width must be a positive integer'));
 }
}

Lo único que hace la función es detectar si la entrada del editor fue un entero que pueda ser utilizado como un ancho fijo en la región.

El formulario de configuración se vería como la siguiente imagen.

panel region style plugin settings

2.3 Definir función render para la región.

En la definición del plugin se declaro que se llamaría a la función theme panels_region_fixed_width_region para aplicar el plugin style a la región, la declaración de esta función se presenta a continuación.

/**
 * Render callback.
 *
 * @ingroup themeable
 */
function theme_panels_region_fixed_width_region($vars) {
 $panes = $vars['panes'];
 $settings = $vars['settings'];
 $output = '';

 $width = empty($settings['width']) ? '100%' : $settings['width'] . 'px';

 $panes_output = '';
 foreach ($panes as $pane) {
 $panes_output .= $pane;
 }

 $output = theme('panels_region_fixed_width', array('content' => $panes_output, 'width' => $width));

 return $output;
}

Esta función actúa como un pre procesamiento para definir la variable content la cual contiene todos los panes contenidos en la región y la variable width la cual se obtiene de la configuración del style para la región.

La función hace uso de la función de Drupal theme para enviar al template las variables y luego devolver al módulo de panels la región con el style plugin aplicado.

2.4 Definir template para el style plugin.

Para finalizar se debe crear una carpeta dentro del módulo con ruta plugins/styles/templates y dentro de esta crear un archivo llamado panels-region-fixed-width.tpl.php y la definición se muestra a continuación.

<?php
/**
 * @file
 *
 * Display a div with a fixed widget.
 *
 * - $content: The content of the box.
 */
?>
<div class="fixed-width" style="width:<?php print $width;?>">
 <?php print $content; ?>
</div>

Al finaliza este proceso y borrar el cache de Drupal podremos escoger el style para nuestras regiones como se muestra en la siguiente imagen.

panel region style plugin 0

Espero que haya sido de su agrado y quizas le lleve a amar un poco mas panels.

enzo

Recibe consejos y oportunidades de trabajo 100% remotas y en dólares de weKnow Inc.