Cómo hacer un plugin de WordPress #2

Como recordarán, en la primera parte del tutorial se explicó la base de un plugin, esta vez veremos como lo podemos potenciar agregando simples configuraciones.

Las configuraciones

Si ya leyeron la primera parte pueden seguir con la segunda parte, en dónde definiremos algunas configuraciones que nuestro plugin debería tener para potenciar su funcionalidad.
Algunas de estas configuraciones serán:

  • Servicio de Placeholder : Será un select (choice) que permitirá seleccionar 1 sitio de servicios de placeholder. Ej. lorempixel, placekitten o placeholdit
  • Tamaño por defecto : Serán dos inputs (text) que por defecto mostrarán 250×250. Esta configuración se utilizará en el momento en que no se entreguen los atributos width y height
  • Texto por defecto : En algunos servicios es posible agregar un texto sobre la imagen, este texto se configurará con un input (text)

Con esto definido podremos crear nuestra pantalla de configuración del plugin utilizando una función nueva

// La función para llamar a las configuraciones
function aPlaceHolderSettings()
{
    // Verificamos si el usuario puede administrar opciones, en caso de que no pueda
    // se envía un mensaje que no tiene los permisos suficientes
    if ( !current_user_can( 'manage_options' ) )  {
        wp_die( __( 'You do not have sufficient permissions to access this page.' ) );
    }

    // Acá se debe incluir el HTML usando la función echo
    echo '';
}

Luego, definiremos aparte como debería lucir el HTML

<div class="wrap">
    <h2>aPlaceHolder Settings</h2>
    <form>
        <label>Servicio de placeholder</label>
        <select>
            <option value="1">Placehold.it</option>
            <option value="2">LoremPixel</option>
            <option value="3">PlaceKitten</option>
        </select>
        <br />
        <label>Tamaño por defecto (width x height)</label>
        <input type="text" value="" placeholder="250"> x <input type="text" value="" placeholder="250">
        <br />
        <label>Texto por defecto</label>
        <input type="text" value="" />
    </form>
 </div>

Todo esto en conjunto generará la interfaz básica de configuración de nuestro plugin. Recuerden que esta función debe ir bajo el código que ya teníamos.

 // Configuraciones
 function aPlaceHolderSettings()
 {
    // Verificamos si el usuario puede administrar opciones, en caso de que no pueda
    // se envía un mensaje que no tiene los permisos suficientes
    if ( !current_user_can( 'manage_options' ) )  {
        wp_die( __( 'You do not have sufficient permissions to access this page.' ) );
    }

    echo '<div class="wrap">
        <h2>aPlaceHolder Settings</h2>
        <form>
            <label>Servicio de placeholder</label>
            <select>
                <option value="1">Placehold.it</option>
                <option value="2">LoremPixel</option>
                <option value="3">PlaceKitten</option>
            </select>
            <br />
            <label>Tamaño por defecto (width x height)</label>
            <input type="text" value="" placeholder="250"> x <input type="text" value="" placeholder="250">
            <br />
            <label>Texto por defecto</label>
            <input type="text" value="" />
        </form>
     </div>';
 }
Menús de Administración

El siguiente paso es aprender cómo agregar nuestra página de configuraciones a un menú del administración. Para lograr esto debemos que tener en cuenta que la opción se puede agregar a cualquier menú principal de WordPress y que, para nuestro caso, usaremos el menú de Ajustes.

Primero debemos crear una función que agrega la página de configuraciones usando la función add_options_page. Con esta función definiremos el nombre del menú, el título, la capacidad, el ID y la función que se utilizará para mostrar la configuración.

 function aPlaceHolderPluginMenu() {
     // Uso de Función : add_options_page( $page_title, $menu_title, $capability, $menu_slug, $function);
     add_options_page( 'aPlaceHolder Settings', 'aPlaceHolder', 'manage_options', 'aplaceholder_settings', 'aPlaceHolderSettings' );
 }

Con esta función ya creada, podremos agregar la opción a nuestro menu de ajustes usando add_action.

add_action( 'admin_menu', 'aPlaceHolderPluginMenu' );

Con estas dos simples acciones ya podremos ver la página de configuración del plugin en el menú de Ajustes.

Y al hacer click sobre ella veremos nuestro hermoso formulario de configuración.

Registrar Configuraciones

Como se habrán dado cuenta, nuestra configuración ya está lista en términos visuales y ahora lo que sigue es guardar estas configuraciones en algún lado. Para hacer esto lo primero que debemos saber es que WordPress cuenta con una función que agrupa las configuraciones y está especialmente pensada para los plugins.

La idea principal es ocupar la función register_setting para definir las configuraciones básicas, luego cuando estas configuraciones están registradas pueden ser utilizadas para ser almacenadas — dentro de la tabla wp_options — y gestionadas por el plugin.

Para registrar las configuraciones crearemos una función que la registre y luego la invocaremos — sí, así como en Naruto — usando la función add_action.

 function aPlaceHolderRegisterSettings()
 {
    register_setting( 'aplaceholder-settings', 'service' );
    register_setting( 'aplaceholder-settings', 'default_size_width' );
    register_setting( 'aplaceholder-settings', 'default_size_height' );
    register_setting( 'aplaceholder-settings', 'default_text' );
 }

Acá estamos definiendo las configuraciones dentro del grupo aplaceholder-settings — nombre elegido para el ejemplo y que es muy descriptivo — y cada opción corresponde a un campo de configuración.
Luego de esto, hacemos la invocación — no necesitaremos un pergamino pero si quieren despertar el Sharingan es cosa de ustedes — de nuestra función.

// Invocación de la función sin sharingan
add_action( 'admin_init', 'aPlaceHolderRegisterSettings');

Cuando actualicen la pantalla no va a pasar nada, pero internamente WordPress dejará el espacio reservado para guardar estos datos.

Guardando Configuraciones

Como ya tenemos nuestro grupo de configuraciones reservado, el siguiente paso es almacenar las configuraciones ahí. Para lograr esto no debemos invocar nada, solo tenemos que hacer unas pequeñas modificaciones al formulario que creamos.

El primer cambio es agregar los atributos necesarios a nuestro formulario a sus campos para que cuando presionemos el botón Guardar — que dicho sea de paso aún no agregamos — los datos sean almacenados donde deben estar. Para esto vamos a ir por parte:

  1. Agregar el atributo action y method al tag "form". El atributo action debe hacer referencia a la página options.php, que es una página interna destinada a almacenar opciones y configuraciones. El atributo method es post porque no queremos que nuestros datos vayan por URL.

    <form action="options.php" method="post">
  2. Agregar el name y el atributo id a cada campo. Tengan en cuenta que los nombres deben ser los mismos que registramos anteriormente.

    <select name="service" id="service">
    
    <input type="text" name="default_size_width" id="default_size_width" value="" placeholder="250">
    
    <input type="text" name="default_size_height" id="default_size_height" value="" placeholder="250">
    
    <input type="text" name="default_text" id="default_text" value="" placeholder="250">
  3. Agregar el for a cada label para que cuando hagamos click en el nombre del atributo éste se seleccione

    <label>Servicio de placeholder for="service"</label>
    
    <label>Tamaño por defecto (width x height) for="default_size_width"</label>
    
    <label>Texto por defecto for="default_text"</label>
  4. Agregar el botón de guardado usando la función submit_button() sobre el cierre de formulario. Ojo al corte que se genera al final del último input y el cierre de formulario

        `';
    submit_button();
    echo '
    ` 
  5. Agregar las funciones de preparación del formulario que lo dejarán listo para almacenar la información. Estas dos funciones son settings_fields y do_settings_sections, se deben utilizar haciendo referencia al grupo de configuraciones que en este caso es aplaceholder-settings

    <form action="options.php" method="post">';
    settings_fields('aplaceholder-settings');
    do_settings_sections('aplaceholder-settings');
    echo '
    <label for="service">Servicio de placeholder</label>

    Ojo de nuevo con el corte de la función echo al final del tag form y al comienzo del tag label.

Con todos estos cambios, nuestro formulario quedará del siguiente modo

    echo '<div class="wrap">
            <h2>aPlaceHolder Settings</h2>
            <form action="options.php" method="post">';
            settings_fields('aplaceholder-settings');
            do_settings_sections('aplaceholder-settings');
    echo '
                <label for="service">Servicio de placeholder</label>
                <select name="service" id="service">
                    <option value="1">Placehold.it</option>
                    <option value="2">LoremPixel</option>
                    <option value="3">PlaceKitten</option>
                </select>
                <br />
                <label for="default_size_width">Tamaño por defecto (width x height)</label>
                <input type="text" name="default_size_width" id="default_size_width" placeholder="250"> x
                <input type="text" name="default_size_height" id="default_size_height" placeholder="250">
                <br />
                <label for="default_text">Texto por defecto</label>
                <input type="text" name="default_text" id="default_text" />';
                submit_button();
    echo '
            </form>
         </div>';

Ahora sí que pueden presionar el lindo botón guardar cambios que aparecerá al actualizar la página.

Y debería aparecer este mensaje de confirmación

Mostrando configuraciones

Como ya estamos guardando las configuraciones el siguiente paso es mostrar los valores en cada campo, como para que el usuario sepa que se están almacenando. Para eso modificaremos de nuevo — sí, de nuevo, lo lamento pero tenemos que ir parte por parte — nuestro formulario agregando el atributo "value" a cada input y haremos algo especial para el select, los valores que mostraremos se obtendrán usando la función get_option.

  1. Agregar el atributo value a las dimensiones por defecto, tanto en height como en width

    <input type="text" name="default_size_width" id="default_size_width" placeholder="250" value="'. get_option('default_size_width') .'">
    
    <input type="text" name="default_size_height" id="default_size_height" placeholder="250" value="'. get_option('default_size_height') .'">
  2. Agregar el atributo value al texto por defecto

    <input type="text" name="default_text" id="default_text" value="'. get_option('default_text') .'" />
  3. Agregar el atributo selected a la opción elegida usando una variable para cada opción. Acá, la lógica busca imprimir la variable después del option, pero solo se mostrará como selected si es que la opción es igual al ID

    <label for="service">Servicio de placeholder</label>';
    
    $option1 = (get_option('service') == 1) ? 'selected' : '';
    $option2 = (get_option('service') == 2) ? 'selected' : '';
    $option3 = (get_option('service') == 3) ? 'selected' : '';
    
    echo '
        <select id="service" name="service">
          <option value="1" '.$option1.'>Placehold.it</option>
          <option value="2" '.$option2.'>LoremPixel</option>
          <option value="3" '.$option3.'>PlaceKitten</option>
        </select>

    Ojo que ésta sería la parte más compleja del tutorial, donde ocupamos variables para imprimirlas entre el HTML y una comparación en línea donde se pregunta el valor de la opción "service" y se define el valor de la variable con el texto "selected" que luego es agregado a la opción correspondiente.

Y con eso, terminamos todos los cambios al formulario, así que el resultado debería ser el siguiente.

echo '<div class="wrap">
    <h2>aPlaceHolder Settings</h2>
    <form action="options.php" method="post">';
    settings_fields('aplaceholder-settings');
    do_settings_sections('aplaceholder-settings');
echo '
            <label for="service">Servicio de placeholder</label>';

$option1 = (get_option('service') == 1) ? 'selected' : '';
$option2 = (get_option('service') == 2) ? 'selected' : '';
$option3 = (get_option('service') == 3) ? 'selected' : '';

echo '
            <select name="service" id="service">
                <option value="1" '.$option1.'>Placehold.it</option>
                <option value="2" '.$option2.'>LoremPixel</option>
                <option value="3" '.$option3.'>PlaceKitten</option>
            </select>
            <br />
            <label for="default_size_width">Tamaño por defecto (width x height)</label>
            <input type="text" name="default_size_width" id="default_size_width" placeholder="250" value="'.get_option('default_size_width').'"> x 
            <input type="text" name="default_size_height" id="default_size_height" placeholder="250" value="'.get_option('default_size_height').'">
            <br />
            <label for="default_text">Texto por defecto</label>
            <input type="text" name="default_text" id="default_text" value="'. get_option('default_text') .'" />';
            submit_button();
echo '
        </form>
     </div>';
Implementando las Configuraciones

El último paso que nos queda es implementar estas configuraciones guardadas en nuestro Widget y que el comportamiento dependa de lo que configuramos. Para esto modificaremos a nuestra función de widget e iremos integrando parte por parte las configuraciones

  1. Definir el texto, ancho y el alto de la imagen según configuraciones o atributos. Haciendo una comparación en línea, primero usamos el atributo si es que existe y sino existe se usa el por defecto.

    function aPlaceHolder($attributes)
    {
        $width  = (isset($attributes['width']))  ? $attributes['width']  : get_option('default_size_width');
        $height = (isset($attributes['height'])) ? $attributes['height'] : get_option('default_size_height');
        $text   = (isset($attributes['text']))   ? $attributes['text']   : get_option('default_text');
  2. Definir la variable $url de acuerdo a la opción elegida. Si es 1 deberá usarse Placehold.it, si es 2 deberá usarse LoremPixel y si no, PlaceKitten. Acá se utilizarán los valores de las variables anteriores para hacer la llamada. El texto se utilizará para placeholdit.

    if (get_option('service') == 1) {
        $url = 'http://placehold.it/'.$width.'x'.$height.'?text='.$text;
    } 
    else if (get_option('service') == 2) {
        $url = 'http://lorempixel.com/g/'.$width.'/'.$height.'/';
    }
    else {
        $url = 'http://placekitten.com/g/'.$width.'/'.$height.'/';
    }
  3. Y finalmente, agregamos la variable $url dentro del resultado

    echo '<img src="'.$url.'" />';

El resultado de todo el código deja la función así

function aPlaceHolder($attributes)
 {
    $width  = (isset($attributes['width']))  ? $attributes['width']  : get_option('default_size_width');
    $height = (isset($attributes['height'])) ? $attributes['height'] : get_option('default_size_height');
    $text   = (isset($attributes['text']))   ? $attributes['text']   : get_option('default_text');

    if (get_option('service') == 1) {
        $url = 'http://placehold.it/'.$width.'x'.$height;
    } 
    else if (get_option('service') == 2) {
        $url = 'http://lorempixel.com/'.$width.'/'.$height.'/';
    }
    else {
        $url = 'http://placekitten.com/g/'.$width.'/'.$height.'/';
    }

    echo '<img src="'.$url.'" />';
 }
La prueba final

Ahora, cuando lo probamos con nuestras configuraciones el resultado se ve así

Y acá aparece el kitten usando el shortcode [aplaceholder]

¡Eso sería todo! En el siguiente y último tutorial vamos a agregar un botón a la barra de herramientas que permita configurar este plugin.

Cualquier consulta sobre códigos PHP y funciones WordPress no duden en hacerlas en los comentarios, Twitter o también por el formulario de contacto.
También pueden descargar la segunda versión del código para que lo vean y prueben apretando el ojo de Kakashi:

¡Descargar!

Blog, Tutorial, Tutorial PHP
11 minutos