Y si no hay AJAX?

4
Nov/09
6

Recientemente escribí un comentario en el blog de Alfredo Artiles1, Bitácora de Webmaster, en un artículo relacionado con la nueva propuesta de los señores de google para hacer indexable un site en Ajax. En su artículo Alfredo resumía que aunque vayan por el buen camino al intentarlo, el uso de las técnicas que proponía Google para conseguirlo no le parecía muy adecuado. Yo voy un paso más allá y diría que sería todo un error implementar las opciones que comenta Google, pero esto daría para otro artículo2.

La cuestión es que su post viene a cuento porque hace tiempo que os quería comentar como, creo, que debería hacerse una web con contenido en AJAX y creo que este sería el mejor momento para ello.

Lo primero, comentaros que el problema de AJAX no solo está con los buscadores, sino principalmente con la usabilidad y accesibilidad. Ese pequeño porcentaje de usuarios que llega al site desde navegadores especiales para discapacitados, o desde navegadores solo texto, o incluso en un porcentaje mayor, aquellos que acceden desde su móvil, ellos son el principal objetivo a solventar cuando se desarrolla en AJAX, no los buscadores que en este caso creo que son secundarios (aunque también salgan muy beneficiados).

Bueno, entonces la panacea al respecto, cual sería? Simple, no desarrollar en AJAX!

Esto que parece una perogrullada es realmente la mejor solución para corregir el problema, desarrollar sin AJAX y añadir la capa de AJAX a posteriori. Con esto conseguimos crear una navegación lo más sólida posible fuera de todo JavaScript, y una vez creada añadimos mediante JS la capa AJAX, a base de modificar los enlaces internos por llamadas asíncronas al servidor y un par más de detalles en el código. Así, si un navegador sin JS o un Bot llegan a tu site con ganas de recorrerlo entero no tendrán ningún problema y podrán navegar por todo el site de forma perfecta.

También están los beneficios añadidos, como poder abrir enlaces en pestañas/ventanas nuevas, crear otra capa de independencia entre la Vista y los Scripts (digamos MVSC), o uno más importante aun el de poder enlazar directamente una página interna desde cualquier lado sabiendo que va a llegar a dicho enlace.

Nota: A partir de aquí el asunto se pone muy denso, así que si lo tuyo no es la programación front o bakend o la maquetación o si no comprendes algo de AJAX, mejor quédate con la idea vista hasta ahora y mira ejemplos en, por ejemplo, la web de Coleccionismo Baral

Lo primero que haremos será dar por sentado unos conceptos de la programación del site:

  • Se programa OOP (aunque en este caso no sea necesario, pero así vamos inculcando las nociones básicas mínimas)
  • Usamos el patrón de diseño de software MVC, separando la Vista y el Control sobretodo.
  • Usamos también el patrón Façade para tener así un único punto de entrada al código.
  • Usamos URLs SEO friendly del tipo http://host/casa/coche que luego pasarán a ser http://host#casa/coche

Bueno, una vez está claro esto, empezamos con la programación del site, creamos la navegación básica, la lógica interna del site, los modelos,… En fin todo el desarrollo pero sin incluir nada de AJAX por ahora. Una vez realizada la navegación y teniendo en cuenta que usamos los patrónes Façade y MVC incluimos un pequeño script3 al código del site similar al siguiente:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
//Script File
 
// variable general que nos servirá para chequear si hay que cambiar contenidos por AJAX
var navAjaxCheck = false;
 
// Función goto, encargada de hacer la llamada asíncrona
// La variable jsonValue incorpora toda la información necesaria
var goto = function (jsonValue)
{
	// Posibles excepciones a la navegación por AJAX
	if (location.hash.test("signup"))
  		return false;
 
	//waiter es para añadir el típico efecto de sombreado en el site mientras se cambia el contenido.
	jsonValue.waiter = jsonValue.waiter === false ? false : true;
 
	//update es el id del contenedor a remplazar
	// (false en caso de no quere actualizar nada y "contenedor general" en caso de "null")
	jsonValue.update = jsonValue.update ? jsonValue.update :
		(jsonValue.update === false ? false : 'contenedor_general');
 
	// El nuevo valor del href
	jsonValue.href = jsonValue.href.test("#") ? " " : jsonValue.href;
 
	new Request.HTML({
	// Aquí está el punto importante, mandamos toda la info a /ajax/
		url: '/ajax/'+JSON.encode(jsonValue),
/*	Se desactiva por fallos con el IE.
		update: $(jsonValue.update),
		useWaiter: jsonValue.waiter,
		waiterOptions: {
		    baseHref: '/',
		    img: {
		        src: 'img/loader.gif',
		        styles: {
		            width: '220',
		            height: '20'
		        }
		    },
		    layer: {
		        background: '#fff',
		        opacity: 0.9
		    }
		},
		waiterTarget: jsonValue.update, */
	// Una vez completado guardamos el href y la información donde corresponde
		onComplete: function(responseTree, responseElements, responseHTML, responseJavaScript){
			$(jsonValue.update).set('html',responseHTML);
			//reseteamos el init() ya que hay contenido nuevo en el site.
			init();
			if (jsonValue.href && jsonValue.replace)
			 	location.hash = "#"+ jsonValue.href.replace(jsonValue.replace,"");
			//reseteamos la variable navAjaxCheck para contener la información del site actual
			navAjaxCheck = location.hash;
		}
	}).send();
};
 
//Función recursiva encargada de hacer de watchdog para la navegación asíncrona (dotando de la opción de retroceder/avanzar)
var navAjax = function()
{
	// Posibles excepciones a la navegación por AJAX
	if (location.href.test("signup"))
		return false;
 
	// Esto se da en el caso de que estemos en una URL normal tipo /casa/coche, que rápidamente la formateamos a
	// #casa/coche para que siga la lógica de navegación asíncrona.
	if (location.pathname != '/')
	{
		var href = location.href;
		var value = 'http://'+WEBHOST+'/'; // WEBHOST es una variable definida anteriormente
	 	location.href = href.replace(value,value+"#"); // por compatibilidad con IE
 
	// Comprobamos con el check generado si ha cambiado el hash de la URL,
	// en cuyo caso llamamos a goto con el nuevo hash
	}else if (location.hash != navAjaxCheck)
	{
		var href = location.hash;
		var value = '#';
		goto({ href: href.replace(value,''),  waiter:false, replace:"" });
	}
};
 
//Función principal encargada de cambiar todos los enlaces internos por llamadas asíncronas.
var addAjax = function ()
{
	// Usamos una frase de testeo simple, el dominio del site (también podría ser algo más complicado mediante exp. regulares)
	var replace = 'http://'+WEBHOST+'/';
 
	// Buscamos todos los enlaces del site
	$$('a').each(function(el)
	{
		var href = el.href;
		// Buscamos los que enlazan dentro del site y evitamos los marcados como "noAjax"
		// a los encontrados así les quitamos la opción por defecto y añadimos la opción de Ajax
		if (href.test(replace) && el.className != "noAjax")
			el.addEvent('click', function(event)
			{
				event.preventDefault();
				goto({href: href, replace: replace});
			});
 
	});
 
// función con las llamadas necesarias al cargar el site (incluir el navAjax, chequear variables...)
var init = function()
{
 
	// Añadimos el ajax
 
	addAjax();
 
	// ....
}
 
// Añadimos los eventos justo cuando el DOM ya se haya cargado.
window.addEvent('domready', function() {
 
	// Lanzamos el control de AJAX con un periodical para que se ejecute continuamente
	// el tiempo aproximado depende de la carga de JS del site y al gusto de cada uno (entre 1 y 5 segundos)
	navAjax.periodical(1000);
 
	// Cargamos el init con la información necesaria.
	init();
 
	// Cargamos el resto de funcionalidades que solo son necesarias una vez.
}
 
};

Como podréis ver, este JS está bastante mal codificado, lo suyo sería crear una clase completa que se encargue de toda la parte de navegación AJAX y hacerle mucho refactoring para conseguir algo decente, pero la idea es explicar los principios de acción, no daros un código 100% válido y correcto.

Ahora, solo tendremos que añadir al controller de la aplicación un método para cuando llegue por “/ajax/” que:

  • Defina la constante AJAX = TRUE4.
  • Coja la información pasada por la variable json del segundo parámetro y cambie la REQUEST_URI por la url del mismo.
    1
    2
    3
    4
    5
    
    //Algo similar a esto debería valer
    $json = /* variable con la información */
    $ajax = json_decode(stripslashes($json), TRUE);
    $url = $ajax["href"] ? $ajax["href"] : $_SERVER["HTTP_REFERER"];
    $_SERVER['REQUEST_URI'] = str_replace("http://".$_SERVER['SERVER_NAME'], '', $url);
  • Continue de forma normal con el controller

Ahora la navegación para el resto del código es normal, hasta que llegamos a la parte de vista, donde utilizando la contante definida AJAX para saber si el usuario está utilizando AJAX o no y en caso afirmativo mostrar solo la información referente al AJAX que queremos, evitando mostrar por ejemplo la sección de “header” o las secciones fijas del template como el footer… Eso a gusto.

Como veis no es tan difícil añadir después la capa de AJAX y así se consigue una navegación con y sin JS casi-perfecta que facilitará y mucho la vida a navegadores y buscadores.

TODO: como observaréis el código JS está muy sucio y habría que hacer un refactoring completo de él. También habría que añadirle la posibilidad de controlar las anclas que ya existieran en el código (por ejemplo quitándolas y añadiendo un efecto de movimiento en la página al clicar sobre el enlace).

La parte del Controller y la de Vista las he dejado muy abiertas, esto es porque aquí cada maestrillo tiene su librillo, así que no he querido meterme mucho en como lo hago yo para no complicar más las cosas.

Y por último decir que en mi caso empecé usando una constante para definir el AJAX, pero rápidamente deseché esta opción ya que es posible que sobre una página se realicen llamadas sobre distintas secciones por ejemplo y al definir solo una constante esto no se cumple. Aquí lo que suelo hacer5 es pasar la información a través de la variable json(“update”) los campos a modificar, e incluir un código similar a este en el método que controla el AJAX para pasarlo a la parte de vista.

if ($ajax["update"])
{
	$zonas = explode ("::",$ajax["update"]);
	foreach ($zonas as $key => $value)
		$ajax[$value] = true;
}
  1. aka @aartiles
  2. Solo diré que con lo fácil de modificar que dicen que es, por qué los señores de Google no han realizado ya los cambios en su código?
  3. Ojo, que estamos trabajando con Mootools y ClientCide y con un código bastante sucio y obsoleto, por cierto
  4. Esto es ligeramente más complicado, pero para simplificar dejemoslo así por ahora
  5. Aunque también habría que refactorizar ya que no me llega a convencer

Y, que es entonces la nuezAzul?

30
Jun/09
6

Bueno, desde que abrí el blog la semana pasada, mucha gente preguntado:

“Vale, según tú1, eres un fanático de la programación estricta bajo PHP, OOP y el uso de los patrones de diseño (GoF); pero, que es la nuezAzul? A que os dedicáis exactamente?

Bueno, nuestro objetivo es bastante simple en la base.

Desarrollo web avanzado para llevar acabo ‘ideas 2.0′ de forma seria, profesional y de calidad.

Queremos evitar que una buena idea desaparezca y por esto, siempre que nos llega una nos dedicamos al 100% a esta, evitando coger más de una idea a la vez y poniendo así todo nuestro esfuerzo en un solo proyecto.

Y esto, que significa realmente?

Bueno, esto significa que no hay proyecto pequeño; saber que todos los proyectos se van a tratar de igual manera. Se mimarán y desarrollarán manteniendo siempre el mismo “mínimo de calidad“, muy superior a la media de empresas de desarrollo web.

Significa que como cliente, no tendrás que vivir verdaderos calvarios para sacar tu web al mercado, para ver avances en el proyecto o simplemente, para ser informado en todo momento del estado del mismo.

En cierta ocasión leí a @loogictuitear” algo similar a:

¿por qué no existe un Grupo Intercom en Madrid?

La verdad es que me sorprendió dicho tweet, pero es totalmente cierto. Hasta ahora no hay ningún Grupo Intercom en Madrid, y aunque suene a utopía, este es nuestro sueño. Llegar a ser en Madrid (y a nivel naciona, claro), lo que es el Grupo Intercom en Barna.

Ser una empresa donde poder llevar acabo esas ideas innovadoras y desarrollos que requieren una verdadera planificación, un desarrollo eficiente y una escalabilidad máxima para el día de mañana. Ese el objetivo de la nuezAzul, ambicioso, verdad!

Para esto, todos los proyectos los dividimos en varias etapas o fases, informando al cliente en todo momento del estado de su proyecto.

En una primera fase hablaremos, y mucho, de la idea, que quiere el cliente y como quiere rentabilizarlo, que ideas podemos aportar nosotros al concepto, como se puede llevar a cabo… Destriparemos por completo la idea, la reorganizaremos, la reensamblaremos y la potenciaremos todo lo que podamos.

Una vez clara la idea, nos pondremos manos a la obra con el proyecto, buscaremos el usuario objetivo, trabajaremos sobre la interacción y usabilidad del site, buscaremos marcar los ROI del proyecto, haremos la toma de requisitos del proyecto, crearemos la interacción completa del site, los wireframe necesarios, las bases de los libros de estilos

Después de las fases de “recogida de información” el proyecto se divide en tres fases paralelas:

  • Diseño y maquetación final de los bocetos de alto nivel; Dentro de los limites de los wireframes los diseñador tendrán que crear algo acorde a la filosofía del proyecto. Después nos tocará maquetarlo, siempre cumpliendo, en la medida de lo posible2 , con los estandares web establecidos.
  • Programación del proyecto, tanto backend como frontend; Gracias a una toma de requisitos amplia se evitarán errores en la programación, situaciones confusas o errores en la navegación. Facilitando así el objetivo principal, realizar un sito escalable, potente y de calidad.
  • Social/Online Branding de la marca;  Mientras que las fases de diseño y programación están trabajando al máximo, aprovechamos para hacer un poco de “online brandig“, haciendo que empiece a sonar la marca en el mundillo web, que aparezca ya en varios sitios y que la gente empiece a interesarse por ella, incluso antes de que esté terminado el site.

Y por último, entendemos que cualquier proyecto de gran calado, es o debería considerse un “ser vivo“. Por lo que realizaremos un seguimiento continuado del proyecto, donde veremos como crece, hacia donde evoluciona, que cambios hay en los habitos de los usuarios,… Así estaremos siempre preparados y con posibilidad de modificar el proyecto con el entorno.

Está es (no) brevemente nuestra filosofía. Esto es lo que queremos hacer. Suena ambicioso, pero no dudo que podremos llegar a hacerlo. Así, que si te ha interesado, a que esperas para llamar?

</blockquote>
  1. Espero ir demostrandolo con el tiempo
  2. Que mi socio me hecha la bronca. En la medida de lo posible no, se cumplen SI o SI

Cuando las cosas se hacen bien, salen bien.

23
Jun/09
0

Bueno, como hablar de algo sin demostrarlo, es como no hablar de nada, vamos a centrarnos un poco en enseñar como entendemos y programamos un proyecto web desde la nuezAzul. Principalmente porque esta es mi área.

También es cierto que toco un poco algunas de las demás partes de un proyecto; maquetación, accesibilidad y usabilidad (de esto poquito), SEO y SEM, branding online,…. Pero de estas prefiero ir dejando pequeños apuntes técnicos sueltos y centrarme en lo que realmente es mi fuerte, la Programación Web Avanzada. Y si, se puede decir esto y sumarle PHP sin restar el más mínimo poder a la frase.

Y para ello, lo primero es desmitificar a los que piensan que PHP es inseguro y poco profesional; el inseguro y poco profesional es el programador, no el lengjuaje.

El primer problema que encontramos con PHP es su mayor virtud. La anarquía del lenguaje. Este lenguaje se creó principalmente con una máxima; la mayor libertad posible. No es necesario definir variables, no tiene una estructura de programación definida, puede mezclarse dentro de código html o html dentro de código php…

Esto ha hecho que desde un principio, PHP fuese muy suculento para todo el mundo. Tanto programadores profesionales, como amateurs e incluso completos “novatos” de la programación pueden hacer en PHP sus pinitos y programar cualquier cosa.

Claro, esto ha dado muchas lineas de código a PHP, de las cuales la mayoría se podría decir que son basura “no reutilizable” y sobretodo muy inseguras y difíciles de auditar/ampliar. Pero claro, no todo es culpa del código, no se le puede pedir a un newbie que entienda de “Sql Injection” o de calidad de código.

Y como se podría solucionar este problema? Bueno, lo primero aquí es saber que se quiere y distinguir los casos.

  • Si eres un newbie, que solo quiere hacer sus pinitos, adelante, este es tu lenguaje y esto es todo lo que deberías leer de este blog.
  • Si realmente quieres realizar código de calidad y reutilizable, empieza por lo básico. Se lo más estricto posible, estructura el código, declara las varibles al principio de cada método, usa patrones de programación y nunca olvides la flexibilidad de PHP, pero no supedites la calidad a la flexibilidad, hazlo al revés, supedita la flexibilidad a  la calidad

El segundo problema es la rápida evolución del lenguaje frente a la lenta o inexistente evolución del programador. Tanto PHP como Apache y las bases de datos han tenido una evolución estos últimos años bastante fuerte, pasando de, por ejemplo, la programación funcional hasta la implementación de la OOP por parte de PHP, el famoso mod_rewriter de Apache o la potencia de las bases de datos relacionales. Todo esto implica un continuo esfuerzo por parte del programador para estar al día con todo lo que le rodea. Cosa que muchas veces no pasa, encontrandonos con que, por ejemplo, PHP4 no llega a desaparecer ya que implicaría restructurar mucho código o que no existan todavía casi ninguna aplicación que sea 100% OOP sino hibridos entre funcional y OOP.

Solucionar este problema es algo más complicado, cada día vemos actualizaciones de PHP, nuevas funcionalidades y otras decrépitas. Estar al día en esto podría ser algo fácil, pero si además hay que sumar el estar al día en las aplicaciones que usas, en Apache, en la base de datos con la que trabajas, revisando tu código para actualizarlo, … La cosa se complica un poco. Lo malo, esta es la única forma de solucionar el problema, es decir, si quieres realmente hacer buen código cada día, debes emplear cada día en formarte un poco más, y para esto no hay ayudas externas. Cada uno debe tener intención de leer y aprender cada día, sino, en poco más de un año, tu también estarás “decrepit“.

Otro de los defectos es la falta de estructura a la hora de programar, la falta de profesionalidad y de “seguridad de código” en lo que uno hace.  Conozco muchos casos en los que un programador, que entiende y usa la OOP, deja esto de lado porque un “proyecto es pequeño” o porque “no es necesario“. Creando archivos faraónicos, sin estructura alguna en la programación, sin revisar los posibles bugs de la aplicación, … Esto siempre es un error, pero es más error cuando esto pasa de ser para “proyectos pequeños” (Aunque nunca llegue a entender que es eso de proyectos pequeños) y se utiliza en todos los proyectos que uno hace.

El mayor problema que esto acarrea es la imposibilidad del posterior mantenimiento del site, los problemas y el tiempo perdido a la hora de implementar nuevas funcionalidades, o simples cambios en el diseño. Como siempre, el mayor problema aquí es la desfatachez del programador al pensar en el hoy y no el mañana. El mañana serán problemas para el cliente, no para el programador.

Y por último, otro de los grandes errores con PHP, es la suma de todo lo anterior, es encontrarnos proyectos “cajón de sastre” en los cuales, los programadores con buenas ideas y sin tiempo para pensarlas bien, crean proyectos, donde se mezcla funcional con OOP, viendo funciones sueltas entre clases, donde no hay una estructura definida correctamente, donde no se tratan los objetos por paquetes como cualquier otro lenguaje de programación orientado a objetos. Donde se ven funciones obsoletas o donde se ven mezclados, entre grandes ideas, código y html. Dando así grandes “cajones de sastre” de los que no se puede reutilizar gran cosa…

Como se podría solucionar? Lo primero es obviar la programación para todas las versiones y centrarse en PHP5 o superior. Versión a partir de la cual se puede hablar realmente de OOP. Y después de esto, aprender de los demás lenguajes de programación, aprender realmente lo que es el paradigma MVC (o cualquier otro que sea válido) y ponerlo en práctica, no pensar que existe un proyecto pequeño, todos son igual de importantes, pues son tu carta de presentación, usar PHP igual que usarías Java o C++ y sobretodo

TENER RESPETO, MUCHO RESPETO, TANTO A TU TRABAJO, COMO A QUIEN PAGA POR ÉL.

Positions by Seo-Watcher