Translate

sábado, 16 de noviembre de 2013

Cometer errores no es malo, no aprender de ellos es el mayor ERROR.

El tiempo es oro, pero a veces, parar y meditar hacia donde vamos y lo que esperamos conseguir nos evitará perder mucho más tiempo. Comparto con todos los que lo deseen uno de esos momentos en que he parado :

Error 1:

Cuando empezamos a desarrollar PYMETRICK hace dos años, solo era una idea sin formas. Una medicina que resolvería todas las limitaciones que existían con cualquier otro producto sobre el que fijábamos la mirada. Una navaja suiza con muchas herramientas preparadas para un desierto, el polo norte o bajo el océano - primer error -.

Simplificar la idea no fue sencillo, viajamos con demasiado equipaje. La idea debió pasar por filtros de eliminar, reducir, modificar y crear lo necesario. En estos procesos hemos descubierto cuanta basura somos capaces de generar y la falta de ideas simples.

Durante el desarrollo ha variado significativamente la filosofía del proyecto, no buscamos resolver todas las limitaciones que existen en otros productos, solo resolver los problemas del día a día que nos encontramos en el 75% de los proyectos. Siempre existirán problemas que no existían, para los que no es posible buscar medicinas. Igual que en los seres vivos, debería crearse el remedio cuando existiera la infección, no antes.

Solución 1 : 

No hemos creado código innecesario, ya habrá tiempo de crear código especializado.

Error 2:

Competir con el resto de las herramientas disponibles de una forma mucho más simple era un aspecto de la idea inicial. Herramientas que llevaban un tiempo considerable en el mundo y que acumulaban una historia de éxitos y sombras, con detractores y seguidores.  Buscar colaboración o ideas o aportaciones en un mundo tan polarizado - segundo error -.

Todo llevaba a Django, Twister, Tornado, WEB2PY,...(perdón si eres seguidor de cualquier otra herramienta o librería y no la he relacionado aquí, todas se merecen mi reconocimiento), existe un gran esfuerzo detrás que las ha hecho posibles, pero han perdido la SIMPLICIDAD.

Si nuestras necesidades tienen pocos requerimientos, deben mantenerse fácilmente - porque siempre existirán los errores (bugs) -, su desarrollo debe ser simple, mejorando los resultados de forma continua hasta conseguir un producto entregable. Este objetivo solo es posible con librerias simples que soporten todos los aspectos del desarrollo, con una documentación sencilla y accesible. Bastante esfuerzo exige un proyecto, pero si además tenemos multiples herramientas a conectar para conseguirlo, será traumático cada vez que un mantenedor o grupo de desarrolladores cambien las especificaciones de alguna de las librerías empleadas.

Solución 2:

Divide las actividades a realizar en módulos independientes según el sentido común, busca la utilidad simple de cada módulo. El código se puede mejorar para conseguir mejores resultados pero no compliques su legibilidad.

Error 3:

Mejorar lo que existe, exige mirar los problemas de una forma diferente. Si sabes cómo usar un martillo, todos los problemas tienen forma de clavo. - tercer error -

Todos los proyectos no son iguales ni exigen los mismos requerimientos en velocidad, seguridad, ...consumir un poco de tu tiempo en estos aspectos, puede liberarte de gran esfuerzo. Seguir el mismo camino de siempre no te llevará a un destino diferente.

Solución 3:

Si necesitas realizar proyectos sencillos - el 90% de ellos lo serán - no incorpores mas codigo que el necesario.




Ahora ya podemos seguir.





 



Web en Apache con Python y WSGI (II) - las plantillas (templates)

Buscando la solución perfecta...

Cada uno tenemos una percepción de lo que sería una solución perfecta, hace poco escuchaba a un compañero que para él, la solución perfecta, era disponer de módulos prefabricados siguiendo el ejemplo de los muebles que comercializa una gran multinacional sueca, donde te proporcionan el despiece desmontado y embalado, además de las pequeñas herramientas y tú montas el mueble, en su caso se escusaba en sus nulas dotes como carpintero o ebanista.

Este aspecto llevado a la programación, consistiria en obtener diferentes librerías que se adaptaran a nuestro proyecto y desde esta base, crear nuestro programa. Con el tiempo, las versiones de las librerías pueden evolucionar y esto nos lleva, como poco, a comprobar si todo sigue funcionando o a modificar nuestro proyecto.  Esta falta de control sobre los elementos que componen nuestros proyectos, deberían hacernos pensar y preguntarnos : ¿Es necesario obtener librerias externas para dar solución a todos nuestros proyectos o podríamos crear alguna que esté al alcance de nuestros conocimientos en programación ?  De la respuesta que demos veremos el grado de dependencia del trabajo de otros.

Los templates o plantillas

Si no has leido la primera entrega, es muy recomendable que comiences por el principio 'Web en Apache con Python y WSGI (I)'.

Siguiendo con nuestra serie de artículos para ser autosuficientes en la creación de un miniframework o entorno de programación de aplicaciones WEB para PYTHON, hoy escribiré sobre cómo funciona un sencillo y potente lector de plantillas.

Partimos de que ya existen otras librerías para plantillas web como JINJA, GENSHI, MAKO, sin olvidar DJANGO TEMPLATE SYSTEM, y muchas otras. A menudo otras librerías funcionan como generadores de HTML con muy pocas líneas de código. A partir de esta información, he dividido la lectura de plantillas en varios módulos independientes por su funcionalidad :

a) Comentarios : Quien no escribe comentarios en su código para facilitar su lectura a otros y a si mismo ?
b) Bloques :  En toda plantilla pueden existir bloques <html></html> o <head></head>o <body></body> o <footer></footer>
c) Importar plantillas externas : Siempre es posible que una parte de nuestro código no sufra modificación entre una plantilla y otras, como puede ser una cabecera o un pie de páginas html, este tipo de código se puede escribir una sola vez y luego se importará desde la plantilla que solicite su importación. También nos ofrece la posibilidad de crear plantillas dinámicas o personalizables.
d) Importar ficheros externos : Es posible que deseemos importar ficheros externos que no necesiten ser procesados como plantillas, por ejemplo los artículos de un blog, podrían importarse como texto o bien ya estarían codificados como html.
e) Condicional IF  : A veces necesitamos que una parte de la plantilla se pueda ver o no si se cumplen unas condiciones.
f) Literales o información que no debe ser procesada : Cualquier información literal que deseemos poner en una plantilla y que esté perfectamente estructurada sin necesidad de realizar ningún proceso. Por ejemplo, código html o javascript o css o un texto.
g) Variables : Imagina una página html donde saludamos a todos los que nos visitan y dependiendo de la hora del día indicamos 'buenos días...', 'buenas tardes...' o 'buenas noches...' sería sencillo incluir una variable que posteriormente podamos sustituir por el saludo correcto.

Aunque la siguiente funcionalidad está fuera de un lector de plantillas, en la nuestra incluiremos un generador de formularios para HTML5, muy util, si tenemos en cuenta que los formularios que se crean habitualmente en una página HTML son estáticos y no permiten nada más que ocultar campos o mostrar otros a través de javascript. Nuestro generador debería permitir crear cualquier tipo de formulario con muy poca codificación, pero esto formará parte de una tercera entrega.

Basándome en la codificación empleada en otras plantillas y para no inventar la rueda, emplearemos una notación para envolver la codificación que entenderá el lector de plantillas, siguiendo la misma clasificación anterior por actividad :

a)       p.e.:
b)  {%block ....%}   ...    {%endblock ....%}     p.e.:  {%block head%} y  {%endblock head%}
c)  {%include  ...  %}   p.e.:  {%include  nombre_de_plantilla.tpl %}
d)  {%merge ... %}      p.e.:   {%merge mi_articulo.txt %}
e)  {%if       {%else   {%endif}
     {%for      {%endfor}
f)  {%literal%}  ...   {%endliteral%}
g)  {{  ...  }}     envolverán el nombre de una variable a sustituir
     <%  ...  %>  encierran comandos
    <  >...</  >    encierran código html que no necesita ser procesado.

Además, es importante identificar los ficheros de plantillas con una extensión, en mi caso he decidido usar .tpl .

Un fichero de plantilla que luego procesaremos para ver el resultado (login.tpl):

login.tpl


{%include head.tpl%}
{%block body%}
{%literal%}<form>
<div>
<div>
</div>
<div>
<i><label for="email">Email</label></i>
<i><input id="email" placeholder="Email" type="email" />
</i></div>
<div>
</div>
</div>
<div>
<div>
</div>
<div>
<i><label for="password">Contraseña</label></i>
<i><input class="form-control" id="password" placeholder="Contraseña" type="password" />
</i></div>
<div>
</div>
</div>
<div>
<div>
</div>
<div>
<div>
<i><label>
<input type="checkbox" /> No cerrar sesión
</label></i></div>
<div>
</div>
</div>
</div>
<div class="form-group">
<div >
</div>
<div >
<i><button type="submit">Entrar</button></i></div>
<div>
</div>
</form>
{%endliteral%}
{%include footer.tpl%}
{%endblock body%}


Observe que no existen lineas en blanco entre el código de login.tpl, esto es importante porque nuestro lector será más rápido si no tenemos que emplear controles adicionales para las líneas sin información.  Pero deberíamos implementar algún tipo de control para avisar de que existen líneas sin información y subsanar el error.

También comprobará que existe {%include head.tpl%} y {%include footer.tpl%}. Pongamos el código de la plantilla de cabecera y pie :

head.tpl


{%block html|lang="es"%}
{%block head%}
<%title| ecommerce framework from python%>
<%author| Yo mismo%>
<%description|ecommerce %>
<!--Esto es un comentario-->
{%literal%}
<style type="text/css">
body {
padding-top: 40px;
padding-bottom: 40px;
background-color: #f5f5f5;
}
.form-signin {
max-width: 300px;
padding: 19px 29px 29px;
margin: 0 auto 20px;
background-color: #fff;
border: 1px solid #e5e5e5;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
border-radius: 5px;
-webkit-box-shadow: 0 1px 2px rgba(0,0,0,.05);
-moz-box-shadow: 0 1px 2px rgba(0,0,0,.05);
box-shadow: 0 1px 2px rgba(0,0,0,.05);
}
.form-signin .form-signin-heading,
.form-signin .checkbox {
margin-bottom: 10px;
}
.form-signin input[type="text"],
.form-signin input[type="password"] {
font-size: 16px;
height: auto;
margin-bottom: 15px;
padding: 7px 9px;
}
.form-search .input-append .search-query {
border-top-left-radius: 14px;
border-bottom-left-radius: 14px;
margin-top: 5px;
}
.form-search .input-append button:last-child{
border-top-right-radius: 14px;
border-bottom-right-radius: 14px;
margin-top: 5px;
}
/* Footer-------------------------------------------------- */
.footer {
text-align: center;
padding: 30px 0;
margin-top: 70px;
border-top: 1px solid #e5e5e5;
background-color: #f5f5f5;
}
.footer p {
margin-bottom: 0;
color: #777;
}
.footer-links {
margin: 10px 0;
}
.footer-links li {
display: inline;
padding: 0 2px;
}
.footer-links li:first-child {
padding-left: 0;
}
</style>
<!-- librerías opcionales que activan el soporte de HTML5 para IE8 -->
<!--[if lt IE 9]>
<script src="js/html5shiv.js"></script>
<script src="js/respond.min.js"></script>
<![endif]-->
{%endliteral%}</i></span>


y footer.tpl


{%block footer%}
      <!-- /container -->
      </i></span>
</i></span></code>
<div>
<code><span style="font-size: small;"><i><span style="font-size: small;"><i>
</i></span> <span style="font-size: small;"><i>          <!--Sidebar content--></i></span></i></span></code>
<code><span style="font-size: small;"><i><span style="font-size: small;"><i>      </i></span></i></span></code></div>
<code><span style="font-size: small;"><i><span style="font-size: small;"><i>
      </i></span></i></span></code>
<div>
<code><span style="font-size: small;"><i><span style="font-size: small;"><i>
</i></span></i></span></code> <code><span style="font-size: small;"><i><span style="font-size: small;"><i>          </i></span></i></span></code>
<div class="pull-right">
<code><span style="font-size: small;"><i><span style="font-size: small;"><i><a href="http://www.blogger.com/blogger.g?blogID=3486515094464098746#">Inicio</a></i></span></i></span></code></div>
<code><span style="font-size: small;"><i><span style="font-size: small;"><i>
</i></span></i></span></code> <code><span style="font-size: small;"><i><span style="font-size: small;"><i>      </i></span></i></span></code></div>
<code><span style="font-size: small;"><i><span style="font-size: small;"><i>
      <div>
          <!--Sidebar content-->
      </div>
      <div>
          © 2013 BTKS ·
<a href="http://creativecommons.org/licenses/by-nc-sa/3.0/deed.es_ES" rel="license"><img alt="Licencia de Creative Commons" src="http://i.creativecommons.org/l/by-nc-sa/3.0/88x31.png" style="border-width: 0;" /></a>
<span href="http://purl.org/dc/dcmitype/Dataset" property="dct:title" rel="dct:type" xmlns:dct="http://purl.org/dc/terms/">ΡΥΜΣΤrick</span> by <a href="http://www.blogger.com/www.betaksistemas.es" property="cc:attributionName" rel="cc:attributionURL" xmlns:cc="http://creativecommons.org/ns#">Yo mismo</a> is licensed under a <a href="http://creativecommons.org/licenses/by-nc-sa/3.0/deed.es_ES" rel="license">Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 Unported License</a>.
</div>
  {%endblock footer%}
   <!-- Placed at the end of the document so the pages load faster -->
  <!-- Librería jQuery requerida por los plugins de JavaScript -->
  <script src="js/jquery.min.js"></script>



Verá que al final no he cerrado el bloque, no es necesario, el lector de plantillas cerrará la etiqueta correctamente al generar el código html.

En el siguiente artículo veremos otro elemento esencial, el enrutado de solicitudes web o simplificando 'ENRUTADOR'.

8/6/2014
En estas fechas ya he liberado la primera versión en desarrollo de PYMETRICK donde podrá encontrar un módulo TEMPLATE.py, además de otros muchos de los que hablaremos.

jueves, 5 de septiembre de 2013

PYMETRICK comienza a ser una realidad...

Todo proyecto comienza con una idea, a veces despues de aglutinar muchas pequeñas ideas y sugerencias.

Somos incorformistas por naturaleza, aunque en algún caso se haya olvidado. Buscamos pero siempre hay un pero..., puede servir lo que hay, pero le falta..., no tengo nada mejor...pero en cuanto pueda. Esta idea surgió de todas las ideas que nunca encontraban un refugio estable.

Un largo camino, muchos libros, ayuda desinteresada ( que agradezco infinitamente a Eugenia Bahit por sus magníficos artículos y cursos ) y mucho esfuerzo, han comenzado a dar respuestas. Ahora solo debe crecer algo más y comenzará a andar solo ( con licencia GPL debajo del brazo ) es lo menos que puedo hacer en respuesta a toda la ayuda recibida.

Todos necesitamos un Pepito Grillo que nos haga aterrizar cuando perdemos el camino...César gracias. Marcarnos objetivos y cumplirlos, que no es poco.

Hoy comienza a funcionar PYMETRICK formado por código desarrollado con un objetivo muy claro: proporcionar productos sencillos, parametrizables, con fácil mantenimiento. Todavía nos queda camino, pero el que pisamos ahora es de asfalto, podremos ir más veloces apostando por la seguridad. Con la versión 0.1 sería demasiado pretencioso ponerlo a disposición de la comunidad PYTHON, pero ese es nuestro objetivo.

¿ Que todavía no sabes qué es PYMETRICK ?  Un motor que nos permite desarrollar proyectos WEB/SOCKET (ecommerce, blog's, formación, publicación de noticias - periódicos - ) pensando en todos los dispositivos disponibles, pero de una forma sencilla - aunque dirigido a programadores - ¿crees que es pretencioso? Seguramente sí, pero si no ponemos metas más lejos, nos quedaremos más cerca de nada.

Como el movimiento se demuestra andando, ya estamos caminando, espero que el camino nos lleve donde queremos.











 




jueves, 11 de abril de 2013

HTML5 y WebStorage. Almacenamiento de datos en local

Hasta el momento, los datos almacenados desde una página HTML solo podían tratarse en 4KB de una coockie o bien, debían tratarse en una base de datos del servidor web.

HTML5 rompe esta limitación y se apoya en navegadores más evolucionados que soportan esta funcionalidad; por tanto, se pueden implementar ya perfectamente en los sitios web que realizamos en la actualidad.

Esta soportado por las siguientes versiones o superiores de cada navegador:
  • IE 8.0+
  • Firefox 3.5+
  • Safari 4.0+
  • Chrome 4.0+
  • Opera 10.5+
  • iPhone 2.0+
  • Android 2.0+

El API WebStorage se divide en dos vertientes, el "SessionStorage", para guardar información que caducará al final de la sesión y el "LocalStorage", que permite almacenar datos que perduren entre distintas visitas del mismo usuario al sitio web.

Ahora un poco de teoría.

API: INTERFAZ STORAGE

Permite acceder a una serie de pares clave/valor, también llamados ítems. Está implementada por los objetos SessionStorage y LocalStorage, explicados más adelante.

Se podría pensar en el objeto como un array asociativo, es decir, un array al que se puede acceder a través de un índice de tipo string (clave) y no necesariamente una posición.

ATRIBUTOS:

length: devuelve el número de pares clave/valor que contiene el objeto. Es de sólo lectura, no es modificable.

MÉTODOS:

key(pos): devuelve la clave que se encuentra en la posición indicada en la variable "pos" que se pasa como parámetro. El parámetro puede ser un literal, es decir, un número, o bien una variable que contenga un valor numérico.

Si la posición es mayor que el número de elementos (length - 1), entonces devuelve null.

getItem(clave): obtiene el ítem del objeto que contiene como clave el valor que se le pasa como parámetro. 'clave' puede ser una cadena de caracteres o una variable de tipo string.

También se puede obtener la clave tomando el objeto como si se tratase de un array asociativo, es decir, storage['clave'] o accediendo como objeto storage.clave.

setItem(clave, valor): comprueba si la clave existe en el objeto, si no existe la inserta y en caso de existir, actualiza su valor al valor que se le pasa como segundo parámetro.

También se puede asignar una clave como si se tratase de un array asociativo, es decir, storage['clave'] = 'valor' o actualizando como objeto storage.clave = valor.

Como curiosidad, decir que los datos se guardan en orden alfabético.

removeItem(clave, valor): comprueba si la clave existe en el objeto, si no existe la inserta y en caso de existir, actualiza su valor al valor que se le pasa como segundo parámetro.

clear(): elimina todos los pares clave/valor del objeto.

SESSIONSTORAGE

Puede guardar información referente a una ventana/pestaña en la que el usuario lleva a cabo una transacción simple, pero podría llevar a cabo múltiples transacciones en diferentes ventanas/pestañas al mismo tiempo.

Para ello se utiliza el atributo sessionStorage. Cabe destacar que los datos se pierden al cerrar el navegador.


LOCALSTORAGE

Puede almacenar información útil para múltiples ventanas/pestañas, que perdura en el tiempo. No se puede compartir de navegador a navegador. Para ello se utiliza el atributo localStorage. En este caso los datos no desaparecen aun cerrando el navegador, únicamente se borrarán haciendo un borrado manual, mediante código, a través de la consola del navegador o borrándolas directamente desde la carpeta en la que se guardan en el SO.

EJEMPLO:

Creamos una página HTML5 y crearemos un ejemplo con LOCALSTORAGE :








<html lang="es">
<head>
.....
<script>
function save()
{
var vnombre = document.getElementById('nombre').value;
var vedad = document.getElementById('edad').value;
var vemail = document.getElementById('email').value;
localStorage.setItem('text_nombre', vnombre);
localStorage.setItem('text_edad', vedad);
localStorage.setItem('text_email', vemail);
}

function load()
{

if (window.localStorage) {

alert(localStorage.length);

var storedValue = localStorage.getItem('text_nombre');
if(storedValue) {
document.getElementById('nombre').value = storedValue;
}
var storedValue = localStorage.getItem('text_edad');
if(storedValue) {
document.getElementById('edad').value = storedValue;
}
var storedValue = localStorage.getItem('text_email');
if(storedValue) {
document.getElementById('email').value = storedValue;
}
} else {
alert('Actualice navegador!!!');
}
}

function remove()
{
document.getElementById('nombre').value = '';
document.getElementById('edad').value = '';
document.getElementById('email').value = '';
localStorage.removeItem('text_nombre');
localStorage.removeItem('text_edad');
localStorage.removeItem('text_email');

// tambien vale
localStorage.clear();
}
</script>

.....
</head>
<body onload="load()">
<form name="formulario">
<label for="nombre"&gtNombre&lt/label&gt&ltinput type="text" name="nombre" id="nombre" />
<label for="edad"&gtEdad&lt/label&gt&ltinput type="text" name="edad" id="edad" />
<label for="email"&gtMail&lt/label&gt&ltinput type="text" name="email" id="email" />
<input type='button' value='guardar' onclick="save()">
<input type='button' value='eliminar' onclick="remove()">
</form>
</body>
</html>

Es un ejemplo muy funcional y sencillo, cada vez que se recarga la página load() preguntará si el navegador soporta LOCALSTORAGE con if (window.localStorage) e indicará cuantos elementos están almacenados alert(localStorage.length); y a continuación carga los datos desde LOCALSTORAGE y los muestra en el formulario.

Solo tiene un botón GUARDAR y otro ELIMINAR, para guardar y eliminar los datos almacenados respectivamente. Cada dato se guardará como una clave/valor diferente, en este caso guardaremos tres claves/valores, aunque con un poco de código es posible guardar muchos valores en una sola clave si fuera necesario.

Cuando la base de datos ha llegado al límite de su máximo contenido ( 5Gb ), se puede comprobar con :

try {
localStorage.setItem('foo', 'bar');
} catch (e) {
if (e == QUOTA_EXCEEDED_ERR) {
alert('el almacén local excede el tamaño máximo permitido');
}
}

RECOMENDACION

Si aún no has encontrado un buen EDITOR para HTML y otros (también útil para PYTHON), te recomiendo SUBLIME TEXT


miércoles, 10 de abril de 2013

Desmontar la Torre de Babel

Es sencillo recorrer el camino que todos pisan, es cómodo, solo debes adaptar tu velocidad, algúnos dirían que llegas antes...todo son ventajas. Otros, los más inquietos, buscarán salirse del camino, orientarse en libertad, disfrutarán con nuevos paisajes antes nunca vistos, huirán del camino marcado que estará demasiado transitado para su gusto.

Mi propuesta intenta tomar lo mejor de los dos, estudiar, copiar, crear e innovar. Para mejorar es necesario aprender y copiar del mejor o de los mejores, trazar nuestro rumbo hacia la innovación y crear algo nuevo a partir de algo antiguo. Aplicando estos conceptos a la construcción de un marco de programación web en PYTHON y después de leer sobre Bottle, Flask, Django, Twisted, Tornado, Werkzeug...estudiar su código, comprobar cómo se resuelven problemas que ni sabía que existían, busco un nuevo camino a mi medida, que me permita aprender y el final del viaje será volver a empezar uno nuevo.

Planificar una serie de módulos que serán muy necesarios para nuestro framework personal, es esencial :
  • (1)¿Cómo gestionar los accesos en el servidor web ? WSGI, SOCKET...
  • (2)¿Cómo crearemos nuestras páginas html, javascript, css?
  • (3)¿Cómo trataremos las solicitudes de rutas y parámetros de nuestro proyecto ?
  • (4)¿Cómo vamos a reconocer a los usuarios que acceden y mantendremos su identidad a salvo?
  • (5)¿Deberíamos adaptarnos a los distintos dispositivos que pueden conectarse a nuestra información de forma dinámica?
  • (6)¿Necesitamos aplicar geobloqueos?¿O redirigir a los usuarios a servicios específicos según su origen?
  • (7)¿Cómo realizaremos una compresión de los datos que proporcionemos?
  • (8)¿Necesitamos un tratamiento en profundidad de imágenes?
  • (9)¿Necesitamos realizar pagos seguros?
  • (10)¿Cuántas conexiones esperamos? ¿Necesitamos un sistema de alto rendimiento para varios millones de accesos?
Más allá de la perfección, pretendo responder a unas necesidades sencillas. Por tanto, buscamos un sistema sencillo y efectivo, lejos de una sobrecarga de módulos :

(1) He decidido usar WSGI sobre un servidor web ( APACHE ), evitaré las complicaciones de un servidor de aplicaciones.

(2) Debemos implementar HTML5, CSS3, JAVASCRIPT y personalizar las respuestas en función del dispositivo que acceda a la información. Es más acertado crear un módulo completo para templates que me proporcione todas estas facilidades.

(3) El sistema debe ser capaz de redirigir la petición de forma correcta y traducir sus parámetros p.ejemplo : www.prueba.es/20130410/francia/editorial/, al recibir esta solicitud podremos comprobar los parametros 20130410, FRANCIA y EDITORIAL, buscando una respuesta válida según una plantilla y en caso contrario, buscar una respuesta por defecto.

(4) Existen varias formas de identificar a un usuario. Principalmente se utiliza una sesión que se almacenará en el servidor y en una cookie en el cliente. También es posible que el navegador del cliente no admita cookies, en este caso deberíamos marcar todas las páginas con el código de la sesión en un datos HIDDEN, de forma que cuando recibamos la respuesta de la página, nos enviará el dato oculto que contrastaremos con la sesión guardada en el servidor.

Con HTML5 se abren otras posibilidades más extensa con sessionStorage, localStorate o genéricamente webStorage. Con las nuevas incorporaciones de HTML5 podríamos almacenar en modo local (CLIENTE) información en tablas de una base de datos local y persistente (persistente por dominio), podríamos aplicar mejoras en carros de compra, agendas, webmail,...

(5) Un módulo específico que sabe leer las cadenas de identificación de cada navegador 'user agent', donde se puede obtener el idioma o idiomas aceptados, sistema operativo, dispositivo, motor, navegador y versión. Toda esta información puede ser complementaria de otras que obtengamos mediante javascript, como tamaño de la pantalla y resolución. Adaptando la información de salida, para la que también se tendrá en cuenta, la información obtenida de otros módulos.

(6) Cada día es más importante tratar información geográfica en las comunicaciones, a veces para evitar ataques, otras para cumplir la legislación de algunos países o para comunicar información adaptada.

(7) Habitualmente los navegadores tienen módulos preparados para comprimir los datos enviados y acelerar la información. También podíamos incluir aquí parte del módulo (8), enviar imágenes adaptadas a tamaños o compresión, permitir o negar el cacheo de la información en el cliente, ...etc.

(8) Con un tratamiento de imágenes, me refiero a permitir corregir tamaños de imagen, transformar datos binarios de una imagen a una cadena en BASE64 para incrustarla en código HTML o CSS3 (estas imágenes no se cachean y tienen un plus de protección), permitir adaptar imágenes dinámicamente a cada pantallas de dispositivos,...etc.

(9) Si necesitáramos una plataforma de pago, deberíamos crear un módulo con las funcionalidades necesarias.

(10) Esto todavía está muy lejos de nuestras necesidades, tendrá respuesta a su debido tiempo.

Es posible desanimarse antes de empezar, pero si conseguimos un desarrollo de framework adaptado a nuestras necesidades, habremos contruido nuestra propia herramienta y podremos dotarla de mejoras en un futuro. Por contra, cualquier framework al uso, nos exigirá una mínima formación, práctica y desarrollar nuestros proyectos en función de la disponibilidad de módulos.

Es necesario que tengamos en cuenta unas reglas básicas, un framework o marco de desarrollo, nunca estará totalmente terminado. Se incorporarán nuevos añadidos en función de nuestras necesidades o de proyectos futuros. Y cada módulo siempre será objeto de mejoras en código y eficiencia, lo que permitirá realizar mejoras de forma indirecta en proyectos pasados.

Para escribir todos estos datos, he realizado todo el proceso que indico de forma efectiva y ha concluido con un desarrollo real PYMETRICK, aunque como indico anteriormente, nunca finalizado, y ahora en fase de pruebas. Con el tiempo, los módulos serán objeto de artículos más detallados.
PYMETrick