Widgets de WordPress

Este post resume mi lectura acerca de widgets de wordpress de automattic.com creadores de los mismos. Un widget de wordpress es un trozo pluggleable (que se puede conectar) para un sidebar. A partir de la versión 2.2, el plugin de widget forma parte del core de wordpress.

Tener habilitado wordpress para soportar widgets no es suficiente, se necesia que los temas estén habilitados para utilizarlo, en el artículo “widgetizing themes” hay un tutorial que indica como hacerlo.

Los widget de wordpress como se dijo anteriormente, se usan en los sidebar, lo primero que debemos hacer es identificar como está implementado nuestro sidebar y como está dividida cada sección. En la mayoría de los casos en los temas que nos encontramos en internet, estos widget están implemementados en listas no ordenadas html, esta estructura puede ser fácilmente adaptada via hojas de estilo en cascada (css) para lograr direntes tipos de efectos.

Para hacer un tema conciente de los widget, basta con agregar en la parte de código que genera el sidebar lo siguiente.

<?php if ( !function_exists('dynamic_sidebar')|| !dynamic_sidebar() ) : ?>
 <!-- codigo sidebar estático-->
<?php endif; ?>

La instrucción dynamic_sidebar() esta disponible en wordpress habilitados con widget y permite que el plugin de widgets fije dinámicamente el contenido del sidebar.

El siguiente paso es registrar el sidebar (Wodpress version 2.0 o superior) para ello, edite el ficher function.php (o creelo si no está) y agrege:

<?php
if ( function_exists('register_sidebar') )
    register_sidebar();
?>

Esto permitirá al plugin conocer que su tema necesita exactamente un sidebar y agregará en la parte administrativa presentación de wordpress un botón widget que le permitirá configurar dinámicamente su barra lateral de manera gráfica usando drag & drop.

El plugin de widget soporta además otras formas de sidebar y permite configurar el contenedor del título y del widget, para personalizar las salidas de los widget, usamos una versión extendida de register_sidebar.

<?php

if ( function_exists('register_sidebar') )
    register_sidebar(array(
        'before_widget' => '',
        'after_widget' => '',
        'before_title' => '<div class="title">',
        'after_title' => '</div>',
    ));
?>

La estructura de before_widget es un poco más compleja, el valor por defecto es incluye las directivas %1$s y %2$s que corresponden al id y a la clase respectivamente (El ID debe ser único en todo el documento html). De esta forma, el registro del sidebar sería:

if ( function_exists('register_sidebar') )

    register_sidebar(array(

    'before_widget' => '<div id="%1$s" class="widget %2$s">',

    'after_widget' => '</div>',

    'before_title' => '<div class="title">',

    'after_title' => '</div>',

    ));

?>

Para registrar varios sidebars use register_sidebars(n) y en el sidebar indique el sidebarque desea usar en la instrucción dynamic_sidebar(Número Sidebar).

Finalmente, para implementar nuestros propios widgets, creamos una función en el tema y la registramos como widget.

function widget_mytheme_search() {
?>
    << PASTE YOUR SEARCH FORM HERE >>
<?php
}
if ( function_exists('register_sidebar_widget') )
register_sidebar_widget(__('Search'), 'widget_mytheme_search');

Para más información sobre como hacer widgets puede leer el documento How I do Develop a Widget. Yo luego estaré escribiendo algo del tema, ahora me voy a jugar un rato con mi temas para widgetizarlos… que termino más raro. :-).

WordPress 2.2.1 Nueva Version (Stan Getz)

Hace apenas 8 dias wordpress sacó su nueva version, la 2.2.1 yo seguia aún con la 2.1.3 y me ha cogido por sorpresa, pero hoy me dispongo a instalarla. Ojalá no tome más del tiempo necesario. Esta nueva versión no solo corrige un montón de bugs, sinó que mejora su seguridad

Inicio bajando el .zip con el código fuente, lo descomprimo, saco un backup de la base de datos, y saco un backup de las fuentes de mi portal anterior para ahorrar tiempo. Incluyendo plugins, imágenes y todo wordpress. Como dato curioso, a los desarrolladores de wordpress les gusta el jazz y a sus versiones principales les ponen un nombre de un músico de jazz, el nombre de la versión 2.2 es Stan Getz

Según los pasos de wordpress, es importante eliminar los ficheros antiguos de wordpress cuando se actualiza desde las versiones 2.0.*, 2.1.* o 2.2, el procedimiento está en este enlace. Básicamente guardar ficheros de configuración (wp-config.php, .htaccess, .htpasswd), el contenido, los plugins, no borrar readme.html, wp.php, xmlrpc.php, and license.txt. Igualmente guardar cualquier fichero de wordpress que se haya modificado.

Desactivo los plugins que tenia activos, y por último, ejecuto es script de actualización que está en wp-admin/upgrade.php. y Voala…. en 2 segundos… funcionando el portal…. 15 minutos desde que inició el proceso.
Es simple y sencillo, ahora a ver que ha cambiado para el desarrollo de los plugins :-). Y a jugar con el tema de widgets que creo que le da una potencialidad muy alta a WordPress y a cualquier gestor de contenido.

Widgets

Un widget es conocido en otros entornos como Gadgets, Gizmos o Wizbangs y permite personalizar un blog basado en wordpress sin tener ningún conocimiento de html y usando mecanismos de drag and drop.

Este mismo concepto es usado en muchos otros entornos para referise a trozos de software que implementan funcionalidades frecuentemente y que ofrecen información visual. En Wikipedia hay un artículo donde se puede conocer más de este tema, yo referencio el primer párrafo.

”En informática, un widget es una pequeña aplicación o programa, usualmente presentado en archivos o ficheros pequeños que son ejecutados por un motor de widgets o Widget Engine. Entre sus objetivos están los de dar fácil acceso a funciones frecuentemente usadas y proveer de información visual. Sin embargo los widgets pueden hacer todo lo que la imaginación desee e interactuar con servicios e información distribuida en Internet; pueden ser vistosos relojes en pantalla, notas, calculadoras, calendarios, agendas, juegos, ventanas con información del clima en su ciudad, etcétera.”

Los widget en general pueden ser programados en diferentes lenguajes, en particular para internet se pueden programar en javascript, como componentes basados en flash u otros.

Aplicaciones como meebo, adSense u otros ofrecen trozos de código que permiten desplegar contenido. Portales como widgetbox se pueden descargar cientos de widget para utilizar en las páginas web, wikies, blogs, etc. Y los nuevos “Desktop” virtuales o “págians personalizadas” como iGoogle se basan en el uso de widget que permiten al usuario configurar lo que quiere ver en su página personal y como lo quiere ver. O los widget para los servicios de mensajería como yahoo o msn live que permiten agregar funcionalidades de terceros a estas aplicaciones.

El siguiente código es un ejemplo de widget de meebo

<!-- Beginning of meebo me widget code.
Want to talk with visitors on your page?
Go to http://www.meebome.com/ and get your widget! -->
<embed src="http://widget.meebo.com/mm.swf?luSGZzLDaL" type="application/x-shockwave-flash" wmode="transparent" width="160" height="250"></embed>

El siguiente es un ejemplo de código de un widget de un reloj:

<script src="http://www.clock-desktop.com/js/embed.js"></script>
<script type="text/javascript" language="JavaScript">obj=new Object;
obj.clockfile="http://www.clock-desktop.com/js-clock/cowboy.7art";
obj.width=152;obj.height=112;obj.wmode="transparent";showClock(obj);</script>

Con solo copiar este código dentro de nuestra página web, o incorporandolo dentro de la semántica de un wiki (Ej en dokiwiki, se coloca dentro de las etiquetas <html>codigo widget</html>) , o dentro de un sidebar de un blog.

En algunos casos, y dependiendo del tipo de widget, un widget puede causar retardos en la carga de una página.

Nota sobre Informe Euroblog 2007

Euroblog 2007, un simposio celebrado en marzo de 2007 presentó los resultados de una encuesta realizada acerca de la evolución de uso de las tecnologías de software social y blogs realizada entre profesionales de relaciones publicas entre noviembre y diciembre de 2006 con participación de 24 paises Europeos.

Los resultados muestran el crecimiento y mayor importancia que está ganando esta corriente en todos los ámbitos y como cada dia, el uso de blogs y otras tecnologías de software social cobra mayor relevancia dentro de las empresas.

Según el informe (que resalta las diferencias entre los entre los datos del 2006 y el 2007), el número de lectores de weblogs pasó de un 37% a un 79%; el número de personas que participan mediante la incorporación de comentarios aumentó de un 10% a un 51% y el número de personas con blog aumentó del 21% al 38%.

Igualmente se refleja un aumento considerable en la frecuencia de uso de estas tecnologías y los sectores que se monitorizan como grupos activistas, competencia, blogs de información relevante para el negocio, periodicos, sitios de software social como youtube, flick etc.

El resultado refleja el comportamiento y uso cada vez mayor de esta tecnología que ha pasado la etapa de implantación inicial y está ahora “invadiendo” todos los sectores y entre ellos, el empresarial en el se observa la necesidad de utilizar cada vez más el software social no solo como herramienta de publicación, sino como mecanismo de análisis de la competencia, tendencias, mercado, etc.

Temas de WordPress a la medida

Siguiendo mi trabajo de investicación entorno a wordpress he encontrado anoche una web muy curiosa, wordpress theme generator y no deja de asombrarme más la fuerza que ha cogido esta herramienta de blog.

Wordpress Theme Generator

WordPress theme generator permite editar de manera gráfica las caracteristicas de nuestro tema, soporta wordpres 2.1, widgets, soporta todos los browsers y yahoo GUI :

  • Color del texto del encabezado
  • Imagen de background
  • Layout básico de dos o tres columnas
  • Menú básico
  • Color de texto del post (titulo, contenido)
  • Ancho del body
  • Y otras caracteristicas básicas

Con esta herramienta un usuario novato sin conocimientos en html, javascript, php y css puede diseñar un tema propio sin mucho esfuerzo.

Disfrutenlo… :-).

WpZipper, Instalador de WordPress a la carta

WPZipper

En ifacethoughts encontré una referencia a WpZipper, un portal que permite descargar una versión de wordpress. Los pasos son muy sencillos y sigue el clasico 3 pasos de web2.0. Los pasos son:

  1. Seleccione los plugins: Tiene un sistema de busqueda por palabra y ofrece una lista inicial aleatoria.
  2. Seleccione los temas: Igual que el anterior permite seleccionar un conjunto de temas para la instalación.
  3. Descargar en un fichero zip: Permite descargar una versión de wordpress con todo lo necesario de acuerdo a los datos seleccionados.

El portal es muy sencillo de utilizar y para utilizarlo solo basta con registrarse, no tiene confirmación de correo. Otra característica es que permite guardar las “Instalaciones Virtuales” como le llaman a la configuración seleccionada. Además permite descargar la version 2.2 de wordpress.

Según su web, tienen más de 3000 temas y ya llevan más de 100.000 descargas, la verdad es que da una flexibilidad muy grande para buscar una configuración, pero en mi concepto se debe haber cacharreado un poco con wordpress y conocer en cierta forma los plugins para realizar una buena selección.

Una cosa que echo en falta es un sistema de etiquetado de plugins y temas para hacer las búsquedas más amenas y un sistema de ranking, no estaría mal esta característica pues ayudaría a hacer mejores selecciones.

WordPress y Bucle

WordPress utiliza el bucle de post para permitir manipular los mismos. De acuerdo al funcionamiento de wordpress, el número de post que presenta depende donde se ejecute. Ej. Si se llama index.php se muestran los más recientes, pero si se está en una categoría, se muestran los más recientes en esa categoría.

Como necesitaba mostrar los más recientes, implementé una funcion que recupera los registros y usa start_wp para hacer el tratamiento de los mismos.

function plugin_showlast($n){
$postslist = get_posts(‘numberposts=’.$n.’&order=ASC&orderby=post_title’);
foreach ($postslist as $post) :start_wp(); ?>
<li><a href='<?php the_permalink();?>’><?php the_title(); ?></a></li>
<?php endforeach;
global $wp_query;
// Since the old style loop is being used, advance the query iterator here.
$wp_query->rewind_posts();
}

Esta función, tiene la particularidad de que saca los $n últimos dependiendo del sitio donde se ejecute, con lo cual la función  get_posts es contextual.

La instrucción:

$wp_query->rewind_posts();

Se usa para reiniciar la variable que contiene los post del contexto, me vi oblicado a ponerla porque se presenta un problema al intentar ver un registro único para hacer comentarios, el bucle principal de single.php donde saca un mensaje que indica que no se han encontrado registros con el criterio utilizado.  (Cuando uso esta función antes de la ejecución del bucle por defecto de wordpress).

sobreescribir librerias de javascript en wordpress

Tengo instalado wordpress 2.2.3 que viene con prototype 1.5.0, en el desarrollo de mis plugins estoy utilizando prototype 1.5.1, como no quiero cargar dos veces la librería de prototype, me he dado a la tarea de buscar la forma de reemplazarla.

El problema que tengo radica que no hay una llamada del API de WordPress que permita quitar las entradas en los scripts registrados, por ello, revisando un poco el código me he dado a la tarea realizar mi própia función para hacerlo.

En busca de una solución, he pasado por dos versiones distintas, la segunda, a mi parecer la más sencilla y limpia consiste en implementar una función de desregistro de script y utilizar el objeto del tipo WS_Script que trae definido wordpress.

function plugin_unregister_script( $handle) {
global $wp_scripts;
if ( !is_a($wp_scripts, ‘WP_Scripts’) )
$wp_scripts = new WP_Scripts();
$wp_scripts->remove($handle);
}

Esta función puede ser usada en la función de registro de cabeceras del plugin para “limpiar” los scripts que deseamos actualizar. Ej.

function plugin_header() {
$webutil=new WSPTWebUtil();
$url=$webutil->getServerURL();
$jsPrototype=$url.’/js/prototype.js’;
$jsWeb=WSPT_PLUGGIN_URL.’/lib/wspt.js’;
//desregistramos el script deseado
plugin_unregister_script(‘prototype’);
//registramos de nuevo el script
wp_register_script(‘prototype’,$jsPrototype,false,’1.5.1′);
wp_register_script(‘wspt’,$jsWeb,’0.1′);
//Mandamos a imprimir los scripts registrados.
wp_print_scripts(array(‘wspt’,’prototype’));
}

Cosas que no he probado, si un plugin invoca la función wp_print_script antes de la ejecución del plugin en cuestión.

Una segunda alternativa, en realidad la primera, fue en implementar una clase WS_ScriptsWrapper que extiende a WP_Scripts y sobreescribe el métodos add para que actualice la entrada del script.
El la clase WP_Scripts gestiona el registro de los scripts, en el método add que es el que nos interesa, no deja registrar un elemento si ya existe en el array de “handlers”.

function add( $handle, $src, $deps = array(), $ver = false ) {
if ( isset($this->scripts[$handle]) )
return false;
$this->scripts[$handle] = new _WP_Script( $handle, $src, $deps, $ver );
return true;
}

Problema, se guarda una variable global $wp_scripts, y PHP no permite hacer un cast para convertir un objeto de mi clase WP_ScriptsWrapper en WP_Scripts. Aunque al final lo he hecho serializando y des-serializando el objeto con un reemplazo de por medio.

La solución, escribir una función my_wp_register_script, que llame el método add modificado de la clase MyWP_Scripts que extiende de WP_Scripts y sobreescribe el método add.

$strobj=serialize($tmpwp_scripts);
$strobj=str_replace(‘WP_ScriptsWrapper’,’WP_Scripts’,$strobj);

Sencillo, pero funciona si quieres convertir recuperar la referencia del objeto padre. (Sobra aclarar que pierdes la referencia al objeto hijo y no podras alcanzar sus métodos.). Con este artilujio, se pueden tener varias alternativas de implementación, pero son más problemáticas que la segunda es decir.. la primera que explique..

Mi primera Cana

Este dia (Miércoles 30 de Mayo) quedara marcado en mi como "El dia en que descubrí Mi primera Cana". Llevaba mucho tiempo esperando este dia. Esta mañana al pasar por el aseo de mi trabajo, me mire al espejo y mis ojos no daban crédito, ahí estaba, blanca y solitaria en medio de una maraña de cabello negro. Aunque me resisti por un momento a creerlo, efectivamente una segunda, tercera y cuarta mirara me lo confirmaron. No era un sueño, estaba ahí sin duda alguna.

Este dia esperado lo hace mucho más especial el hecho de la existencia de la canción "Mi primera Cana" de Diomedes Dias, canción que me hace evocar viejos tiempos en mi pueblo natal, La Plata Huila.

En aquellos tiempos, al escuchar:

Una hebra de cabello adorna mi cuerpo
una hebra de cabello adorna mi alma
ay! ve mi primera cana noticias de mi vejez

Se me venia a la cabeza la imagen de mi madre a quien quiero con toda mi alma y a la que recuerdo siempre que escucho esta canción. Igualmente, me acuerdo de mis amigos, Flor Divia Collazos y Mauricio Rentería, grandes amistades de mi juventud a quienes recuerdo, admiro y quiero con especial aprecio.

La siguiente estrofa me traslada a mi entorno familiar.

Yo sé que Rafael Santo Cuando me vea
lleno de juventud le dice a la mama
ay ve papá tiene canas, no se si ella se lo crea
.

Cuando no tenia hijos, siempre pensaba en decirle a mi hijo (me imaginaba que seria uno y hombre) que siempre que escuchara esta canción se acordara de mi, y cuando estuviera viejo y muriera, lo siguiera haciendo pues esta estrofa me hizo pensar en él aun antes de conocer a su madre y a él mismo. Mauricio, recuerdame con esta canción.

Con las siguientes tres estrofas.

Un montón de mujeres se me llevaron
lo mejor de mi vida sentimental
hay unas que me pagaron mal
y otras que muy bien se portaron

La vida me ha golpeado mas de dos veces
pero yo he sido un hombre muy optimista
ay! ve gracias virgen del Carmen
por dame tantas cosas bonitas

Por ejemplo me diste una mujer
que ha sido como la madre mía
de Luis Ángel, de Santo Rafael
de Diomedes y el gran Martín Elías

Mi mente se dirige a mi esposa, Paula Inés Martinez, la madre de mis hijos, una mujer muy especial a la que amo profundamente. Y como dice la canción, Paula es de las mujeres que bien se portaron , se sigue portando y se seguirá portando (Espero ). Y en la tercera estrofa …me diste una mujer… está su nombre clavado, con nuestros hijos Oscar Mauricio y Mara Isabel.

Y el texto:

ay! ve gracias virgen del Carmen
por dame tantas cosas bonitas

Me hace agradecer a Dios y la Virgen por todo lo obtenido, mi mujer, mis hijos, mi familia, mis amigos, la familia de mi esposa y todo lo que nos rodea.

Inconsistencia en $_SERVER PHP

He estado programando un plugin para wordpress con un servidor apache 2.2 ejecutandose en el puerto 8080 y php5.2.1. Pero esta mañana se me presentó un problema con un código que aparentemente no tiene nada de malo.

El código es el siguiente.

var GB_ROOT_DIR = “<?php echo ‘http://’.$_SERVER[‘SERVER_NAME’].’:’.$_SERVER[‘SERVER_PORT’].$this->gbPath?>”;

El Problema

Bajo ciertas condiciones en WordPress al cargar una entrada específica (usando single.php), la variable $_SERVER[‘SERVER_PORT’] me da el valor de 80, en lugar de 8080 que es donde escucha el servidor web.

La Solución

Luego voltear un rato, encontré lo siguiente:

Aunque mi servidor está en el puerto 8080 (La directiva Apache tiene este valor -Listen 8080-), la variable ServerName está en el puerto 80. (ServerName server.server.com:80).

Cambiando el valor de server.server.com a 8080 se solucionó el problema

El lio es que esto solo se presentó al mostrar las entradas del blog individuales, las entradas de categorías y el index no presentaron ningún problema.

El contenido de la variabel $_SERVER es el siguiente.

Array ( [REDIRECT_STATUS] => 200
[HTTP_ACCEPT] => image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, application/x-shockwave-flash, */*
[HTTP_REFERER] => http://localhost:8080/blogs/ws/2007/05/25/pepito-perez-2/59
[HTTP_ACCEPT_LANGUAGE] => es
[HTTP_ACCEPT_ENCODING] => gzip, deflate
[HTTP_USER_AGENT] => Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727; InfoPath.1)
[HTTP_HOST] => localhost:8080
[HTTP_CONNECTION] => Keep-Alive
[HTTP_COOKIE] => rated_23=1; dbx-postmeta=grabit:0+|1+|2+|3+|4+|5+|6+&advancedstuff:0-|1-|2-; dbx-pagemeta=grabit:0-|1-|2-|3-|4-|5-|6-|7-&advancedstuff:0- [PATH] => C:\\WINDOWS\\SYSTEM32;C:\\WINDOWS;C:\\WINDOWS\\SYSTEM32\\WBEM;C:\\Archivos de programa\\Microsoft SQL Server\\80\\Tools\\BINN;C:\\Archivos de programa\\Panda Software\\Panda Antivirus Platinum\\;c:\\Archivos de programa\\Microsoft SQL Server\\90\\Tools\\binn\\;C:\\Archivos de programa\\MySQL\\MySQL Server 5.0\\bin
[SystemRoot] => C:\\WINDOWS
[COMSPEC] => C:\\WINDOWS\\system32\\cmd.exe
[PATHEXT] => .COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH [WINDIR] => C:\\WINDOWS
[SERVER_SIGNATURE] =>
[SERVER_SOFTWARE] => Apache/2.2.4 (Win32) PHP/5.2.1
[SERVER_NAME] => localhost [SERVER_ADDR] => 127.0.0.1
[SERVER_PORT] => 80
[REMOTE_ADDR] => 127.0.0.1
[DOCUMENT_ROOT] => D:/apacheweb/htdocs
[SERVER_ADMIN] => diego.acosta@xxxxxx.org
[SCRIPT_FILENAME] => D:/apacheweb/htdocs/blogs/ws/index.php [REMOTE_PORT] => 2809
[REDIRECT_URL] => /blogs/ws/2007/05/25/pepito-perez-2/59 [GATEWAY_INTERFACE] => CGI/1.1
[SERVER_PROTOCOL] => HTTP/1.1 [REQUEST_METHOD] => GET
[QUERY_STRING] =>
[REQUEST_URI] => /blogs/ws/2007/05/25/pepito-perez-2/59
[SCRIPT_NAME] => /blogs/ws/index.php
[PHP_SELF] => /blogs/ws/index.php
[REQUEST_TIME] => 1180439795 )

Puede observase que [HTTP_HOST] => localhost:8080 y [SERVER_PORT] => 80 tienen valores diferentes.