Crear un Widget para WordPress

Hoy en el trabajo me he visto en la obligación de crear un Widget para WordPress. Los Widgets son aquellos «cuadros» que podemos añadir normalmente al sidebar de nuestro blog, aunque hablando con propiedad se pueden añadir a cualquier área de Widgets (pueden existir varias áreas, para el footer, o áreas personalizadas para las diferentes visualizaciones).

Por ejemplo, en este blog, los cuadros que hay a la derecha son Widgets (el de búsqueda, Twitter, posts, etc).

WordPress desde la versión 2.8 nos facilita la tarea de crear nuevos Widgets personalizados que podemos complicarlos todo lo que queramos. En este caso, como se trata de un ejemplo haremos uno bastante sencillo, un Widget gestionable donde podremos decir cuál es el título, la descripción de una oferta y la URL de la oferta.

Para crear Widgets en WordPress se utiliza la clase WP_Widget cuyo código podéis analizar aquí.

Para crear uno tenemos que crear una clase en PHP con cuatro funciones básicas:

  • constructor
  • form
  • update
  • widget

// La nueva clase debe heredar de WP_Widget
class ofertas_widget extends WP_Widget {
   function ofertas_widget() {
       // Constructor del Widget
   }

   function form($instance) {
       // Construye el formulario de administración
   }

   function update($new_instance, $old_instance) {
       // Guarda las opciones del Widget
   }

   function widget($args, $instance) {
       // Construye el código para mostrar el widget públicamente
   }
}

Tras la creación de la clase debemos usar el conector widgets_init asociado a una acción que llame a la función register_widget().

Vamos a ver esto en un ejemplo.

add_action('widgets_init', 'registra_mis_widgets');
function registra_mis_widgets() {
    register_widget('ofertas_widget');
}

Pero antes de lo anterior tenemos que «rellenar» las funciones básicas de la clase del Widget.

Constructor

En el constructor básico principalmente llamamos al constructor de la clase WP_Widget, lo podemos hacer como está aquí o llamando al constructor de la forma de PHP5.

Los parámetros de este constructor son la id del Widget, el título y unos argumentos opcionales que incluyen la descripción y la clase que se aplicará al «envoltorio» del Widget que en cada tema puede ser un elemento diferente (li, div, etc).

Se puede pasar un cuarto parámetro, que es un array conteniendo la altura y anchura del cuadro de configuración en el panel de administración aunque la altura por ahora no se usa. En el ejemplo no se pasa.

function ofertas_widget() {
       $options = array('classname' => 'mi-estilo',
                        'description' => 'Widget que muestra una oferta');
       $this->WP_Widget('ofertas_widget', 'Ofertas', $options);
    }

El siguente paso es la función form.

Form

La función form, recordemos, muestra el formulario de edición en el panel de administración.

    function form($instance) {
        // Valores por defecto
        $defaults = array('titulo' => 'Ofertas', 'descripcion'=> '', 'url' => '');
        // Se hace un merge, en $instance quedan los valores actualizados
        $instance = wp_parse_args((array)$instance, $defaults);
        // Cogemos los valores
        $titulo = $instance['titulo'];
        $descripcion = $instance['descripcion'];
        $url = $instance['url'];
        // Mostramos el formulario
        ?>
        <p>
            Titulo
            <input class="widefat" type="text" name="<?php echo $this->get_field_name('titulo');?>"
                   value="<?php echo esc_attr($titulo);?>"/>
        </p>

        <p>
            Descripcion
            <input class="widefat" type="text" name="<?php echo $this->get_field_name('descripcion');?>"
                   value="<?php echo esc_attr($descripcion);?>"/>
        </p>

        <p>
            URL
            <input class="widefat" type="text" name="<?php echo $this->get_field_name('url');?>"
                   value="<?php echo esc_attr($url);?>"/>
        </p>
        <?php
    }

Update

Recordamos que en esta función se hace la actualización de los datos de la instancia.

function update($new_instance, $old_instance) {

        $instance = $old_instance;
        // Con sanitize_text_field elimiamos HTML de los campos
        $instance['titulo'] = sanitize_text_field($new_instance['titulo']);
        $instance['descripcion'] = sanitize_text_field($new_instance['descripcion']);
        $instance['url'] = sanitize_text_field($new_instance['url']);

        return $instance;

    }

Widget

Y por último la función que muestra el Widget en la parte pública.

function widget($args, $instance) {
        // Extraemos los argumentos del area de widgets
        extract($args);

        $titulo = apply_filters('widget_title', $instance['titulo']);
        $descripcion = $instance['descripcion'];
        $url = $instance['url'];

        echo $before_widget;
        echo $before_title;
        echo $titulo;
        echo $after_title;
        echo '<p>'.$descripcion.'</p>';
        echo '<p>'.$url.'</p>';
        echo $after_widget;
    }

¿Y de donde salen variables como $before_widget, $after_widget, $before_title o $after_title? Cuando registramos un área de Widgets son argumentos que podemos pasar. Por ejemplo en el theme Twentytwelve, este es el registro del sidebar principal.

// Main
register_sidebar( array (
	'name'				=> __( 'Main Sidebar','wpex'),
	'id'				=> 'sidebar',
	'description'		=> __( 'Widgets in this area are used in the default sidebar. This sidebar will be used for your standard blog posts.','wpex' ),
	'before_widget'	=> '<div class="sidebar-box %2$s clr">',
	'after_widget'		=> '</div>',
	'before_title'		=> '<'. $wpex_sidebar_headings .' class="widget-title">',
	'after_title'		=> '</'. $wpex_sidebar_headings .'>',
) );

Solamente faltaría una cosa, incluir la clase del Widget y hacer su registro. En functions.php lo incorporaríamos.

require_once(get_template_directory().'/core/ofertas_widget.php');
add_action('widgets_init', 'registra_mis_widgets');
function registra_mis_widgets() {
    register_widget('ofertas_widget');
}

Resultado

Bueno, y tras toda esta ristra de código, pasamos a poner unas imágenes del resultado en el panel de administración:

widget

En la parte pública nos encontraríamos con lo siguiente:

widget_public

Como se puede ver en el Firebug al aside se le aplica la clase CSS que hemos pasado en el constructor (cuando pasamos las opciones), faltaría, claro está, estilizar la clase para que se muestre el Widget de una manera más visual.

Hasta aquí el cómo crear un Widget sencillo. Podemos complicarlo todo lo que queramos, incorporar librerias Javascript, hacer acordeones, tabs, invocar al bucle de WordPress y un sinfín de opciones cuyo límite es nuestra imaginación y un poco de destreza buscando documentación 😉

Espero que os haya resultado interesante la entrada y no se haya hecho muy pesada. Tenéis los comentarios abiertos para cualquier sugerencia o duda.

Gracias por la lectura 🙂

(Visited 9.804 times, 1 visits today)

17 comentarios en “Crear un Widget para WordPress”

  1. Pingback: Vende más. Tripadvisor en tu web - Blog de Juan Ignacio Alberola

    1. Juan Ignacio Alberola Colomo

      Hola Jesus,

      tal como comento en el artículo se debe introducir en el archivo functions.php y crear otro fichero para la clase en PHP que contiene el nuevo Widget. En este caso la tengo dentro de la carpeta core y se llama ofertas_widget.php.

      Un saludo.

  2. Muy buen post, solo me queda una duda, en mi caso necesito que la oferta traiga una imagen,
    ¿Cómo la agregaría en este form de ofertas?

    1. Hola Yeister.

      A ver, creo que te refieres a los iconos a la derecha del menú en la captura que me mandas. Eso tal como me lo muestras no son widgets, son elementos del menú con una clase CSS que le pone el fondo a esos elementos del menú.

      En algunos themes sí que existe un area de Widgets a la derecha del menú pero queda separado del mismo.

      Al final todo se puede solucionar con un poco de PHP y CSS.

      Un saludo!

      1. no me refiero a los iconos del menu eso se como hacerlos como comentas con CSS.

        El problema que tengo es que al desplegar el menu me salga algo asi como ese formulario pequeños para seleccionar de tags para Filtar los post a visualizar dependiendo de los tags seleccionados en el Home de la pagina es para un tema que estoy construyendo y me pidieron hacer algo asi como la imagen que muestro

        De ante mano muchas gracias por responder

  3. Buenas Juan.
    Tengo un problema. He creado tu widget siguiendo tus pasos y he añadido un select para lo que necesito. El problema viene que cuando actualizo, todos los campos se actualizan menos el del select.
    El problema viene en el update pero no se la función exacta para que actualice bien cuando elijo una opción del select.

    1. Juan Ignacio Alberola Colomo

      Hola Jose,

      seguramente el valor si se esté introduciendo correctamente en la base de datos. Probablemente el problema lo tengas en la carga del select en el que tienes que indicar que la opción esté «selected» cuando el valor coincida con el de la base de datos.

      Un saludo.

  4. Joel Elmer Tello

    Se podría publicar mediante un Widget un Mapa interactivo… Lo tengo en código Html y JavaScript… No se si se podría hacer eso

  5. Gracias Juan Ignacio por compartir tus conocimientos.
    En mi caso me gustaría saber como puedo modificar una widget que viene por defecto en wordpress para que sus letras sean más grandes, porque quedan muy pequeñas en el conjunto del diseño de mi web.
    Me refiero en concreto al widget «Categorías». ¿Puedo poner su tipografía más grande y cambiar los colores de las letras o del fondo, sin tener que hacer un widget?
    Gracias por tu respuesta.
    Pedro Alonso.

    Nota: Actualmente mi web está sólo en html e incompleta. La estoy trasladando a wp y por eso esta duda.

    1. Juan Ignacio Alberola Colomo

      Hola Pedro,
      lo que buscas hacer lo podrás hacer sin problema modificando la regla CSS de la hoja de estilos que se esté aplicando al widget en concreto.
      Si tienes dudas házmelo saber por correo con la URL y lo veo.
      Un saludo.

Dejar un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.

Ir arriba

Si continuas utilizando este sitio, aceptas el uso de las cookies. Más información

Las opciones de cookie en este sitio web están configuradas para "permitir cookies" para ofrecerte una mejor experiéncia de navegación. Si sigues utilizando este sitio web sin cambiar tus opciones o haces clic en "Aceptar" estarás consintiendo las cookies de este sitio.

Cerrar