Best way to initialize a class on a WordPress plugin

When you’re developing a WordPress plugin, there are certain patterns and practices that are extremely useful to know and apply in order to get a better fit with the platform as a whole.

One of these things it’s what’s the better way to initialize a class on a plugin, which this answer on the WordPress StackExchange covers in great detail, while also explaining other interesting topics and recommendations such as using an autoloader and global access, registry and service locator patterns.

While you’re at it, you might also want to check these posts from Tom McFarlin:

 

Usar moment.js como helper en Ember/Handlebars

moment.js es una librería completísima para trabajar con fechas en Javascript, que puedes registrar como helper para Ember de modo de facilitar todas la tarea de parsear y formatear fechas desde y hacia distintos formatos.

Ember.Handlebars.registerBoundHelper('fecha', function(stringFecha, options){
  // options.hash es un objeto con las opciones
  var args = Ember.$.extend({
    inputFormat: 'M/D/YYYY',
    outputFormat:  'D MMM YYYY'
  }, options.hash );
  var fecha = moment(stringFecha, args.inputFormat);
  return fecha.format( args.outputFormat );
});
  • El método Ember.Handelbars.registerBoundHelper() te permite registrar un helper para propiedades que están ligadas al modelo, de modo que si éste cambia se vuelven a calcular.
  • La función que registra el helper recibe dos argumentos: el valor sobre el cual actúa el helper y un objeto de opciones.
  • El uso de Ember.$.extend() permite definir parámetros variables y opcionales e indicar sus valores predeterminados.

Uso:

// de forma normal, la propiedad post_published va a estar ligada al modelo
{{fecha post_published outputFormat="YYYY/MM/DD"}}

// también puedes usarlo de esta forma para que no cambie al cambiar los datos
{{unbound fecha post_published}}

Trabajar con fechas en MySQL

Trabajar con fechas es una tarea que al estar sujeta a tantas reglas especiales (meses con distinta cantidad de días, años bisiestos, comienzo de mes a media semana, etc) puede ser muy compleja si lo intentamos abordar sin el apoyo de una buena base.

Anteriormente he escrito sobre cómo trabajar con fechas en PHP y en Javascript: en ambos casos contamos con el concepto de fechas como objetos, lo que ordena y facilita bastante su manipulación a través de los métodos propios de cada lenguaje.

En MySQL existe a su vez un concepto de fechas y tiempos como tipos de datos con sus propias características, y junto con ellos, un montón de funciones que nos pueden servir para realizar distintos cálculos y operaciones al realizar consultas.

Continue reading “Trabajar con fechas en MySQL”

El nuevo PHP

Aunque por mucho tiempo PHP ha sido considerado el patito feo de los lenguajes de programación, lo cierto es que desde que hace aproximadamente un año pudimos confirmar la sospecha de que es por lejos el lenguaje más popular en la web: según cifras de Google, se trata del lenguaje que está tras el 75% de la web.

Pero esta cifra no es la única buena noticia para quienes utilizamos este lenguaje, ya existen varias señales ligadas a su desarrollo y utilización que auguran un futuro cada vez más brillante, al punto que en varios medios se habla del renacer de PHP.

Continue reading “El nuevo PHP”

Usando decoradores para extender WP_Post

La clase WP_Post recientemente introducida en WordPress 3.5 permite facilitar muchas tareas comunes en el desarrollo sobre este CMS, en particular el trabajo con campos personalizados almacenados en la tabla {$wpdb->prefix}postmeta.

Sin embargo, la forma en que está implementada esta clase aparentemente pone una limitante importante, ya que al estar definida como final no puede ser extendida mediante herencia:

class MiPost extends WP_Post{}
// Error Fatal: Class MiPost may not inherit from final class

Sin embargo, y aunque quizás no parezca obvio, es totalmente posible extender la funcionalidad de esta clase no utilizando herencia sino composición, por ejemplo, utilizando el patrón Decorator.

abstract class PostDecorator{
	
	/**
	 * Almacena el objeto post
	 * @access private
	 */
	private $post;
	
	/**
	 * @param object $post Un objeto de tipo WP_Post
	 */
	public function __construct( WP_Post $post ){
		$this->post = $post;
	}
}


class PostProyecto extends PostDecorator{
	
	/**
	 * @param string Nombre de la propiedad que se desea obtener
	 * @return string Valor de la propiedad
	 */
	public function __get( $key ){
		// permite acceso como $objeto->autor
		if ( $key === 'autor' )
			return $this->getAuthor();

		// si no corresponde a la funcionalidad que estamos agregando
		// podemos aprovechar el método __get() del objeto post
		return $this->post->{ $key };
	}

	/**
	 * @return string Nombre del autor o enlace
	 */
	public function getAuthor(){
		// el nombre del autor se almacena como un post meta con clave "_author"
		$author     = $this->post->_author;
		// la url está en un post meta con clave "_author_url"
		$author_url = $this->post->_author_url;
		return ( $author_url ) ? '<a href="'. esc_url($author_url) .'">'. $author .'</a>' : $author;
	}

}



$project_post = get_post(123);
$project = new PostProyecto( $project_post );

echo $project->autor;
// <a href="http://felipe.lv">Felipe</a>

De este modo, podríamos crear una clase para cada tipo personalizado de contenido, de modo de poder separar ordenadamente la lógica de la presentación y obtener una sintaxis muy clara y simple.

Objetos de posts de WordPress y la clase WP_Post

Una de las novedades más interesantes para desarrolladores que trae WordPress 3.5 es que a partir de esta versión los objetos tipo “post” ya no son objetos estándares de PHP (stdClass) sino instancias de WP_Post.

Por supuesto, este cambio está asociado a algunas ventajas inmediatas, relacionadas con una mejor performance y una optimización en que estos objetos se pueden almacenar en la caché de objetos (sobre todo si estás usando una caché externa, como APC, XCache o memcached). Esto es en parte debido a la utilización de métodos mágicos, tales como __isset( $key ), y el que resulta mucho más interesante, __get( $key ), que por ejemplo, permite cargar los “ancestros” de una entrada sobre demanda (con “lazy loading”), pero además tiene la posiblidad de cargar cualquier campo personalizado con la misma técnica.

En la práctica, esto significa que la utilización de datos de postmeta es muchísimo más sencilla. Por ejemplo:

<?php

// WordPress pre-3.5
// Deseo mostrar el campo personalizado "_ubicacion"
$ubicacion = get_post_meta( $post->ID, '_ubicacion', true );
echo $ubicacion;

// WordPres 3.5+
echo $post->_ubicacion;

Es decir, puedes acceder cualquier postmeta simplemente indicando el correspondiente meta_key como propiedad del objeto $post… ¡más conveniente, imposible!

Y si como yo tienes una “sana preocupación” por la performance de esta funcionalidad, puedes estar tranquilo: desde hace varias versiones WordPress carga en caché toda la información de postmeta al acceder a cualquier campo personalizado, lo que significa que no estará realizando una consulta a la base de datos cada vez que debas acceder a una propiedad de postmeta.

El único “pero” de la implementación de la clase WP_Post es que está marcada en el core como una clase final, por lo que si deseas utilizarla en un contexto mayor, no podrás extender la clase mediante herencia (como en MiClase extends WP_Post), sino que deberás hacerlo mediante composición, un patrón de diseño que quizás es un poco menos obvio… pero eso es motivo para otro post.