Contenido

POM: Programación Orientada a Maquetadores

25 jul

+ 20

Entre diseñadores web y desarrolladores web siempre ha habido una línea un tanto difusa entre las funciones de uno y las funciones de otros. En esa línea difusa aparece el perfil de maquetador que en muchas empresas recae entre las funciones de uno o de otro.

Si nos ponemos tiquismiquis podemos sacar muchos más perfiles, pero para este artículo nos bastará con estos 3  :D

Proceso de creación

Para entendernos un poco mejor, explico lo que entiendo por un proceso de creación de una aplicación web, partiendo de que se haya hecho (o no…) un buen análisis, con su correspondiente toma de requerimientos y si ya estás en una empresa seria de verdad, un proceso de validación de prototipos, y especificaciones… pero solo si es una empresa seria de verdad, no vale con ir de ello…

En ese punto, una vez aprovado todo por el cliente, remarcado y explicado perfectamente lo que se ha pedido y lo que se ha de entregar, se comienza a trabajar.

En este punto, los diseñadores empiezan a darle forma a esos prototipos, esos wireframes que el usuario a validado y que espera recibir. Una vez terminados estos diseños, generalmente en formato imagen, se le muestran al usuario para que valide el diseño de la página y pasemos a darle funcionalidad a la misma. (Ojo!, creo que estoy entrando en un mundo utópico rodeado de unicornios y dragones… :D).

Vale, ya hemos validado con el usuario el diseño y la funcionalidad que desea para su nueva y flamante nueva aplicación web, ha sido un proceso duro, pero nos permite disponer de toda la información necesaria para empezar y no tener que volver a molestar al usuario, salvo las notificaciones periódicas que se planifiquen.

En este punto, el diseño se pasa a los maquetadores, encargados de convertir ese diseño en el HTML que el usuario podrá ver en su navegador, este HTML no contendrá ninguna funcionalidad, únicamente habrá HTML y CSS.

En este punto, entramos una zona pantanosa, ya que nos encontramos código javascript que necesita el diseño para ser funcional (sliders, autocompletes, ….). Soy de los que cree que esta responsabilidad debería caer en el maquetador, ya que es el que está más cerca del diseñador para saber que funcionamiento ha de tener esa porción de web concreta.

Por otro lado, nos encontramos con que hay ciertas funcionalidades que afectan, tanto al maquetador como al desarrollador web, por ejemplo los autocompletes (suggest), validación de formularios, … esta funcionalidad es a veces un poco difusa. En este punto entra lo que yo llamo, en alarde de originalidad POM (Programación Orientada a Maquetadores).

POM: Programación Orientada a Maquetadores

Se trata de ofrecer al maquetador una serie de herramientas que le permita añadir funcionalidad básica al HTML sin necesidad de tocar una sola línea de Javascript. Básicamente se trata de generar componentes autónomos que lean el HTML y los atributos especiales que este HTML ha de tener.

Hace ya mucho tiempo, publiqué un ejemplo de validación de formularios con jQuery que seguía esta metodología. Se basaba en indicar a cada elemento de que tipo de validación requería para comprobar los datos de entrada. A grandes rasgos, vemos que usando el class de los atributos <input />, <select />,… informábamos el tipo de validación.

Atributos data-*

Entonces llegó HTML5 y sus atributos data-*, unos atributos que abren un abanico de posibilidades, y aunque antes me daban un poco de miedo, ahora disfruto con ellos :D

Los atributos data-*, nos permiten dotar a nuestros elementos de un montón de datos que podemos usar en nuestro código javascript, de forma que podremos construir un código capaz de trabajar con ellos y construirse en función de ellos.

Veamos un ejemplo:

<input type="text" class="autocomplete estilobonito" data-max-items="15" data-type="clientes" data-min-length="3" />

// jQuery
$("input.autocomplete").bind(function(){

	// Recogemos valores
	var $this = $(this),
	 	$value = $this.val(),
		$maxitems = $this.data("max-items") || 5,
		$type = $this.data("type") || "compras", 
		$minlength = $this.data("min-length") || 5;
	
	
	/* Funcionalidad */
	
	// Salimos si ha pulsado menos de $minlength carácteres
	if ($value.length < $minlength) return;
	
	jQuery.getJSON("http://miservicio.com/", {
		type: $type,
		items: $maxitems,
		value: $value
	},function(){
		/* LO QUE QUIERAS HACER*/
	});
});

Como podemos ver, nos permita acceder a ellos fácilmente, sin jQuery y para IE es igual de fácil.

¿Donde está la gracia?

La gracia está en hacer el código lo más reutilizable posible, haciendo que nos permita configurar nuestros elementos HTML de forma fácil. En mi caso personal, esta programación ha conseguido descargarme bastante de trabajo que antes hacía yo para que ahora los maquetadores/diseñadores puedan configurar.

Por experiencia, puedo decir que siempre terminas modificando el código y adaptando el código a las diferentes necesidades del diseño, pero se convierte en una tarea más sencilla y fácil de depurar.

Un ejemplo que estamos usando y que nos funciona muy bien, a ver si un día puedo implementar una versión de demo para que la veáis, es un autocomplete usando el de jQuery UI, capaz de diferenciar entre 3 o 4 tipos diferentes de datos y 3 o 4 salidas diferentes que comparten prácticamente todo el código.

Esto, añadido al modelo de programación modular que vimos hace ya muuucho tiempo, nos está dando unos muy buenos resultados, tanto a la hora de desarrollar como a la hora de depurar la aplicación.

Introducción a GTD (Getting Things Done)

14 sep

+ 18

Hace una semana que estoy intentando hacerme con el método de gestión de tareas llamado GTD (Getting Things Done). Por el momento me está ayudando a gestionarme más eficientemente las tareas del día a día. Y poco a poco voy cogiendo la rutina de trabajar con este sistema.

Aprovechando que lo tengo reciente publico este mini resumen por si a alguien no lo conoce y le puede ayudar. Aunque yo no lo he hecho (aún) recomiendo leer el libro “Organizate con Eficacia /GTD”.

Descripción

GTD (Getting Things Done) es un método de gestión de tareas descrito por  David Allen, que se basa en apuntar las tareas y descargar al cerebro de la tarea de almacenarlas conscientemente.

En su lugar, propone que se creen listas por contextos, permitiéndonos revisar únicamente las tareas asociadas a un contexto. De esta forma únicamente será necesario procesar las del contexto en el que estemos en ese momento.

Por ejemplo, ¿Por qué pensar en las tareas a hacer en casa mientras estamos en el trabajo? Al llegar a casa, tendremos las tareas que debemos hacer en el contexto “casa”.

Continua —>

Reduce el ruido de tus fotografías apilando imágenes I

23 may

+ 11

Si recordamos los 3 factores que intervienen en la correcta exposición de una fotografía nos encontramos con la sensibilidad ISO, que era la que nos permite especificar la cantidad de luz que el sensor es capaz de procesar. Este proceso se realiza forzando la sensibilidad por defecto del sensor electrónicamente. Este sobreesfuerzo del sensor produce un efecto en forma de ruido, píxeles encendidos aleatóriamente por toda la fotografía que puede (o no) afear la imagen.

Una técnica que se usa para reducir el ruido de la imágen es la de apilar imágenes y promediarlas para eliminar los puntos aleatorios y reforzar los puntos de información de una fotografía. En este ejemplo usaré Photoshop, aunque hay muchas herramientas que permite conseguir el mismo efecto.

Poniendonos en situación

Imaginemos que estamos dentro de una iglesia, catedral o recinto oscuro que nos obliga a subir la sensibilidad ISO para obtener la imagen correctamente expuesta. Yo he usado el trípode como modelo y he hecho la foto en una habitación con la ventana cerrada para simular la falta de luz.

inicio
(Ver Imagen)

La fotografía está tomada a:

  • Velocidad: 1/20 seg
  • Apertura: f/4.0
  • ISO: 1600
  • Focal: 10mm

Continua —>

Wp-Answers, crea una comunidad de preguntas y respuestas con WordPress

7 nov

+ 77

Hace unos meses empecé a montar este plugin que permite crear comunidades basadas en preguntas y respuestas, al estilo StackOverFlow y/o Yahoo! Answers. La idea es generar, sin modificar para nada el núcleo de WordPress, un sistema basado en votaciones de comentarios y ordenarlos por este número de votaciones.

De esta forma, podremos disponer de un sistema que nos permita lanzar preguntas y que mediante las contestaciones de los usuarios y sus votos, podamos obtener una respuesta lo más acertada posible.

Wp-Answers

El plugin se encarga de añadir un formulario a cada comentario permitiendo que los usuarios puedan votar positiva o negativamente dicho comentario. Posteriormente y dependiendo del número de comentarios de este comentario y los demás, lo ordenará de forma que el comentario con más votos quede primero, el segundo mejor votado segundo y así sucesivamente.

wp-answers
(Ver Imagen)

Nuestro theme

El plugin, está pensado para no depender de ningún theme y que pueda funcionar en cualquiera, por ello todo el estilo CSS y el Javascript (para realizar las llamadas con Ajax) se puede añadir fácilmente adaptándolo a cada WordPress.

Dándole estilos

El formulario, por defecto no tiene estilos aunque puede personalizarse como más nos guste incluyendo los estilos a nuestro style.css de nuestro theme. Os dejo un ejemplo del que he usado para las pruebas:

.wp_answers_votes {
 float:right;
 background-color:#F1F1F1;
 margin-bottom:10px;
 padding:10px
 text-align:center;
 -moz-border-radius:6px;
 -webkit-border-radius:6px;
 border-radius:6px;
}
.wp_answers_total_votes{
 font-size:2em;
}

Opciones

Disponemos de una serie de opciones, muy sencillas que nos permiten configurar el nivel de Karma que aporta o resta la votación de comentarios. Además de poder indicar si necesitamos que el usuario este registrado en el blog o no.

wp-answers-options
(Ver Imagen)

Widget

He creado un pequeño Widget que nos permitirá mostrar un top N usuarios, ordenados por karma acumulado en nuestro sidebar, simplemente tendremos que indicar las opciones del Widget y añadirlo al sidebar que deseemos.

wp-answers-widget
(Ver Imagen)

Descargar

Aquí teneis el enlace, también podeis verlo en funcionamiento con el theme P2 (de WordPress)

Actualización

Por sugerencia de Cristian Eslava añado la opción de seleccionar una categoría a la que asociar este sistema de mostrar los comentarios. De esta forma, es posible asociarlo a una parte de tu WordPress y no a todo.

Introducción a los W3C Widgets

22 abr

+ 3

Hace 3 años que vimos las primeras noticias sobre el borraror de la W3C sobre los Widgets. Y ya entonces vimos que el tema prometía. QuirksBlog nos muestra una introducción sobre como usar estos Widgets.

¿Que es un widget?

Esencialmente un Widget es un conjunto de HTML/CSS/Javascript locales. Decimos locales, por que una vez que, por ejemplo, un movil descarga un widget debe ser capaz de usarlo localmente, al quedar instalado en él.

Aunque actualmente la utilización de widgets es muy límitada, lectores de RSS, relojes,… no hay razones teóricas de que no puedan ser capaces de crear aplicaciones basadas en Javascript realmente complejas, por ejemplo una Hoja de Cálculo.

La belleza de este modelo, es que aunque una aplicación requisiera 200kb de Javascript, más una serie de librerías, el usuario únicamente tendrá que descargarlo una sola vez. Después de la descarga, la aplicación se instala y las próximas veces se ejecutará en local sin necesidad de descargar nada.

En caso de requerir cualquier dato externo al widget, dispone de una interface que nos permite realizar peticiones Ajax y cargar el contenido en el momento que lo necesitamos.

Los W3C Widgets nacen como estandarización a los ya existentes creados para dispositivos como el iPhone, móviles Android, … que usan sistemas propietarios y únicamente adaptables a sus dispositivos. Con W3C Widgets se intenta crear un sistema que permita la interoperatividad de estos widgets en diferentes dispositivos sin necesidad de tener que modificar una sola línea de código del widget. Y todo ello aprovechando las técnicas HTML/CSS/Javascript que los desarrolladores conocemos.

En fin, los W3C Widgets apuntan como el futuro de la web movil. Son fáciles de crear, usan estándares abiertos y se ajustan al mínimo consumo de la red.

Información técnica

Los Widgets no son más que sitios web comprimidos. Creamos un fichero HTML, le añadimos los estilos necesarios en ficheros CSS y la funcionalidad viene dada en ficheros Javascript. Todo ello comprimir en un fichero zip, al que le cambiaremos la extensión a .wgt y listo. ¿Sencillo verdad?

Actualmente la especificación está continua como Working Draft (Borrador) modificado últimamente el día 5 de Febrero de 2009. Aunque el proceso está siendo tan lento como la W3C ya están las bases muy bien definidas.
Continua —>

iCal Archive para WordPress

17 feb

+ 13

Ya podemos descargar iCal Archive para WordPress. Se trata de de una adaptación sobre WordPress del script que vimos hace unos días con el que podiamos crear un calendario al estilo iCal (del iPhone) con jQuery.

ical_archive_wordpress

Ver Demo

Instalación

  1. Descargamos el ficheros
  2. Descomprimimos y colocamos el directorio completo en la raiz de WordPress.
  3. Modificamos el HTML si queremos adaptarlo al diseño del blog.

Descargar

Versión 0.1

Ejecutar PHP en tus posts con shortcodes

4 feb

+ 8

Hace unos minutos he publicado una entrada sobre los ShortCodes y la importante labor que pueden llegar a desempeñar en nuestros WordPress. Usando la API de ShortCodes he montado un pequeño script basado en execPHP que permite ejecutar PHP en nuestros posts mediante un sencillo shortcode.

Código

function eval_php($atts, $content=null) {
        ob_start();
        eval($content);
        $output = ob_get_contents();
        ob_end_clean();
        return "Entro".$output;
}

add_shortcode("php", "eval_php");
// Forzamos el do_shortcode al principio
add_filter('the_content', 'do_shortcode', 1);

Modo de empleo

[php]Código PHP[/php]

Sin los tags de php <?php ni ?>.

Ejemplo

[php]
	$str = "Hello {xx}";
	echo str_replace('{xx}', 'World!', $str);
[/php]

¿Donde pongo este código?

Puedes ponerlo en el fichero functions.php de tu theme o crear un plugin con el código.

¿Precauciones?

Hay que pensar que se está ejecutando código PHP desde los posts, si no eres el único usuario que postea debes tener esto en cuenta y quizas modificar el script. He montado 2 ejemplos para los más vagos :D

1. Limitando por ID de usuario

// ID's de usuarios permitidos
$users_avail = array(1,2,3,4);

function noPHP($data = null){
	global $current_user, $users_avail;
  	 get_currentuserinfo();

	if (in_array($current_user->ID, $users_avail)) return $data;
	$data["post_content"] = str_replace("[php]", "", str_replace("[/php]", "", $data["post_content"]));
	$data["post_content_filtered"] = str_replace("[php]", "", str_replace("[/php]", "", $data["post_content_filtered"]));
	return $data;
}

add_filter('wp_insert_post_data', 'noPHP');

function eval_php($atts, $content=null) {
	ob_start();
	eval($content);
	$output = ob_get_contents();
	ob_end_clean();
	return $output;
}

add_shortcode("php", "eval_php");

// Forzamos el do_shortcode al principio
add_filter('the_content', 'do_shortcode', 1);

2. Limitando por level mínimo

// Level mínimo
$minlevel = 5;

function noPHP($data = null){
	global $current_user, $minlevel;
      get_currentuserinfo();

	if ($current_user->user_level > $minlevel)
		return $data;

	$data["post_content"] = str_replace("[php]", "", str_replace("[/php]", "", $data["post_content"]));
	$data["post_content_filtered"] = str_replace("[php]", "", str_replace("[/php]", "", $data["post_content_filtered"]));
	return $data;
}

add_filter('wp_insert_post_data', 'noPHP');

function eval_php($atts, $content=null) {
	ob_start();
	eval($content);
	$output = ob_get_contents();
	ob_end_clean();
	return $output;
}

add_shortcode("php", "eval_php");

// Forzamos el do_shortcode al principio
add_filter('the_content', 'do_shortcode', 1);

Así y todo yo tendría cuidado con esto ya que mediante la ejecución de PHP en los posts, los autores, editores, … pueden hacer desastres de magnitudes impredecibles…

Limitaciones

No he podido hacer muchas pruebas, así que es posible que surjan errores y quizas haya limitaciones en el código que ponemos, podríamos comentarlas.

Divide formularios en pasos con jQuery

28 ene

+ 10

Revisando los posts del foro, en un rato que he tenido, me he encontrado babySteps, un plugin que hans me muestra y que se encarga de dividir formularios en partes. Un componente ideal para formularios rápidos y complicados.

Revisando el plugin he visto que tu defines los puntos de corte y eso no me acaba de gustar, el tener que poner elementos que no tendrían ningún sentido si no fuera por el plugin no me ha gustado mucho. Así que me montado un pequeño script, que usando jQuery, nos permite obtener lo mismo siguiendo un poco más la semántica del HTML.

stepForm()

Simplemente es una función que se encarga de convertir todos los formularios cuyo atributo class sea stepMe. Únicamente se encarga de cortar el formulario por elementos <fieldset /> haciendo que un formulario largo aparente ser varios de menor tamaño.

Veamos un ejemplo que he montado.

<form action="" method="post" class="stepMe">
	<fieldset>
		<label for="name">Nombre:</label>
		<input name="nombre" id="name" value="" />
		<label for="surname">Apellidos:</label>
		<input name="apellidos" id="surname" value="" />
		<label for="birthday">Fecha de Nacimiento:</label>
		<input name="fnac" id="birthday" value="" />
	</fieldset>
	<fieldset>
		<label for="text1">Text1:</label>
		<select id="text1">
			<option>1</option>
			<option>1</option>
			<option>1</option>
			<option>1</option>
			<option>1</option>
		</select>
		<label for="text2">Text2: </label>
			<input type="radio" id="text2" />
	</fieldset>
	<fieldset>
		<label for="submit">Submitar datos </label>
		<input type="submit" id="submit" value="Enviar" />
	</fieldset>
</form>

Este ejemplo nos divide la página en 3 pasos. Para permitir al usuario moverse entre los pasos he añadido un enlace “Volver” y otro “Seguir“, pero no descarto añadir una pequeña paginación esta noche :D

Personalización

Podemos definir nuestro propio estilo para los enlaces que se añaden mediante el uso CSS de las clases .nextStep y .backStep.

Además, podemos definir el texto que queremos mostrar en ambos enlaces pasándolo como parámetro. Disponemos de 3 parámetros:

  1. Texto Back. (por defecto Volver)
  2. Texto Next. (por defecto Seguir)
  3. Contenedor. (por defecto fieldset)
$.stepForm();
// Volver / Seguir [fieldset] 

$.stepForm('Back','Next');
// Back / Next [fieldset]

$.stepForm('<-','->', 'p');
// Volver / Seguir [p]

Si somos reacios a usar <fieldset /> podemos pasar como 3er parámetro el tag que vamos a usar como contenedor.

Código

jQuery.extend({
    stepForm: function(txtBack, txtNext, token){
    	var fieldsets = $((token || 'fieldset'), $("form.stepMe"));
        var total = $(fieldsets).length;
	$(fieldsets).each(function(x,el){
			    if (x > 0) {
			      $(el).hide();
			      $(el).append('<a class="backStep" href="#x_' + (x-1) + '">'+ (txtBack || 'Volver') +'</a>');
			      $(".backStep", $(el)).bind("click", function(){
			                $("#x_" + (x - 1)).show();
			                $(el).hide();
			       });
			    }

			    if ((x+1)< total) {
			        $(el).append('<a class="nextStep" href="#_' + (x+1) + '">'+(txtNext || 'Seguir')+'</a>');
			        $(".nextStep", $(el)).bind("click", function(){
			                $("#x_" + (x + 1)).show();
			                $(el).hide();
			        });
			    }
			    $(el).attr("id", "x_" + x);
	});
    }
});

Actualización

Marco Neumann  ha portado el script a MooTools para los usuarios de este framework. La verdad es que la claridad del código no tiene comparación.

@webdev2k, el microblog del desarrollo web

26 ene

+ 8

Usando Twitter y este artículo de ThinkVitamin, no ha sido muy complicado montar un microplanet de microposts sobre desarrollo web. Por ese motivo ha nacido @webdev2k, un lugar donde encontrar las últimas herramientas, artículos y/o publicaciones sobre desarrollo web en tiempo real.

¿Como funciona?

webdev2k1

Simplemente hay que añadir @webdev2k en tu tweet (micropost) en Twitter y automáticamente aparecerá en la aplicación. Como podemos ver en la imagen.

¿Para que sirve?

Principalmente para agrupar todo lo relacionado con el desarrollo web y promocionar tus aplicaciones, posts o artículos relacionados con el mundo web.

Visita @webdev2k

Para los que quieran seguirlo desde Twitter, podeis seguirlo como a otro usuario más.

@webdev2k en Twitter

jsCron, portando Cron a Javascript

5 ene

+ 31

En un momento de aburrimiento he estado implementado una versión de Cron para Javascript. Para los que no lo sepan, Cron es una utilidad del sistema Unix que permite programar tareas a lo largo del tiempo. Una de las utilidades más usadas para tareas como copias de seguridad, envío de mails, …

Para Javascript he pensado que sería interesante usar la misma estructura cron usa en el fichero crontab, donde se almacena la lista de tareas programadas.

35 17 * * * hola()

Hagamos un pequeño repaso a los parámetros de Cron (por orden):

  1. minuto [0-59]
  2. hora [0-23]
  3. dia del mes [0-31]
  4. mes [0-12]
  5. dia semana [0-7]
  6. ejecutable

Los * indican cualquier, por lo tanto en el ejemplo anterior indicamos que cada día a las 17:35 se ejecutará el script hola().

La hora especificada será la del navegador del usuario

Veamos unos ejemplos más:

* 16 * * * hola()

Cada día desde las 16:00 a las 16:59 se ejecutará hola().

30 6 1 * * showHola()

Ejecutamos showHola() el día 1 de cada mes a las 6:30 de la mañana.

Se trata de un sistema bastante rudimentario, pero funciona y aunque operadores como (/2) no están contemplados, dan mucho juego.

Codigo

var jsCron = {
		items:[],
		interval: null,
		parse: function(strUnix) {
				return strUnix.match(/^(\d+|\*) (\d+|\*) (\d+|\*) (\d+|\*) (\d|\*) +(\w+)/);
		},
		check: function() {
				var hoy = new Date();
				var test = [new Date(), hoy.getMinutes(), hoy.getHours(), hoy.getDate(), hoy.getMonth(), hoy.getDay()];

				for (var i in this.items) {
					var exec = 0;
					var t = this.parse(this.items[i][1]);
					for (var x in t)
				    if (t[x] && (t[x] == test[x] || t[x] == "*"))exec++;
					if (exec == 5 && this.items[i][0] == 0) {
							eval(t[6]).call();
							this.items[i][0] = 1;
					} else if (exec < 5 && this.items[i][0] == 1) {
						this.items[i][0] = 0;
					}
				}
		},
		set: function(strUnix) {
			if (!/^(\d+|\*) (\d+|\*) (\d+|\*) (\d+|\*) (\d|\*) +(\w+)/.test(strUnix)) return new Error("Formato invalido");
			this.items.push([0, strUnix]);
		},
		init: function(seg) {
			var seg = seg || 1000;
			this.interval = setInterval("jsCron.check()", seg);
		}
};
jsCron.init();

Modo de uso

Al igual que de un crontab debemos especificar un listado de tareas a programar, para ello usaremos el método set() e introduciremos la sentencia en el formato explicado anteriormente.

// Función hola();
function hola() {
   alert("Hola");
}

// Tarea programada
jsCron.set("35 17 * * * hola()");

Descargar Fichero JS (jscron)

Actualización

Un comentario de Ajaxian, me ha dado una solución al usar un eval() para ejecutar el código. Así podemos usarlo de una forma más cómoda sin perder la legibilidad de la función.

// Tarea programada
jsCron.set("35 17 * * *", hola())
// de forma inline
jsCron.set("35 17 * * *", function() {
   alert("Hola");
});