Cómo crear un widget en WordPress

Widgets en WordPressWordPress utiliza muchos “mecanismos” para personalizar nuestro blog y uno de ellos son los widgets. Los widgets generan contenido que se visualiza principalemente en las barras laterales de nuestras plantillas. El core de WordPress viene con varios widgets de fábrica, pero se pueden añadir más, ya sea mediante la instalación de plantillas o de plugins. En este tutorial veremos como crear un widget pesonalizado.

Los widgets generan contenido que se visualiza principalemente en las barras laterales de nuestras plantillas

Widget: Ordenar categorías

Queremos un widget que muestre un listado de categorías con las siguientes características:

  • Podremos ordenar las lista por orden alfabético o por cantidad de entradas de la categoría
  • Podremos cambiar el número de categorías a mostrar
  • Podremos modificar el título del widget

Una vez definido nuestro widget vamos con el código.

La clase WP_Widget

Todos los widget se crean como una clase que hereda de la clase WP_Widget. Nuestro widget se va a llamar Widget_Categories_Order y debe tener cuatro funciones básicas. Éste es el esqueleto de la clase:

class Widget_Categories_Order extends WP_Widget {

    public function __construct() { }

    public function widget( $args, $instance ) { }

    public function form( $instance ) { }

    public function update( $new_instance, $old_instance ) { }

}

Ahora explicamos cada función.

Constructor

El constructor es la función invocada cuando instanciamos una clase. Se puede llamar de dos formas, _construct() o con el nombre de la clase (en nuestro caso Widget_Categories_Order). El constructor del widget necesita llamar al constructor de la clase padre parent::__construct, y éste a su vez necesita tres parámetros:

  • Identificador del widget.
  • Nombre del widget.
  • Opciones. Es un array con dos parámetros: descripción y el nombre de la clase (para estilos CSS)
public function __construct() {

    $widget_ops = array(
        'description' => __( 'Categories in different order', 'DOMAIN' ),
        'classname'   => 'widget_categories_order_class' );

    parent::__construct( 'widget_categories_order', __( 'Categories in Order', 'DOMAIN' ), $widget_ops );

}

Función Form

La función form muestra el formulario del Widget en el panel de administración. El formulario tiene este aspecto:

Form Widget Categories Order

La función form utiliza la variable $instance que es un array con los parámetros de configuración del widget. Éstos parámetros vienen de la base de datos y los usamos en el formulario. Lo vemos en el siguiente código:

public function form( $instance ) {

    $defaults = array(
        'title'        => 'Categories',
        'orderby'  => 'name',
        'number_cat' => '10' );

    $instance = wp_parse_args( (array) $instance, $defaults );
    $title = $instance['title'];
    $orderby = $instance['orderby'];
    $number_cat = $instance['number_cat'];
    ?>
        <p><?php _e( 'Title', 'DOMAIN' ) ?>:
           <input class="widefat"
                name="<?php echo $this->get_field_name( 'title' ); ?>"
                type="text" value="<?php echo esc_attr( $title ); ?>" />
        </p>
        <p><?php _e( 'Order by', 'DOMAIN' ) ?>:
            <select name="<?php echo $this->get_field_name( 'orderby' ); ?>">
                <option value="name" <?php selected( 'name', $orderby ); ?> >
                    <?php _e( 'Name', 'DOMAIN' ) ?></option>
                <option value="count" <?php selected( 'count', $orderby ); ?> >
                    <?php _e( 'Post count ', 'DOMAIN' ) ?></option>
            </select>
        </p>
        <p><?php _e( 'Number of categories to show', 'DOMAIN' ) ?>:
           <input name="<?php echo $this->get_field_name( 'number_cat' ); ?>"
                type="text" value="<?php echo esc_attr( $number_cat ); ?>"
                size="2" maxlength="2" />
        </p>
    <?php
}

Explicamos el código anterior en detalle. Si vemos los requisitos iniciales, el widget necesita tres parámetros de configuración, el título del widget (title), el orden de las categorías (orderby) y el número de categorías a mostrar (number_cat). Así que creamos un array con éstos parámetros y sus valores por defecto.

$defaults = array(
    'title'        => 'Categories',
    'orderby'  => 'name',
    'number_cat' => '10' );  

Después utilizamos la función wp_parse_args. Esta función junta dos arrays, uno con los valores de $instance y otro con los valores por defecto de $default. Si los valores de $instance no existen utiliza los de $default.

$instance = wp_parse_args( (array) $instance, $defaults );  

Por último generamos el formulario html con los valores obtenidos:

<p><?php _e( 'Title', 'DOMAIN' ) ?>:
   <input class="widefat"
        name="<?php echo $this->get_field_name( 'title' ); ?>"
        type="text" value="<?php echo esc_attr( $title ); ?>" />
</p>
<p><?php _e( 'Order by', 'DOMAIN' ) ?>:
    <select name="<?php echo $this->get_field_name( 'orderby' ); ?>">
        <option value="name" <?php selected( 'name', $orderby ); ?> >
            <?php _e( 'Name', 'DOMAIN' ) ?></option>
        <option value="count" <?php selected( 'count', $orderby ); ?> >
            <?php _e( 'Post count ', 'DOMAIN' ) ?></option>
    </select>
</p>
<p><?php _e( 'Number of categories to show', 'DOMAIN' ) ?>:
   <input name="<?php echo $this->get_field_name( 'number_cat' ); ?>"
        type="text" value="<?php echo esc_attr( $number_cat ); ?>"
        size="2" maxlength="2" />
</p>  

Observamos que el parámetro orderby utiliza un selector con dos valores name y count. Podemos ver todos los valores posibles en Codex

Función widget

Esta función genera la vista para los usuarios de la web. Y tiene dos parámetros:

  • $args Que son los parámetros generales del widget.
  • $instance Al igual que en la función form es un array con los parámetros de configuración del widget.

El código de la función, y a continuación, la explicación en detalle:

public function widget( $args, $instance ) {
    extract( $args );

    $title = apply_filters( 'widget_title', $instance['title'] );
    $orderby = $instance['orderby'];
    $number_cat = $instance['number_cat'];

    $order = 'ASC';
    if ( $orderby == 'count' )
        $order = 'DESC';

    $args_list_cat = array(
        'orderby' => $orderby,
        'number'  => $number_cat,
        'order'       => $order,
        'title_li'    => '' );

    echo $before_widget;

    if ( $title )
        echo $before_title . $title . $after_title;
    ?>
        <ul>
    <?php
        wp_list_categories( $args_list_cat );
    ?>
        </ul>
    <?php

    echo $after_widget;
}   

Primero usamos la función extract para convertir todos los elementos del array $args en variables independientes. Éstas variables se usan en todos los widgets ($before_widget, $before_title, etc…). Después recuperamos los parámetros de configuración de nuestro widget.

extract( $args );

$title = apply_filters( 'widget_title', $instance['title'] );
$orderby = $instance['orderby'];
$number_cat = $instance['number_cat'];

Para obtener el listado de categorías usaremos la función wp_list_categories. Esta función recibe un array de parámetros que preparamos con la configuración de nuestro widget. Además le añadimos dos parámetros más:

  • title_li = '': Con este parámetro wp_list_categories genera la lista de categorías sin título.
  • order: Listamos las categorías de forma ascendente (ASC) o descendente (DESC).
$order = 'ASC';
if ( $orderby == 'count' )
    $order = 'DESC';

$args_list_cat = array(
    'orderby' => $orderby,
    'number'  => $number_cat,
    'order'       => $order,
    'title_li'    => '' );   

El resto del código genera el html con el título, la lista de categorías con los parámetros anteriores y el resto de parámetros generales del widget como $before_widget, $before_title, etc…

echo $before_widget;

if ( $title )
    echo $before_title . $title . $after_title;
?>
    <ul>
<?php
    wp_list_categories( $args_list_cat );
?>
    </ul>
<?php

echo $after_widget; 

Función update

Para completar la clase nos queda la función update, que se usa para sanear los valores enviados por el formulario y guardarlos en la base de datos.

public function update( $new_instance, $old_instance ) {
    $instance = $old_instance;
    $instance['title'] = sanitize_text_field( $new_instance['title'] );
    $instance['orderby'] = sanitize_text_field( $new_instance['orderby'] );
    $instance['number_cat'] = absint( $new_instance['number_cat'] );

    return $instance;
}   

Con la función update hemos terminado la clase de nuestro widget, pero ahora debemos decirle a WordPress que queremos usarlo. Para ello registramos el widget con la función register_widget:

add_action( 'widgets_init', 'tuto_register_widgets' );

function tuto_register_widgets(){
    register_widget( 'Widget_Categories_Order' );
}

Con esto el widget queda activo y se puede usar desde el panel de administración. Para más información, podemos recurrir al API de los widget.

Código completo

Todo el código expuesto aquí lo puedes usar directamente en el fichero functions.php de tu plantilla. O mejor aun puedes create un plugin e instalarlo junto con cualquier plantilla. Puedes bajar el código como plugin desde aquí.

Deja un comentario

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