Crear un widget para WordPress desde cero

     

En WordPress un widget personalizado puede ser muy útil, si los widgets que trae wordpress por defecto no cumplen nuestras expectativas. En este tutorial usted aprenderá a crear su propio widget personalizado sin necesidad de Plugins gracias a la API que provee WordPress desde la versión 2.8.

Para este tutorial crearemos un widget de entradas más comentadas con numeración y degradado. Sin embargo siguiendo este ejemplo usted será capaz de crear cualquier widget a medida, veamos la muestra:

Wordpres

Los requisitos.

WordPress 2.8 o superior
Para que un widget pueda funcionar un theme debe estar widgetizado, generalmente la mayoría de themes tienen soporte.
Es necesario que tenga conocimientos en programación php y css de manera básica.

Paso 1

Crear la clase necesaria para generar el widget, esta clase hereda de la clase WP_Widget, se copiarán a functions.php.

class WidgetMasComentadoGradient extends WP_Widget {
 function WidgetMasComentadoGradient() {
 parent::__construct( false, 'Más Comentados Gradient' , array( 'description' => 'Una escalera de posts poulares en degradado'));
 }
 function widget( $args, $instance ) {
 masComentadosGradient($args, $instance);
 }
 function update( $new_instance, $old_instance ) {
 return $new_instance;
 }
function form( $instance ) {
 $title = esc_attr($instance['title']);
 $numero = esc_attr($instance['numero']);
 ?>
 <p>
 <label for="<?php echo $this->get_field_id('title'); ?>">Titulo: </label>
 <input id="<?php echo $this->get_field_id('title'); ?>" class="widefat" name="<?php echo $this->get_field_name('title'); ?>" type="text" value="<?php echo $title; ?>" />
 </p><p>
 <label for="<?php echo $this->get_field_id('numero'); ?>">Cantidad a mostrar: </label>
 <input id="<?php echo $this->get_field_id('numero'); ?>" class="widefat" name="<?php echo $this->get_field_name('numero'); ?>" type="text" value="<?php echo $numero; ?>" />
 </p>
 <?php 
 }
}

Como observarás, el en constructor de la clase se agrega el Titulo y la Descripción del widget, es lo que aparecerá en el panel de widgets de su blog, como la siguiente imagen:
[IMAGEN]
Creamos la función encargada de imprimir el widget , el cual recibe como parámetros los argumentos del widget y las instancias.

function masComentadosGradient($args, $instance){
 extract($args);
 $title = apply_filters( 'widget_title', $instance['title'] );
 $numero = apply_filters( 'widget_title', $instance['numero'] );
 /*Se muestra el título del widget*/
 echo $before_widget;
 if (!empty( $title ))
 echo $before_title . $title . $after_title;
 else
 echo $before_title . 'Más comentados' . $after_title;
?>
<div class="gradient">
 <ul>
 <?php 
 /*Filtro para mostrar los post del ultimo mes*/
 function filter_where( $where = '' ) {
 $where .= " AND post_date > '" . date('Y-m-d', strtotime('-30 days')) . "'";
 return $where;
 }
 $popular = new WP_Query('orderby=comment_count&posts_per_page='.$numero);
 remove_filter( 'posts_where', 'filter_where' );
 $i=1;
 ?>
 <?php while ($popular->have_posts()) : $popular->the_post(); 
 ?>
 <li id="list_<?php echo $i ?>">
<div class="text"> 
 <span class="num"><?php echo $i ?></span>
 <a class="popup_link" href="<?php the_permalink() ?>" rel="bookmark"><?php echo (strlen(get_the_title()) > 90 ? substr(get_the_title(),0,90). '...' : get_the_title() ); ?></a>
 </div>
 </li> 
 <?php 
 $i++; endwhile; ?>
 </ul>
</div>
<?php 
 echo $after_widget; 
}

Paso 3

Añadimos una acción cuando los widgets se inicializan en el panel de administrador con la siguiente función:

function creaWidgets(){
 register_widget( 'WidgetMasComentadoGradient' );
}
add_action( 'widgets_init', 'creaWidgets' );

Paso 4

Ahora hay que aplicarle estilos css para mejorar la apariencia, si desea puede añadir los estilos dentro de la función masComentadosGradient, pero para pruebas añadiremos los estilos al final de style.css del theme actual, luego al final explicaré a poner todo en un solo archivo. Previamente a los estilos , al arrastrar el widget en el sidebar quedaría así de feo.
[IMAGEN]

Entonces es hora de darle efecto, pega el siguiente código en style.css:

.gradient{
background: #fff;
padding-left: 8px;
position: relative;
}
.gradient li{
margin-bottom: 6px;
position: relative;
}
.gradient li a{
display: block;
background: red;
margin-bottom: 6px;
padding: 6px 8px;
height: 40px;
width: 245px;
text-decoration: none;
}
.gradient li a.popup_link{
padding-left: 40px;
color: #fff;
}
.gradient li#list_1 a.popup_link {
 width: 245px;
 background: red;
}
.gradient li#list_2 a.popup_link {
 width: 235px;
 background: #FA2121;
} 
.gradient li#list_3 a.popup_link {
 width: 220px;
 background: #FA4A4A;
} 
.gradient li#list_4 a.popup_link {
 width: 210px;
 background: #FC5C5C;
} 
.gradient li#list_5 a.popup_link {
 width: 195px;
 background: #FD7272;
} 
.gradient li#list_6 a.popup_link {
 width: 180px;
 background: #FC7F7F;
}
.gradient li#list_7 a.popup_link {
 width: 165px;
 background: #FF8E8E;
} 
.gradient li#list_8 a.popup_link {
 width: 150px;
 background: #FF9B9B;
} 
.gradient li#list_9 a.popup_link {
 width: 135px;
 background: #FFA9A9;
} 
.gradient li#list_10 a.popup_link {
 width: 120px;
 background: #FDBDBD;
}
.gradient li a.popup_link:hover{
 background: #FC2D6F !important;
}
.gradient li span.num{
 position: absolute;
 display: block;
 width: 40px;
 height: 40px;
 left: 10px;
 top: 15px;
 font-size: 40px;
 font-weight: bold;
 color: #fff;
}

Realizado esto, su vista tendrá una mejor experiencia, ademas puede modificar los colores del degradado a su gusto.

Paso 5

Como lo dije antes todo el código puede añadirle a functions.php, pero yo recomiendo crear un archivo por separado y luego incluirlo a functions.php, entonces lo haremos así.

Creamos un archivo llamado widget-gradient.php , añadimos todo el código anteriormente explicado y guardamos en el directorio principal del theme que actualmente está usando.

<?php 
function masComentadosGradient($args, $instance){
?>
<style>
.gradient{
background: #fff;
padding-left: 8px;
position: relative;
} 
.gradient li{
margin-bottom: 6px;
position: relative;
} 
.gradient li a{
display: block;
background: red;
margin-bottom: 6px;
padding: 6px 8px;
height: 40px;
width: 245px;
text-decoration: none;
}
.gradient li a.popup_link{
padding-left: 40px;
color: #fff;
}
.gradient li#list_1 a.popup_link {
 width: 245px;
 background: red;
}
.gradient li#list_2 a.popup_link {
 width: 235px;
 background: #FA2121;
} 
.gradient li#list_3 a.popup_link {
 width: 220px;
 background: #FA4A4A;
} 
.gradient li#list_4 a.popup_link {
 width: 210px;
 background: #FC5C5C;
} 
.gradient li#list_5 a.popup_link {
 width: 195px;
 background: #FD7272;
} 
.gradient li#list_6 a.popup_link {
 width: 180px;
 background: #FC7F7F;
}
.gradient li#list_7 a.popup_link {
 width: 165px;
 background: #FF8E8E;
} 
.gradient li#list_8 a.popup_link {
 width: 150px;
 background: #FF9B9B;
} 
.gradient li#list_9 a.popup_link {
 width: 135px;
 background: #FFA9A9;
} 
.gradient li#list_10 a.popup_link {
 width: 120px;
 background: #FDBDBD;
}
.gradient li a.popup_link:hover{
 background: #FC2D6F !important;
}
.gradient li span.num{
 position: absolute;
 display: block;
 width: 40px;
 height: 40px;
 left: 10px;
 top: 15px;
 font-size: 40px;
 font-weight: bold;
 color: #fff;
}
</style>
<?php 
 extract($args);
 $title = apply_filters( 'widget_title', $instance['title'] );
 $numero = apply_filters( 'widget_title', $instance['numero'] );
echo $before_widget;
 if (!empty( $title ))
 echo $before_title . $title . $after_title;
 else
 echo $before_title . 'Más comentados' . $after_title;
?>
<div class="gradient">
<ul>
 <?php 
 /*Filtro para mostrar los post del ultimo mes*/
 function filter_where( $where = '' ) {
 $where .= " AND post_date > '" . date('Y-m-d', strtotime('-30 days')) . "'";
 return $where;
 }
 $popular = new WP_Query('orderby=comment_count&posts_per_page='.$numero);
 remove_filter( 'posts_where', 'filter_where' );
 $i=1;
 ?>
 <?php while ($popular->have_posts()) : $popular->the_post(); 
 ?>
 <li id="list_<?php echo $i ?>">
<div class="text"> 
 <span class="num"><?php echo $i ?></span>
 <a class="popup_link" href="<?php the_permalink() ?>" rel="bookmark"><?php echo (strlen(get_the_title()) > 90 ? substr(get_the_title(),0,90). '...' : get_the_title() ); ?></a>
 </div>
 </li> 
 <?php 
 $i++; endwhile; ?>
 </ul>
</div>
<?php 
 echo $after_widget; 
} //Fin de la funcion
class WidgetMasComentadoGradient extends WP_Widget {
 function WidgetMasComentadoGradient() {
 parent::__construct( false, 'Más Comentados Gradient' , array( 'description' => 'Una escalera de posts poulares en degradado'));
 }
 function widget( $args, $instance ) {
 masComentadosGradient($args, $instance);
 }
 function update( $new_instance, $old_instance ) {
 return $new_instance;
 }
function form( $instance ) {
 $title = esc_attr($instance['title']);
 $numero = esc_attr($instance['numero']);
 ?>
 <p>
 <label for="<?php echo $this->get_field_id('title'); ?>">Titulo: </label>
 <input id="<?php echo $this->get_field_id('title'); ?>" class="widefat" name="<?php echo $this->get_field_name('title'); ?>" type="text" value="<?php echo $title; ?>" />
 </p><p>
 <label for="<?php echo $this->get_field_id('numero'); ?>">Cantidad a mostrar: </label>
 <input id="<?php echo $this->get_field_id('numero'); ?>" class="widefat" name="<?php echo $this->get_field_name('numero'); ?>" type="text" value="<?php echo $numero; ?>" />
 </p>
 <?php 
 }
}

function creaWidgets(){
 register_widget( 'WidgetMasComentadoGradient' );
}
add_action( 'widgets_init', 'creaWidgets' );

Luego incluimos el archivo functions.php, nos dirigimos al final de functions.php y pegamos lo siguiente:

include_once(TEMPLATEPATH.'/widget-gradient.php');

Realizado esto ya tiene su widget disponible, inclusive para utilizarlo en cualquier theme. Cualquier duda estoy atento a sus preguntas por el formulario de comentarios. (Y)

Comentarios

  1. Hola, está muy interesante el post, lo pondré en pràctica. Solo una pregunta, ¿Aunque el archivo con el código lo incluyes en el directorio del theme actual, este seguirá estando disponible para los otros temas?
    Gracias;-)

Deja una respuesta

Tu dirección de correo electrónico no será publicada.

*

*

*