Archivo de la categoría ‘Desarrollo web’

Gestión del proceso de login con tokens

martes 10 de octubre de 2017

El uso de tokens en API REST es un método que proporciona mucha facilidad a la hora de controlar los accesos a diferentes rutas del servidor.

De manera resumida de procedimiento consiste en:

  1. el usuario envía sus credenciales al servidor (usuario/contraseña).
  2. el servidor comprueba la autenticidad y generar un token. La generación es un proceso más o menos complejo que escapa al objeto de este post, pero para el que tenga curiosidad puede seguirlo aquí.
  3. el token generado es enviado al cliente.
  4. en la siguientes peticiones, el cliente envía el token que le identifica y, en el caso de que sea correcto, el servidor manda los datos que se le solicitan.

En principio la forma de enlazar todos estos pasos no requiere de demasiada explicación (si no tenemos en cuenta el proceso de generación y verificación del token), pero se complica en el momento en el que queremos que validación correcta de credenciales redirija a otra página (por ejemplo el tablero de configuración del usuario).

¿Qué problemas aparecen?

La primera opción que se nos plantea es la de utilizar AJAX para enviar las credenciales, redireccionar a la página que nos interese y recibir el token. Desgraciadamente, si la petición es vía AJAX el cliente espera recibir contenido o información para cargar en la misma página (no ambas cosas)  y por lo tanto la redirección no funciona.

Otra opción sería no redireccionar sino enviar el documento html y, vía jQuery, cargar el documento utilizando la función $(“html”) .html. En este caso el problema radica en que se produce fallos en la carga con jQuery y que además no pasamos el token.

Un cambio de enfoque es más funcional aunque produce más acoplamiento y, desde mi punto de vista, es menos elegante: enviar vía AJAX las credenciales, recibir el token y desde el propio cliente redireccionar a la URL que nos interesa. Este sistema necesita que el cliente sepa de la necesidad de cambiar de URL, es decir, requiere tener conocimientos de lo que quiere hacer el servidor.

Al final la opción que más me convence es la de enviar vía POST de manera síncrona (mediante un formulario) los datos de las credenciales y contestar con la página que deseamos que se muestre, pasando en el HEADER de la respuesta (ya sea mediante un campo oculto o mediante una cookie) el token que necesita el cliente.

+Info: Autenticación de aplicaciones con tokens
+Info: ¿qué es la autenticación basada en tokens?

 

Instalación Cordova/PhoneGap

lunes 28 de julio de 2014

Apache_Cordova1

En general la instalación de Cordova no resulta muy complicada, pero si es verdad que con la aparición de la versión 3.x resulta un poco más compleja que las anteriores. Es posible encontrar por la red tutoriales sobre la instalación en MacOS y Windows, pero cuesta más encontrarlos sobre Linux.

Los pasos se han realizado en un Linux Mint, pero debería ser posible realizarlos sin problemas en cualquier distribución basada en Debian.

1. Instalación del entorno de desarrollo. Al trabajar con Linux tenemos la posibilidad de poder instalar los SDK de Amazon, Android, Blackberry10, Firefox OS y Ubuntu, aunque nosotros nos vamos a centrar en la instalación de Android. Puedes seguir los pasos de la instalación desde aquí. En caso de que el SDK ya esté instalado es conveniente actualizar a la última versión del SDK y del SDK-tools

Desde MacOS tenemos también la opción de instalación del SDK de iOS, para lo cual es necesario instalar XCode.

2. Instalación de Node.js. En principio puede ser instalado directamente desde el propio gestor de paquetes que la distribución tenga (synaptic o similar), pero es importante tener en cuenta dos cosas.

  • La primera es la versión a instalar. Normalmente en el gestor puede haber una versión antigua, por lo que es interesante incluir el ppa correspondiente para estar al día.
  • Lo siguiente es que hay que tener en cuenta que el paquete npm (el instalador de paquetes de Node) se encuentra en un paquete distinto a Nodejs, por lo que hay que recordar instalarlo.

En MacOS la instalación simplemente consiste en descargar el paquete desde la web de nodejs e instalarlo.

3. Instalación de phonegap. Simplemente

sudo npm install -g cordova

Una vez completada la instalación lo mejor es comprobar que todo el sistema funciona correctamente. Para ello lo primero es crear un proyecto.

  • Desde un terminal vamos a la carpeta en la que queremos alojar el proyecto. En caso de estar con MacOS podemos arrastrar desde el finder el icono de la carpeta a un terminal.

cordova create hello com.ejemplo.hello HelloWorld

siendo hello la carpeta que crearemos, HelloWorld el nombre del proyecto y com.ejemplo.hello el paquete

  • Creamos las plataformas, es decir las estructuras de los proyectos para cada una de las plataformas en la que queremos crear la aplicación. En este caso sólo hemos instalado los SDK de Android, luego sólo podremos generar para esa plataforma. Entramos dentro de la carpeta creada (en nuestro caso hello) y desde allí:

cordova platform add android

En MacOS podríamos crear también para iOS.

cordova platform add ios

 Al añadir el proyecto en Android es posible que aparezca algún error. Casi seguro que es porque o no se ha instalado el SDK o no está en el path. Si has hecho el paso 1, el problema será el path. Para añadirlo:

export ANDROID_HOME=/carpeta/donde/esta/instalado/sdk
export PATH=$ANDROID_HOME/tools:$PATH
export PATH=$ANDROID_HOME/platform-tools:$PATH

  • Construimos las plataformas:

cordova build android

A partir de ese momento ya podemos ejecutar la aplicación, ya sea en un emulador o en un dispositivo. Por eficiencia lo mejor es conectar un dispositivo Android y ejecutar :

cordova run android

En el caso que quisiéramos probar con el emulador el comando sería:

cordova emulate android



PhoneGap/Cordova: desarrollo de aplicaciones móviles multiplataforma

martes 8 de julio de 2014

Apache_Cordova1

 

Con toda seguridad el requisito más importante de VisualDomo sea la necesidad de que corra en varias plataformas móviles sin ser necesario la creación desde cero de una nueva aplicación. La clave está en el uso de PhoneGap/Cordova.

¿Qué es PhoneGap?

De manera resumida, PhoneGap es un framework para la creación de aplicaciones móviles multiplataforma. Es decir su objetivo es crear un único código y que este pueda funcionar en distintas plataformas móviles como iOS, Android, Blackberry, FirefoxOS, Windows Phone… Suena bien, ¿verdad?

En general para conseguir un objetivo así, la idea es crear aplicaciones web con HTML5, CSS3 y javascript que corran sobre un navegador. Evidentemente este método proporciona multiplataforma, pero por contra hace las aplicaciones más lentas (necesitan al navegador entre ellas y el SO) y, por motivos obvios de seguridad, limita el acceso a varios recursos como la cámara, el acelerómetro, etc.

Para solucionar en parte este problema PhoneGap permite la creación de aplicaciones híbridas, es decir, añadir ciertos componentes (que llama plugins) que conectan de manera nativa con esos recursos. Lógicamente esto hace que la aplicación pierda la posibilidad de ser multiplataforma, pero la manera de migrar a otras plataformas queda únicamente reducida a crear los plugins en ellas. Estos accesos se desarrollan en javascript, que si permite la llamada a código nativo (ya sea Java, C, C++…)

De esta manera una aplicación desarrollada con PhoneGap no es una simple página web, sino que que es una aplicación nativa (un apk si hablamos en sistemas Android) que en su interior lleva un componente visualizador Web (WebView), las páginas web creadas y los plugins de acceso a los recursos.

Por otra parte, para entender el concepto de framework podemos relacionarlo con Java o .NET. Este concepto incluye herramientas que ayudan al proceso de compilación, API’s, etc. y que generalmente se ejecutan sobre una máquina virtual. En este caso podríamos hacer la relación de máquina virtual/webView. Para entenderlo mejor podemos ver el esquema de bloques de una aplicación PhoneGap.

Esquema phonegap

El bloque UI framework no es necesario. Obviamente podemos desarrollar las aplicaciones desde cero con CSS3 y Javascript, pero es obvio que si ya hay diferencias entre distintos navegadores más las puede haber ahora que entra además el factor plataforma. Es por ello que resulta muy interesante el uso de algún tipo de librería como JQuery mobile que ayude de a la creación sencilla del interfaz.

Por último queda otro pequeña confusión a aclarar: ¿qué es Apache Cordova y que tiene que ver con PhoneGap? Durante todo el post he hablado de PhoneGap, pero realmente tendría que haberlo hecho de Apache Cordova. PhoneGap fue desarrollado por Nitobi, empresa que al poco tiempo fue comprada por Adobe. Adobe ha cedido la licencia a la Fundación Apache para liberar el código y asegurar que ese tipo de licencia se mantenga. De esta manera el producto pasó a denominarse Apache Cordova y PhoneGap a ser una distribución del él. No puedo asegurarlo, pero la única diferencia es el servicio de compilación en la nube que PhoneGap ofrece.

VisualDomo: Requisitos

martes 1 de julio de 2014

VisualDomo logo_com7

Antes de empezar a diseñar conviene dejar bien definidos los requerimientos del proyecto, tanto los mínimos como los opcionales

Mínimos

  • No será posible acceder a un ODControl que no esté en la red a la que se encuentre conectado VisualDomo. Dicho de otro modo, no es posible controlar dispositivos externos a la red local. Aún así se preverá un posible acceso futuro a dicha funcionalidad.
  • Posibilidad de trabajar con varios ODControl de una misma red (mínimo 10)
  • El protocolo de comunicación entre VisualDomo y los ODControl será HTTP autenticado (no seguro)
  • En una primera fase, VisualDomo debe correr en plataformas Android. Los cambios entre plataformas deben ser mínimos.
  • Se debe permitir la configuración de localizaciones con varias plantas.
  • La definición de los planos se hará mediante la carga de algún formato gráfico (png, jpg, etc…)
  • La configuración de la localización podrá realizarse off-line.
  • VisualDomo debe guardar las configuraciones de cada localización (puertos, planos, ubicaciones,…) para facilitar una posterior conexión.
  • Identificación sencilla por iconos del tipo y estado de cada puerto.
  • Control de errores con notificaciones en caso de problemas en los ODControl.
  • Los estados serán actualizados de manera automática a los ODControl, aunque también se podrán solicitar de manera manual.

Opcionales

  • La aplicación permitirá trabajar con varias localizaciones si bien al mismo tiempo únicamente con una de ellas. Aplicación SDI (Single Document Interface).
  • Modo multivista en tabletas que permitan visualizar varias plantas de manera simultánea.

Por cierto, en la cabecera ya utilizo el logo de la aplicación, muy inspirado en el logo oficial de OpenDomo. Espero que os guste.

VisualDomo. Entendiendo el problema (II). Objetivos

lunes 23 de junio de 2014

ODControl-logo

 

Después del post anterior donde se presentaba ODControl, el siguiente paso es definir los objetivos a los que se pretende llegar con el proyecto:

El objetivo principal es la creación de una aplicación de código abierto para el control visual de una localización domotizada controlada por uno o varios ODControl. Dicha aplicación debe ser compatible con la gran mayoría de dispositivos móviles independientemente de su plataforma o modelo. Específicamente la aplicación debe:

  • Localizar o permitir configurar los posibles ODControl existentes.
  • Permitir cargar planos de la localización a controlar.
  • Ubicar en los planos los distintos dispositivos a controlar.
  • Guardar las configuraciones para simplificar futuros accesos.
  • Visualizar el estado de los puertos de entrada, ya sean digitales o analógicos.
  • Modificar el estado de los puertos de salida.

En otro ámbito más transversal:

  • Es de desear que la aplicación pueda trabajar en varios idiomas (al menos español e inglés).
  • Diseño responsable. Dentro de las limitaciones de diseño indicadas por los fabricantes de los sistemas se pretende que el diseño de la aplicación se adapte al entorno hardware en el que está siendo ejecutado (móvil, tableta o navegador en equipo de sobremesa).
  • Se tendrá especial cuidado en conseguir alta usabilidad.

Existen otros objetivos relacionados con la visibilidad del proyecto:

  • El código del proyecto será publicado en alguna comunidad virtual, en este caso GitHub.
  • Documentar el código de tal manera que simplifique la continuidad del trabajo por parte de otros usuarios. Para facilitar la internacionalización de esta labor dicha documentación se hará en inglés.
  • Se pretende realizar un seguimiento del proyecto mediante el desarrollo de un blog que muestre tanto el proceso de diseño como el de programación. Dado el carácter abierto de VisualDomo se espera que, junto con la publicación del código, el blog facilite la labor de hacer crecer el desarrollo inicial del mismo.
  •  Publicación en las principales tiendas electrónicas de aplicaciones (Google Play, App Store...)

 

 

VisualDomo. Entendiendo el problema (I)

viernes 20 de junio de 2014

Como en cualquier otro proyecto, el primer paso a realizar es conocer bien el problema al que nos enfrentamos y definir correctamente adonde queremos llegar. Obviamente en nuestro contexto el protagonista principal es ODControl.

Controlador IP

De manera sencilla, un ODControl es un controlador IP. Un controlador es un sistema electrónico que, como su nombre indica, permite controlar un conjunto dispositivos eléctricos que puede ser conectados a él, para lo cual dispone de una serie de puertos ya sean por una parte de entrada o salida y por otra, analógicos o digitales.

El hecho de ser IP lo convierte además en un dispositivo que puede ser conectado a un red IP, posibilitando el acceso desde otro dispositivos de la red y,  mediante un navegador web, una consola ssh o cualquier otro método, acceder a las funciones que disponen sus entradas y salidas.

Por ver un ejemplo gráfico, el esquema de una supuesta instalación completa (y básica) para controlar un sistema de iluminación podría ser:

esquema-controlador

El controlador IP (C-IP) está conectado mediante Ethernet a un modem-router que, por una parte, da salida/entrada a internet y por otra funciona como punto de acceso WiFi. Además el C-IP conecta una de sus salidas a un relé (R1) que hace las funciones de interruptor y que a su vez estará conectado a la fase y al punto de luz a controlar. Dicho control (apagado/encendido) se podrá realizar desde el dispositivo móvil.

ODControl

ODControl es el controlador IP que comercializa OpenDomo Services S.L.. En el momento de desarrollo del proyecto, OpenDomo Services S.L. tiene disponibles dos versiones (la 1 y 2).

ODControl-picture

Para nuestro objetivo, no es necesario entrar en detalle en varias de las especificaciones técnicas de cada una, si bien es interesante saber las funcionalidades de ambos productos, especialmente en la versión 2 que es en la que nos centraremos en un primer momento.

 

ODControl 1

ODControl 2

Parámetro

Valor

Parámetro

Valor

Número de salidas digitales

8

Número de salidas digitales

8

Número de entradas digitales

8

Número de entradas digitales

8

Número de entradas analógicas

8

Número de entradas analógicas

2

Número de salidas analógicas

0

Número de salidas analógicas

2

Bus IP (RJ45)

1

Bus IP (RJ45)

1

Protocolos

UDP, HTTP

Protocolos

UDP, HTTP

Puertos virtuales

48

Puertos virtuales

61

 

Obviamente, el número de puertos es limitado luego según las necesidades de la instalación puede ser necesario utilizar para cada una de las localizaciones más de un ODControl.

La configuración de cada ODControl se realiza accediendo mediante un navegador web a la dirección IP asignada al controlador (por defecto 169.254.0.15), lo que da acceso a la aplicación Configurator. Desde ella es posible visualizar el estado de los puertos digitales de salida y de entrada, pero también podremos configurar los puertos, ejecutar comandos o realizar tareas de mantenimiento (cambio de IP’s, contraseñas, nombre, etc)

Para simplificar la configuración, ODControl permite el uso de plantillas predefinidas. El usuario puede crear las que desee y posteriormente replicarlas en otros de sus ODControl o descargar desde el sitio web de OpenDomo aquellas que le resulten interesantes y que otros usuarios han compartido. Así, por ejemplo, si deseamos una instalación para el control de 8 puntos de luz (plantilla que podemos encontrar en la web) la configuración de los puertos (asignar nombres a los puertos de entrada, activarlos… ) simplemente se reduce a cargar la plantilla.

Además de los puertos físicos ODControl también posee puertos virtuales. Estos puertos permite el almacenamiento de manera temporal o persistente de valores para ser utilizados posteriormente. El valor que guardan puede venir calculado por alguna operación booleana o aritmética entre otros dos puertos, por la finalización de un disparador (día, fecha o cuenta atrás) o el resultado de una operación de comparación donde el puerto virtual se activará (1) en caso de que la condición sea cierta.

Por último, el ODControl posee una gran cantidad de comandos que puede ser ejecutados desde el propio Configurator o mediante llamadas externas al puerto 81 utilizando el protocolo HTTP. Este tipo de comunicación va autenticada pero no cifrada, por lo que únicamente resulta conveniente su uso en entornos controlados. Como se verá a lo largo del desarrollo este va a ser el principal mecanismo de comunicación entre VisualDomo y ODControl.

+Info: Comandos ODControl
+Info: OpenDomo Lightweight Encryption Protocol (ODLEP)

Un nuevo proyecto: VisualDomo

viernes 13 de junio de 2014

logoODS

Tras unos meses de sequía por compromisos varios, en los próximos meses voy a desarrollar un nuevo proyecto: VisualDomo,una aplicación para dispositivos móviles que permite el control de manera visual de dispositivos ODControl.

ODControl es un controlador con posibilidad de conexión IP desarrollado por la empresa OpenDomo Services S.L.. Este controlador permite actuar sobre diferentes dispositivos electrónicos gracias a varios puertos tanto de tipo analógico como digital, lo que lo hace muy adecuado para el control de instalaciones domóticas.

El objetivo del proyecto es facilitar al usuario el manejo de su instalación domótica, permitiendo definir su localización mediante la carga de planos y controlar cada uno de los aparatos conectados a los puertos de manera sencilla.

Las propia idiosincracia del proyecto implica la posibilidad de abarcar el mayor número posible de dispositivos móviles existentes, no únicamente por configuración física (tabletas o móviles) sino también por la variedad de plataformas existentes. Además los productos OpenDomo están en constante evolución, lo que hace complicado el mantenimiento de varias aplicaciones. Por todo ello se ha decidido utilizar para el desarrollo el framework PhoneGap/Cordova, que permite mediante tecnologías web (HTML5+JS+CSS3) crear un único código fácilmente compilable en distintas plataformas.

Además de su valor empresarial, el proyecto también tiene carácter académico y educativo ya que se presenta como Trabajo Final del Master Universitario de Software Libre, impartido por la Universitat Oberta de Catalunya (UOC).

La idea es  crear durante estos meses una serie de posts que hablen sobre el proceso de creación, centrándome especialmente en la parte técnica.

+Info: opendomo
+Info: ODControl
+Info: cordova
+info: Univesitat Oberta de Catalunya

Configuración y uso de rsync contra un Ubuntu Server

martes 3 de enero de 2012

rsync es una aplicación que se puede encontrar en vuestros sistemas Linux, MacOS o  Windows y que permite sincronizar archivos y directorios entre dos máquinas de una red o entre dos carpetas de una misma máquina. Su uso es sencillo y es ideal para mantener al día copias de elementos utilizados por varias personas,  hacer copias de seguridad de nuestros datos de manera rápida y segura o mantener actualizada nuestra página web.
Puede funcionar de dos maneras:

  1. Instalando un daemon (un servicio) en nuestro servidor (donde tenemos los elementos a sincronizar) al cual accederemos mediante el protocolo rsync.
  2. Mediante un terminar remoto como SSH

Caso 1.El objetivo es instalar un daemon en nuestro servidor que atienda las peticiones de sincronización. Para ello los pasos a seguir son:

1.a) Instalar rsync. En general viene instalado de serie, y más en una versión server de Ubuntu, pero si no fuera así simplemente instálalo con Synaptic o mediante:

sudo apt-get install rsync

1.b) Hay que crear el fichero de configuración del daemon “/etc/rsyncd.conf”. En él definimos las caracterísiticas generales de la conexión, así como las de cada uno de los módulos o,  para definirlo mejor, las posibles ubicaciones de sincronización. El fichero tendrá una forma similar a esta

max connections = 2
log file = /var/log/rsync.log
timeout = 300

    [nombremodulo1]
    comment = Carpeta de documentos personales sobre Linux
    path = /carpeta/sobre/la/que/sincronizo/los/documentos/personales
    read only = yes
    list = yes
    uid = usuario1
    gid = usuario1  
    auth users = usuario1
    secrets file = /etc/rsyncd.secrets

    [nombremodulo2]
    comment = Carpeta de documentos Uhuru
    path = /carpeta/sobre/la/que/sincronizo/los/documentos/uhuru
    read only = yes   
    list = yes   
    uid = nobody
    gid = nogroup   
    auth users = usuario1 usuario2
    secrets file = /etc/rsyncd.secrets

Al principio del fichero se definen aquellas características generales de la conexión. En este caso aparecen el número de conexiones simultáneas, donde se va a ubicar el fichero log y el tiempo máximo de espera. En esta parte es posible indicar también algunas de las características que aparecen en los módulos para que todos ellos la hereden (salvo que se redefinan dentro de uno en concreto). Por ejemplo, en el código anterior, podríamos haber escrito en las características generales la configuración de secrets file o la opción list, ya que su valor es común para todos los módulos.

A continuación aparecen la definición y características del módulo. Los elementos más importantes son:

  • comment: un comentario sobre que se sincroniza con ese módulo.
  • path: el camino completo de la ubicación.
  • uid: nombre del usuario con el que rsync realizar las acciones.
  • gid: grupo con el que rsync realizará las acciones.
  • auth users: usuarios a los que se les está permitido la sincronización. Estos usuario en principio no tiene porque coincidir con ningún usuario del sistema.
  • secrets file: lo vemos en el apartado siguiente.

1.c)  Crear el fichero “/etc/.rsyncd.secrets”. Este fichero almacena parejas usuario:contraseña, que hacen relación a los usuarios definidos en el fichero “/etc/rsyncd.conf”. En nuestro caso podría ser algo como esto:

usuario1:mipassword1
usuario2:mipassword2

Obviamente este fichero, al ser texto plano,  ha de ser protegido contra “mirones”, ya que en caso contrario nuestras contraseñas quedan fácilmente accesibles. Es más rsync ni siquiera funcionará si no asignamos unos permisos adecuados a este fichero. Para ello:

sudo chmod 600 /etc/rsyncd.secrets

Es decir, el propietario debe ser el root y sólo puede ser leído por él.

1.d) Una vez configurado, sólo nos queda arrancarlo. Para ello lo mejor es utilizar xinetd, otro de los demonios que podemos encontrar en linux y que permite gestionar las conexiones de otros demonios bajo demanda.

Para ello lo primero es instalarlo (si es que no lo tienes aún):

sudo apt-get install xinetd

1.e) Configurar xinetd. Si no existe crea el fichero “/etc/xinetd.d/rsync” con el contenido siguiente.

service rsync
{
    disable = no
    socket_type = stream
    wait = no
    user = root
    server = /usr/bin/rsync
    server_args = --daemon
    log_on_failure += USERID
}

1.f) Comprobar el puerto por el que el servidor rsync escuchará. Para ello ves al fichero”/etc/services” y comprueba que la siguiente línea existe y no está comentada:

rsync 873/tcp

1.g) Reinicia el daemon xinetd. Para ello:

sudo /etc/init.d/xinetd restart

1.h) Ya tenemos el servidor funcionado. ¿Como lo usamos?. Sencillo, en local ejecutamos:

rsync -v --recursive --times --perms --links --delete /mi/carpeta/personal/local rsync://[email protected]/nombremodulo1

donde estamos haciendo una sincronización recursiva, preservando fechas y permisos de los archivos origen, incluyendo vínculos, borrando archivos que fueron borrados en el directorio origen. Todo ello desde un directorio origen /mi/carpeta/personal/local y utilizando el protocolo rsync contra el servidor miservidor, con el usuario1 y utilizando el módulo nombremodulo1

Caso 2. La segunda opción consiste en la utilización del terminal remoto seguro ssh.

El proceso de creación de clave pública y privada y configuración del terminal escapa de este tutorial.

En este caso no es necesaria la configuración del demonio en el servidor, tan sólo que rsync esté instalado en él. Para ejecutar la sincronización:

rsync -v --rsh=/usr/bin/ssh --recursive --times --perms --links --delete /mi/carpeta/personal/local [email protected]:carpeta/destino/servidor

Uploadify: Subida de archivos con jQuery

jueves 31 de marzo de 2011

La última página web que hemos creado en Uhuru Labs, Navarro y Soler CAD-PLM Software, requería una sección donde los usuarios de la web pudieran mandar a nuestro cliente ficheros de un tamaño considerable. Teniendo este requerimiento empezamos a investigar por la red buscando algún uploader que no fuese el simple formulario de subida de ficheros, sino que proporcionara algo más, aparte de ser fácilmente configurable.

Enamorados como estamos de jQuery y de todo lo que lleva consigo esta potente librería en javascript, buscamos algún uploader que estuviera hecho a partir de jQuery y encontramos Uploadify. Un pequeño vistazo por encima nos hizo darnos cuenta de las grandes posibilidades que tenía este pequeño trozo de código.

Al estar utilizando WordPress como backend primero miramos si había algún plugin hecho ya que nos facilitara las cosas. Encontramos uno, pero no conseguimos hacerlo funcionar, así que lo pusimos a pelo en la plantilla que estábamos creando. Nos basamos en la última versión que tiene uploadify ahora mismo estable, la 2.1.4, ya que la beta 3.0 carecía de documentación y no queríamos embarrarnos las manos con cosas no probadas.

Una vez bajado el archivo comprimido con todos los archivos necesarios, descomprimimos en la carpeta de nuestro tema. Con lo que quedaría todo dentro de una carpeta, en nuestro caso la llamamos uploadify.

Entonces hicimos la carga de los archivos .js necesarios y de la hoja de estilos .css. Nosotros siempre cargamos las hojas de estilo en la etiqueta <head>:

<link rel="stylesheet" type="text/css" media="all" href="<?php bloginfo( 'template_url' ); ?>/uploadify/uploadify.css" />

y la carga de los archivos javascript lo hacemos en el footer.php, justo antes del cierre del tag <body>:

<!-- Uploadify -->
<script type="text/javascript" src="<?php bloginfo( 'template_url' ); ?>/uploadify/swfobject.js"></script>
<script type="text/javascript" src="<?php bloginfo( 'template_url' ); ?>/uploadify/jquery.uploadify.v2.1.4.js"></script>

Utilizamos el código php bloginfo(‘template_url’) para poner la dirección absoluta donde se encuentran los archivos.

Queríamos que cada cliente tuviera su propio directorio para subir archivos con lo que necesitábamos el nombre de usuario una vez logueado el cliente. Así que en la página donde queríamos el uploader pusimos este trozo de código:

<script type="text/javascript">
var files = new Array();
var user = '<?php echo $username; ?>';
var $cont = 0;
           jQuery(document).ready(function() {
             jQuery('#file_upload').uploadify({
               'uploader'  : '<?php bloginfo( 'template_url' ); ?>/uploadify/uploadify.swf',
               'script'    : '<?php bloginfo( 'template_url' ); ?>/uploadify/uploadify.php',
               'cancelImg' : '<?php bloginfo( 'template_url' ); ?>/uploadify/cancel.png',
               'folder'    : '<?php echo URI_UPLOADS.'/'.$username.'/'; ?>',
               'auto'      : false,
               'removeCompleted' : false,
               'simUploadLimit' : 3,
               'buttonText' : '<?php _e('SELECCIONAR','nysplm'); ?>',
               'multi' : true,
               'onError' : function (event,ID,fileObj,errorObj) {
                 alert(errorObj.type + ' Error: ' + errorObj.info);
               },
               'onComplete' : function (event, ID, fileObj, response, data) {
                        var json = {"name": fileObj['name'], "size": fileObj['size'], "type": fileObj['type']};
                        files[$cont] = json;
                        $cont++;
                },
               'onAllComplete' : function (event, data) {
                        //alert("Response: "+response);
                        send_confirmation(data);
                        $cont = 0;
                        files = [];
                 }
              });
           });

Donde le decimos a uploadify:

  • uploader: donde está el archivo .swf que contiene el código flash que nos permitirá subir los archivos
  • script: donde está el archivo .php que necesita uploadify para hacer la carga de los archivos
  • cancelImg: donde se encuentra la imagen que se muestra para cancelar la subida de los archivos
  • folder: el directorio donde queremos subir los archivos. En nuestro caso esto es dinámico, así el cliente subirá los archivos a su propio directorio.
  • auto: indica que la subida no será automática, sino que el usuario deberá, una vez cargados los archivos, presionar un enlace para comenzar la carga.
  • removeCompleted: indicamos que no quite de pantalla los archivos subidos.
  • simUploadLimit: establecemos a 3 ficheros el límite de subida simultánea.
  • buttonText: ya que este gran software está en inglés, utilizamos esta opción para cambiar el texto del botón de carga de archivos.
  • multi: indicamos que se pueden subir varios archivos simultáneamente.
  • onError: función que mostrará una alerta js si se produce algún error.
  • onComplete: función que se ejecutará cada vez que se suba correctamente uno de los ficheros
  • onAllComplete: función que se ejecutará cuando se hayan subido todos los ficheros.

Alguien se habrá dado cuenta del comentario que hay en el onAllComplete:

 alert("Response: "+response);

Esto sirve de mucha ayuda cuando estamos desarrollando. Puede ser que el archivo no se suba correctamente por falta de permisos. Esto para uploadify no es un error, ya que no es competencia suya, con lo que el error es devuelto a la función onAllComplete en lugar de lanzar un error la función onError. Por ello, si vemos que no se muestra ningún error pero el archivo no se sube al servidor correctamente, descomentar esta línea puede aclarar que está pasando.

Y por último, y no menos importante, habrá que poner el tag donde se cargará uploadify:

<input id="file_upload" name="file_upload" type="file" />
<a href="javascript:$('#file_upload').uploadifyUpload();"><?php _e('Subir archivos','nysplm'); ?></a>

donde ponemos el input con el identificador que cargará uploadify y un enlace para subir los archivos simultáneamente.

Y hasta aquí, esperamos haber sido de ayuda. Si alguien tiene alguna duda pues a comentar. Ayudaremos en lo que podamos.

Pods CMS

lunes 25 de octubre de 2010

Al empezar la creación de una página web siempre nos habíamos preguntado cual sería la mejor opción a la hora de elegir un CMS.

Nuestras investigaciones por internet y después de barajar varias opciones hizo que descubriéramos Pods CMS. Pods es un plugin para WordPress que lo convierte en un cms cómodo, rápido y muy fácil de configurar.

Para empezar a trabajar con Pods simplemente hay que bajar el plugin y activarlo en una instalación de WordPress. Podéis encontrar el plugin Pods CMS en la web de plugins para wordpress.

Pods funciona principalmente como un generador de tipos de contenido, desde el punto de vista del programador podríamos verlo como un generador de clases, esto es, permite definir un modelo y asignarle varios campos de diferente tipo para luego poder crear objetos de dicha clase e interaccionar con ellos. Simplemente con esta funcionalidad ya es suficiente para dejarte con los ojos abiertos, pero hay mucho más.

Con Pods puedes hacer cualquier cosa, ya que tienes muchas formas de sacar la información introducida en la base de datos:

  • Mediante páginas desde Pods en el área de administración. En estas páginas se puede poner tanto código php como caracteres comodín en las URL. Por ejemplo la página recetas/* será el handler por defecto de todas las páginas que empiecen por recetas/. Una forma de routing sencilla para el usuario…
  • Se puede también añadir código en php directamente en los templates del tema que estés utilizando en WordPress.
  • Utilizar shortcode de WordPress para incluir instancias de Pods o detalles de un Pod específico dentro de páginas o entradas de WordPress.
  • Y por último y la más importante de todas creo yo, la API de Pods, que te permite hacer CRUD directamente de cualquier Pod que tengas creado en el sistema. Esto viene de perlas por ejemplo para hacer plugins que utilicen el sistema Pods como entrada de datos en las tablas.

Por poner un ejemplo, estamos trabajando en una web donde utilizamos Pods como entrada de datos en el sistema. Una de las partes de la página principal muestra los servicios más llamativos que proporciona nuestro cliente cada mes. Para ello creamos un Pod (que llamaremos Servicios destacados) que contendrá los siguientes datos: nombre, imagen, activa, oferta del mes, enlace.

Una vez creado el Pod podemos introducir datos desde la sección Add Servicios destacados que aparece en el menú principal de Pods (esto puede cambiarse mediante Pods UI o creando un menú nuevo mediante un plugin, pero eso lo comentaremos en otro post):

Ya introducidos los datos podremos asociar una página de WordPress a un template concreto y modificar ese template para que lea los datos del pod que queremos. En este caso creamos un template con este código:

<?php
/*
Template Name: Servicios destacados
*/
<?php get_header(); ?>
<?php
	// Consultamos la base de datos en Pods. 4 servicios destacados que estén activos
	$imagenes = new Pod('servicios_destacados');
	$imagenes->findRecords('name ASC','4','t.activa = 1');
	$total_imagenes = $imagenes->getTotalRows();
?>

//Bucle por los servicios destacados encontrados para crear la página
<div id="servicios-destacados">
<?php if( $total_imagenes>0 ) : ?>
	<ul>
	<?php while ( $imagenes->fetchRecord() ) : ?>
		<?php
			// iniciamos nuestras variables
			$id        	= $imagenes->get_field('id');
			$nombre      	= $imagenes->get_field('name');
			$imagen  	= $imagenes->get_field('imagen');
			$imagen_url     = $imagen[0]['guid'];
			$enlace		= $imagenes->get_field('enlace');
			if($enlace=="") $enlace = "#";
		?>

		<li>
			<a href="<?php echo $enlace; ?>">
			<img src="<?php echo $imagen_url; ?>" alt="<?php echo $nombre; ?>" />
			</a>
		</li>
	<?php endwhile ?>
	</ul>
<?php endif ?>
</div><!-- #servicios-destacados-->
<?php get_footer(); ?>

En este template lo que hacemos es:

  1. consultar cuatro productos destacados activos
  2. hacer un bucle por los productos para mostrarlos en pantalla

Con esto hemos visto lo fácil que es meter contenido propio en una base de datos utilizando el gran backEnd que tiene WordPress y consultar ese contenido con un template. Todo esto gracias a Pods.

Por último os dejo con un video de uno de los autores rascando un poco por encima las posibilidades de Pods y de su creciente documentación: