3.- Desarrollo de plugins - Dario BF€¦ · dariobf.com ¿Qué es un plugin? Un plugin es un...

Post on 23-Sep-2020

3 views 0 download

Transcript of 3.- Desarrollo de plugins - Dario BF€¦ · dariobf.com ¿Qué es un plugin? Un plugin es un...

dariobf.com

3.- Desarrollo de PluginsArchivos del plugin, Hooks, Shortcodes, Página de opciones del plugin, objeto

$wpdb, Actualización del plugin.

#1

¿Qué es un plugin?¿Y cómo crearlo?

dariobf.com

¿Qué es un plugin?Un plugin es un conjunto de ficheros cuyo fin es añadir funciones extra a WordPress.

Un plugin: • Requiere una cabecera específica, única con información del plugin. • Se guarda en wp-content/plugins (Normalmente en subdirectorio. • Se ejecuta sólo cuando está activado, a través del panel de plugins • Aplica sus funciones a todos los temas. • Debe tener un propósito; por ejemplo: convertir artículos en páginas,

ofrecer mejoras de posicionamiento o ayudar con los backups.

dariobf.com

index.php

¿Cómo es un plugin?

dariobf.com

Cabecera del plugin• Plugin name. • Plugin URI. • Description. • Author. • Author URI. • Version. • Domain Path. • Network. • Text domain.

dariobf.com

<?php/** * Plugin Name: Name of the plugin, must be unique. * Plugin URI: http://URI_Of_Page_Describing_Plugin_and_Updates * Description: A brief description of the plugin. * Version: The plugin's version number. Example: 1.0.0 * Author: Name of the plugin author * Author URI: http://URI_Of_The_Plugin_Author * Text Domain: Optional. Plugin's text domain for localization. Example: mytextdomain * Domain Path: Optional. Plugin's relative directory path to .mo files. Example: /locale/ * Network: Optional. Whether the plugin can only be activated network wide. Example: true * License: A short license name. Example: GPL2 */

Cabecera del plugin

#2

Los HooksGanchos

dariobf.com

¿Qué son los ganchos?

dariobf.com

¿Qué son los ganchos?

Técnicamente son eventos.

Por ejemplo, invocado por la llamada de do_action() o apply_filters() que desencadena después todas las funciones de filtro de acción previamente enganchados a ese evento.

dariobf.com

¿Qué son los ganchos?

En esencia, el gancho o evento invoca un Observer, que recoge una serie de funciones "enganchadas" y los llama usando la función call_user_func() de PHP; permitiendo que el código y operaciones sean implementadas en el proceso del core sin modificar el código de este.

dariobf.com

¿Qué son los ganchos?

Como los “Actions” y “Filters” requieren del uso de Hooks, es posible que escuches hablar con frecuencia de “Action hooks” y “filter hooks”.

dariobf.com

No le tengas miedo a los hooks

dariobf.com

El Hook se ejecuta

¿Cómo funcionan?La llamada al servidor inicia el index.php, que ejecuta código del core. El código del core invoca al método do_action().

» » Vuelve a ejecutar el código del core.

dariobf.com

Ejemplo de Hook<?phpadd_filter(‘the_content’, ‘my_function’);

function my_function($content) {return $content . ‘<p>¡Compártelo con un amigo!</p>’;

}?>

Este código es un “Filter hook” sencillo que añade el texto “¡Comparte con un amigo!” después del contenido de cada entrada o página.

dariobf.com

CuidadínTu función se integrará con el core de WordPress. Hay que tener cuidado con los nombres que utilizamos. Aquí te dejo algunos nombres reservados.

• start_process() • output() • modify_content() • pluginname_process() • pluginname_output() • pluginname_modify_content()

dariobf.com

Naming de funciones<?phpadd_filter(‘the_content’, ‘_trackableshare_process’);

function _trackableshare_process($content) {/* whatever */

}?>

En el ejemplo, nuestro plugin llamado Trackable Social Share Icons. Recomendado empezar sus funciones con el prefijo “_trackableshare_”

Evitar confusiones con otros plugins.

dariobf.com

Naming de funciones

Si estás utilizando Programación Orientada a Objetos, o construyendo tu plugin como una clase puedes evitar los consejos anteriores, ya que tus métodos estarán separados de la función del plugin (o en otra dimensión).

Sin embargo, todavía tienes que asegurarte de que el nombre de tu clase (o de su área de trabajo) es único

dariobf.com

Ejemplo de plugin OOP<?php

class trackable_social_share{public function __construct() {// Add Hooksadd_filter('the_content', array($this, 'process'));

}public function process($content) {/* ... */

}

}

$trackable_social_share = new trackable_social_share();

?>

Esto es más complicado, es sólo un ejemplo de cómo sería.

dariobf.com

Resumen

•  Un Hook es un evento que llama a una función o método en una acción.

•  Tu código es integrado en el core de WordPress dinámicamente, pasando a ser parte de él.

•  Nos referimos con frecuencia a los hooks como “Action hooks” y “Filter hooks”

•  Puedes utilizar tanto código tradicional como Orientado a Objetos con hooks.

•  Recuerda que el naming de las funciones es clave.

#3

Los Filter Hooks

dariobf.com

Filter HooksEl Filter Hook está diseñado para modificar contenido.

En lugar de ser invocado en una acción específica, el Filter Hook es invocado cuando se procesa el contenido; ya sea cuando se guarda o cuando se representa.

En los ejemplos anteriores se utilizó el Filter Hook para añadir contenido al contenido de nuestra entrada o página. Este es un perfecto ejemplo de cómo funciona este gancho.

También podemos manipular el contenido mediante otras funciones PHP.

dariobf.com

Ejemplo de manipulación de contenido

<?php

add_filter('the_content', ‘guorpres_vs_wordpress’); function guorpres_vs_wordpress($content) { return str_replace('wordpress', 'WordPress', $content);

} ?>

Reemplazamos los wordpress mal escritos por WordPress.

dariobf.com

Consejo: Filter Hooks

<?php

add_shortcode('pirate', 'ninja_function');function ninja_function() {

return ‘ninja’;}

?>

No utilices Filter Hooks para el uso de shortcodes.

Puedes utilizar str_replace, pero WordPress tiene su propia función sólo para shortcodes: add_shortcode()

dariobf.com

Filter Hooks

Los filtros pueden ser utilizados múltiples veces y en múltiples tipos de contenido.

Pueden modificar el contenido antes de guardarlo en la base de datos, o más adelante; durante la fase de renderizado.

También puedes modificar el autor, comentarios, widgets, enlaces, blogroll, fechas y horas, elementos del escritorio, etc, todo de forma dinámica sin tener que modificar el código del núcleo de WordPress.

https://codex.wordpress.org/Plugin_API/Filter_Reference

dariobf.com

Filtro pre-guardado comentarios

<?php

add_filter('comment_status_pre ', 'pluginname_malwordpress'); function pluginname_malwordpress($content) { $badwords = array('wordpress', 'Wordpress', 'güorpress', 'wordPress', 'hook'); return str_replace($badwords, 'WordPress', $content);

}

Reemplazamos los wordpress mal escritos por WordPress.

dariobf.com

Añadiendo Filter Hooks

<?php

add_filter($tag, $function, [$priority],[$accepted_args]); ?>

Todos se añaden utilizando la función add_filter()

Tag: (string) A qué tipo de proceso de contenido debe ser aplicado el filtro

Function: (callback) La función a ejecutar

Priority: (int) – opcional Orden en el que debe ser ejecutado. A número más bajo antes se ejecutará. Por defecto 10.

Accepted Args: (int) – opcional Número de argumentos aceptados cuando utilizamos apply_filters() (WP >= 1.5.1). Por defecto 1.

dariobf.com

Pregunta 1<?php

add_filter('the_content', ‘regla_poni');add_filter('the_content', ‘regla_caballo', 9);add_filter('the_content', ‘regla_batman', 8);function regla_poni($content) {return str_replace(‘mi animalito', ‘Ponis!’, $content);

}function regla_caballo($content) {return str_replace(‘mi animalito', ‘Caballitos!', $content);

}

function regla_batman($content) {return str_replace(‘mi animalito', ‘NANANA BATMAN!!’, $content);

}

?>

Si nuestro contenido es sólo “mi animalito”, ¿qué imprimirá?

dariobf.com

Resultado

La respuesta es “NANANA BATMAN!!”, porque tiene la prioridad más alta (número más bajo).

Estamos utilizando un str_replace(), reemplazará el texto “mi animalito” por “NANANA BATMAN!!” ignorando las funciones anteriores.

dariobf.com

Pregunta 2<?php

add_filter('the_content', ‘regla_poni');add_filter('the_content', ‘regla_caballo', 9);add_filter('the_content', ‘regla_batman', 8);function regla_poni($content) {return ‘Ponis!’;

}function regla_caballo($content) {return ‘Caballitos!’;

}

function regla_batman($content) {return ‘NANANA BATMAN!!’;

}

?>

Si nuestro contenido es sólo “mi animalito”, ¿qué imprimirá?

dariobf.com

Resultado

La respuesta es “Ponis!”. Tiene la prioridad más baja.

Ahora, no estamos reemplazando un trozo del texto, estamos reemplazando TODO el contenido.

Primero lo reemplazamos por “NANANA BATMAN!!”, después lo reemplazamos por “Caballitos!” y, por último, por “Ponis!”.

#4

Los Action Hooks

dariobf.com

Action Hooks

El Action Hook se invoca en WordPress cuando una acción tiene lugar, como cargar una página (front-end o wp-admin), se inserta un comentario, se guarda un artículo o incluso cuando cambiamos el tema.

dariobf.com

Action Hooks

Por ejemplo, un Action Hook puede ser invocado cuando cargamos el header, footer o el escritorio de administración.

Así mismo, cuando creamos un artículo, el Action Hook admin_init es invocado, y cuando lo guardamos es invocado el save_post.

dariobf.com

Action Hooks

El Action Hook está diseñado para proporcionar una mayor flexibilidad en cómo se procesan los elementos, así como la posibilidad de añadir funciones adicionales al sistema WordPress (tales como campos de texto adicionales al crear o editar una entrada), la adición de JavaScript / hojas de estilo, y otros artículos.

dariobf.com

Ejemplo de Action Hook

<?phpadd_action(‘admin_menu', ‘mi_plugin_extraordinario’);function mi_plugin_extraordinario() {

if(function_exists('add_submenu_page')) {add_submenu_page(‘plugins.php','Extraordinario', ‘Extraordinario’, 10, ‘my_new_plugin', 'my_new_plugin_admin_page_function');

}}

?>

¿Qué hace mi plugin?

dariobf.com

Resultado

El Action: Obtiene el menú de administración.

La petición: Cuando estés generando el Menú de administración, ejecuta esta función que añade un elemento bajo la sección de plugins.

El Resultado: El menú es generado con nuestro enlace, justo debajo de la sección de plugins.

dariobf.com

Añadiendo Action Hooks

<?php

add_action($tag, $function, [$priority],[$accepted_args]); ?>

Todos se añaden utilizando la función add_action()

Tag: (string) A qué tipo de proceso de contenido debe ser aplicado el filtro

Function: (callback) La función a ejecutar

Priority: (int) – opcional Orden en el que debe ser ejecutado. A número más bajo antes se ejecutará. Por defecto 10.

Accepted Args: (int) – opcional Número de argumentos aceptados cuando utilizamos apply_filters() (WP >= 1.5.1). Por defecto 1.

dariobf.com

Resumen

Filter Hooks

Modifican contenido.

Se crean con add_filter().

Es importante la prioridad. Recuerda que un número más bajo significa más prioridad.

Action Hooks

Añaden o eliminan código en una acción concreta.

Se crean con add_action().

#5

Advanced Hooking

dariobf.com

Advanced Hooking

WordPress integra algunas funciones para determinar las funciones que han sido enganchadas a un filtro, si el hook ya ha sido invocado, eliminando funciones de hooks e incluso eliminando todas las llamadas a funciones de un hook.

dariobf.com

Funciones basadas en un Action

has_action(‘hook’, ‘function’);

did_action(‘hook’);

remove_action(‘hook’, ’function’);

remove_all_actions(‘hook’);

dariobf.com

Funciones basadas en un Filter

has_filter(‘hook’, ‘function’);

did_filter(‘hook’);

current_filter();

remove_filter(‘hook’, ’function’);

remove_all_filters(‘hook’);

dariobf.com

has_*

Las funciones has_action() y has_filter() detectan cuando (o cuando no) se ha añadido una función al array de hooks para un evento determinado.

Esto retornará verdadero o falso.

dariobf.com

did_*

Las funciones did_action() y did_filter() detectan cuando (o cuando no) se ha invocado un evento. Si tu evento no ha sido enganchado al hook, pero el evento se ha invocado retornará true.

Esto retornará verdadero o falso.

dariobf.com

current_filter

La función current_filter() retorna si el evento actual ha sido procesado. Por ejemplo, si el hook invocado es “the_content”, esta función retornará “the_content”.

Es muy útil cuando utilizamos una función o método para manejar varios tipos de filtros.

dariobf.com

remove_*

Las funciones remove_action() y remove_filter() eliminará una función específica de un hook determinado.

Es útil si quieres evitar que una función sea llamada cuando suceda el evento.

dariobf.com

remove_all_*

Las funciones remove_all_actions() y remove_all_filters() eliminará todas las funciones específica de un hook.

Esta función recibe el nombre del hook como primer parámetro y acepta un segundo (opcional) que es la prioridad.

Por ejemplo, si quieres eliminar todas las funciones de “the_content” con prioridad 4: remove_all_filters(‘the_content”, 4);

dariobf.com

Creando Hooks personalizados

Podemos definir Hooks personalizados en nuestro plugin o tema que pueden ser enganchados dentro de otros plugins utilizando la función do_action() y apply_filters().

do_action(‘hook_name’);apply_filters(‘hook_name’, $content);

‘hook_name’ es el nombre que le damos a nuestro nuevo Hook y como nos referiremos a él.

dariobf.com

Ejemplo de Hook personalizado

<?php

function my_plugin_function() {// Allow hooks into this functiondo_action('my_plugin_init');// Create Content$content = 'Hello world';// Allow Content to have filters ran against it// Be sure to store the returned result of the FILTER!!!$content = apply_filters('my_plugin_content', $content);

}

?>

dariobf.com

Resumen

WordPress nos facilita varias funciones que pueden ser utilizadas para modificar Hooks incluso después de haber utilizado las funciones add_filter() o add_action().

También nos facilita crear nuestros propios Hooks en nuestro tema o plugin.

dariobf.com

Utiliza el Codex

Hemos visto mucha información sobre los Hooks de WordPress, pero hay mucha más disponible en el Codex, incluyendo los tipos de parámetros que algunos Hooks enviarán a tus funciones cuando el evento es invocado.

Todo sobre Filter Hooks: http://codex.wordpress.org/Plugin_API/Filter_Reference

Todo sobre Action Hooks: http://codex.wordpress.org/Plugin_API/Action_Reference

#6

Shortcodes

dariobf.com

Shortcodes

• El uso es muy simple: [recent-posts]

• Y pueden recibir parámetros: [recent-posts posts=“5”]

• Y, además, pueden recibir más contenido:

[recent-posts posts=“5”]Cabecera de los últimos posts[/shortcode]

Shortcode simple<?php

function recent_posts_function() {

query_posts(array('orderby' => 'date', 'order' => 'DESC' , 'showposts' => 1));

if (have_posts()) :

while (have_posts()) : the_post();

$return_string = '<a href="'.get_permalink().'">'.get_the_title().'</a>';

endwhile;

endif;

wp_reset_query();

return $return_string;

}

function register_shortcodes(){

add_shortcode('recent-posts', 'recent_posts_function');

}

add_action( 'init', 'register_shortcodes');

?>

[recent-posts]

Shortcode avanzadofunction recent_posts_function($atts){

extract(shortcode_atts(array(

'posts' => 1,

), $atts));

$return_string = '<ul>';

query_posts(array('orderby' => 'date', 'order' => 'DESC' , 'showposts' => $posts));

if (have_posts()) :

while (have_posts()) : the_post();

$return_string .= '<li><a href="'.get_permalink().'">'.get_the_title().'</a></li>';

endwhile;

endif;

$return_string .= '</ul>';

wp_reset_query();

return $return_string;

}

[recent-posts posts=“5”]

Shortcode avanzado 2function recent_posts_function($atts, $content = null) {

extract(shortcode_atts(array(

'posts' => 1,

), $atts));

$return_string = '<h3>'.$content.'</h3>';

$return_string .= '<ul>';

query_posts(array('orderby' => 'date', 'order' => 'DESC' , 'showposts' => $posts));

if (have_posts()) :

while (have_posts()) : the_post();

$return_string .= '<li><a href="'.get_permalink().'">'.get_the_title().'</a></li>';

endwhile;

endif;

$return_string .= '</ul>';

wp_reset_query();

return $return_string;

}

[recent-posts posts=“5”]Cabecera de los últimos posts[/shortcode]

dariobf.com

Habilitar shortcodes

<?phpadd_filter('widget_text', ‘do_shortcode');add_filter( 'comment_text', 'do_shortcode' );add_filter( 'the_excerpt', 'do_shortcode');

?>

dariobf.com

Shortcodes útiles

<?phpfunction linkbutton_function( $atts, $content = null ) {

return '<button type="button">'.do_shortcode($content).'</button>';

}

add_shortcode('linkbutton', 'linkbutton_function');

?>

[linkbutton]¡Soy un botón![/linkbutton]

function menu_function($atts, $content = null) {

extract(

shortcode_atts(

array( 'name' => null, ),

$atts

)

);

return wp_nav_menu(

array(

'menu' => $name,

'echo' => false

)

);

}

add_shortcode('menu', 'menu_function');?>

[menu name=“main-menu”]

function googlemap_function($atts, $content = null) {

extract(shortcode_atts(array(

"width" => '640',

"height" => '480',

"src" => ''

), $atts));

return '<iframe width="'.$width.'" height="'.$height.'" src="'.$src.'&output=embed" ></iframe>';

}

add_shortcode("googlemap", “googlemap_function");

[googlemap width="600" height="300" src="http://maps.google.com/maps?q=Heraklion,+Greece&hl=en&ll=35.327451,25.140495&spn=0.233326,0.445976& sll=37.0625,-95.677068&sspn=57.161276,114.169922& oq=Heraklion&hnear=Heraklion,+Greece&t=h&z=12"]

function pdf_function($attr, $url) {

extract(shortcode_atts(array(

'width' => '640',

'height' => '480'

), $attr));

return '<iframe src="http://docs.google.com/viewer?url=' . $url . '&embedded=true" style="width:' .$width. '; height:' .$height. ';">Your browser does not support iframes</iframe>';

}

add_shortcode('pdf', ‘pdf_function');

[pdf width="520px" height=“700px”]AQUI LA URL DEL PDF[/pdf]

#7

Pantalla de configuración

dariobf.com

Pantalla de configuración

<?phpadd_menu_page($page_title, $menu_title, $capability, $menu_slug, $function, $icon_url, $position);

?>

$page_title - (string) (required) El texto que se mostrará en la etiqueta <title> cuando el menú está seleccionado.

$menu_title - (string) (required) El nombre del menú (Label).

$capability - (string) (required) El nivel de permisos necesarios para mostrar el menú a un usuario.

$menu_slug - (string) (required) El slug con el que nos referiremos a este menú (debe ser único).

dariobf.com

Pantalla de configuración

<?php

add_action('admin_menu', 'test_plugin_setup_menu');

function test_plugin_setup_menu(){

add_menu_page( 'Test Plugin Page', 'Test Plugin', 'manage_options', 'test-plugin', 'test_init' );

}

function test_init(){

echo "<h1>Hello World!</h1>";

}

?>

http://www.1stwebdesigner.com/wordpress-plugin-development-settings-page/

#8

Interactuando con la base de datos

dariobf.com

$wpdb

WordPress define una clase llamada wpdb, que contiene una serie de funciones utilizadas para interactuar con la base de datos. El objetivo principal es proporcionar una interfaz con la base de datos, pero se puede utilizar para comunicarse con otra base de datos cualquiera.

dariobf.com

<?php

// set the meta_key to the appropriate custom field meta key

$meta_key = 'miles';

$allmiles = $wpdb->get_var( $wpdb->prepare(

"

SELECT sum(meta_value)

FROM $wpdb->postmeta

WHERE meta_key = %s

",

$meta_key

) );

echo "<p>Total miles is {$allmiles}</p>";

?>

https://codex.wordpress.org/Class_Reference/wpdb

#9

WP_Cron

dariobf.com

WP_CronCuando vemos la palabra cron, nos imaginamos tareas programadas a una hora concreta para ejecutarse durante intervalos específicos.

Al contrario, WP-Cron no es lo mismo que el cron de Unix.

La gran diferencia está en su ejecución: WP_Cron se ejecuta cuando un visitante abre tu sitio WordPress. Es decir, su ejecución es imprecisa.

Como ejemplo, haremos un cron que cuente los suscriptores de nuestro canal RSS mediante feedburner.

dariobf.com

WP_CronPara entender bien WP_Cron es importante tener localizado el catálogo de sus funciones: http://codex.wordpress.org/Category:WP-Cron_Functions

Para nuestro propósito (contar los seguidores de feedburner) no tiene sentido hacerlo en cada carga de página en WordPress.

Para ello utilizaremos la función wp_schedule_event(), que recibe estos parámetros:

• Hora: Hora en formato Unix especificando cuándo se invoca.

• Recurrencia: Con qué frecuencia debe ser re-invocado después del tiempo programado.

• Hook: El Hook que utilizaremos para añadir la funcionalidad cuando sea invocado.

• Args: (opcional) Los argumentos a pasar (en array) para pasarle a las funciones enganchadas al hook.

dariobf.com

WP_Cron

Nuestro evento se invocará cuando la hora actual coincida o sobrepase la que le pasamos a esta función, marcada por un futuro visitante de nuestro sitio.

Será re-invocada basándonos en el parámetro de recurrencia, que puede ser definido como “hourly”, “twicedaily”, “daily” o “none”. También podemos definir nuestros propios parámetros de recurrencia.

Para ejecutar algo en nuestro evento, utilizamos un hook.

dariobf.com

WP_CronComo feedburner se actualiza diariamente, nuestra programación será diaria (daily).

<?phpwp_schedule_event( time(), 'daily', 'feedburner_refresh' );

?>

Si te das cuenta, la hora de ejecución es time(); esto significa que en cuanto el plugin esté activo se ejecutará y lo hará cada día a la misma hora.

Además, si colocamos esto en nuestro functions.php ejecutará esta acción en cada carga de página del sitio; no es lo que queremos.

Programado

dariobf.com

WP_CronLa forma sencilla de evitar esto, es hacer la comprobación siguiente:

<?phpif( !wp_next_scheduled( 'feedburner_refresh' ) ) { wp_schedule_event( time(), 'daily', 'feedburner_refresh' );}

?>

Esta función wp_next_scheduled() retornará falso si el evento no está programado para invocarse en el futuro o la hora no cumple.

Programado

dariobf.com

WP_CronSi necesitamos desprogramar un evento, es tan sencillo como utilizar la función wp_unschedule_event(), que requiere los mismos parámetros que wp_schedule_event().

Hay que tener en cuenta que el parámetro “time” será el del próximo evento a invocar (de nuestro programado); esto lo obtendremos con wp_next_scheduled().

<?phpif( false !== ($time = wp_next_scheduled('feedburner_refresh'))) { wp_unschedule_event( $time, 'feedburner_refresh' );}

?>

Desprogramado

dariobf.com

WP_Cron

También podemos desprogramarlo limpiando el hook al que hacemos referencia en nuestro programado:

<?phpwp_clear_scheduled_hook( 'feedburner_refresh' );

?>

Desprogramado

dariobf.com

WP_Cron

Ahora que ya tenemos programado nuestro evento, sólo falta definir qué queremos hacer con él.

<?phpadd_action( 'feedburner_refresh', 'update_rss_subscriber_count' );

?>

Ejecutando

En la función update_rss_subscriber_count() definiremos qué hace nuestro plugin; en este caso conectarse al API de Feedburner y obtener los seguidores. Sólo nos quedará guardarlo con update_option(‘subscriber_count’) y donde queramos ver ese dato utilizar get_option( 'subscriber_count' );

#10

Widgets

dariobf.com

Definir barra lateralEn el functions.php:

register_sidebars( $count, $args );

Con $args controlamos lo siguiente:

'before_widget' => '<li id="%1$s" class="widget %2$s">','after_widget' => "</li>n",'before_title' => '<h2 class="widgettitle">','after_title' => "</h2>"

dariobf.com

Mostrar barra lateralEn nuestra plantilla:

dynamic_sidebar($sidebar);

Forma más correcta:

<ul id="sidebar"><?php if ( !function_exists('dynamic_sidebar') || !dynamic_sidebar() ) : ?>

<li>{static sidebar item 1}</li><li>{static sidebar item 2}</li>

<?php endif; ?></ul>

dariobf.com

Ideas para Widgets• Crear un widget que diferencie tu tema de alguna manera.

• Registrar un widget para reemplazar a uno original y modificarlo de alguna manera.

• Recuerde que un "widget" realmente no es más que un nombre para un código configurable. Puede ser invisible o posicionarse de forma absoluta; horizontalmente o verticalmente.

• Utilice los atributos de clase y el id de uno o todos los widgets en los scripts para animar su barra lateral.

• Puedes utilizar jQuery (incluido con WordPress) para hacer sus widgets arrastrables o replegables...