30 enero, 2009

Sembrando semillas para JS en el servidor

Kevin Dangoor, perteneciente al equipo de Mozilla Developer Tools, ha escrito un artículo titulado Lo que Javascript necesita en el servidor (via) donde, acertadamente, pone el dedo en la llaga al comparar las comunidades de otros lenguajes de servidor (como Python, Java, PHP o Ruby) con lo que existe actualmente con Javascript. Si bien es cierto que Helma ya tiene unos cuantos años, y hace poco Jaxer ha aparecido como alternativa, los desarrollos de los nuevos motores y el auge de Ajax ha hecho crecer mucho el interés en el lenguaje, incluso para servir páginas al otro lado de la conexión.

Ciertamente no existe un estándar para solicitar la carga de un módulo, para acceder al sistema de archivos o a la base de datos y eso supone un claro freno al desarrollo de una comunidad con un potencial increíble. Proyectos recientes como JackJS para sentar las bases de la comunicación entre una aplicación web y un servidor javascript o el repositorio de proyectos JSAN (JavaScript Archive Network) no son más que indicios de que es necesaria la creación de una comunidad que permita aunar y reaprovechar los esfuerzos que hasta el momento están resultando demasiado individuales.

Por todo ello, Dangoor ha dado un primer paso y ha creado el grupo ServerJS para abrir la discusión sobre el tema y establecer un camino que permita nacer al que, sin duda, se va a convertir en el nuevo lenguaje de servidor para el desarrollo de aplicaciones web.

29 enero, 2009

Un arreglo disfrazado de avance

En Hackademix.net hacen referencia a la última característica de seguridad en IE8: la cabecera no estándar (Microsoft sigue sin aprender) X-FRAME-OPTIONS que si especifica el valor DENY, impide que la página se muestre dentro de un frame en IE8. Un parche en toda regla que podría parecer innecesario utilizando la conocida línea de código que detecta si no se está en el documento principal, y en ese caso se autorecarga como principal:

if (top!=self) top.location.href=self.location.href;
Pero como a Microsoft le encanta salirse de los estándares, aunque sólo sea para amargar la vida de los desarrolladores, en su día se les ocurrió añadir la propiedad exclusiva <IFRAME SECURITY=restricted>, que invalida la comprobación anterior y abre un agujero de seguridad en Internet Explorer que nadie más tiene.

Hay que tener morro para vender como una mejora de seguridad que otros aún no tienen un parche exclusivo que sólo mejora la seguridad en su propio navegador, que obliga al desarrollador a introducir otra propiedad exclusiva para IE, y que además tiene como objetivo resolver un problema que ellos mismos crearon al salirse del camino y para lo cual se vuelven a salir de él. Están pidiendo un boicot a gritos.

Cinco por cinco

Recuerdo que hace unos años me entretenía en clase rellenando las casillas de una especie de cuadrado mágico de 5 por 5 casillas en el que había que numerar todas las casillas siguiendo dos reglas simples:

  1. Si la casilla actual tiene un número n, es posible marcar como n+1 la casilla tres posiciones más arriba, a la izquierda, a la derecha o abajo si está libre.
  2. Si la casilla actual tiene un número n, es posible marcar como n+1 la casilla dos posiciones en diagonal a su nordeste, noroeste, sudeste o sudoeste si está libre.

El otro día estuve probando dos o tres veces y como no recordaba si tenía solución, dejé de intentarlo y probé a hacer un algoritmo que probase si encontraba alguna solución.

Se puede probar en este enlace de jsbin.

Aunque yo inicio el proceso a partir de la casilla 0 (la superior izquierda) y detengo el proceso cuando ha encontrado 20 soluciones (se trata de un proceso muy intensivo, especialmente para el navegador). Por ejemplo:

01-09-19-02-10
14-22-05-13-21
07-17-25-08-18
04-12-20-03-11
15-23-06-16-24

Y el código (simplificado):
function itera(board, pos, num) { 
  if (salida>20) return; 
  board[pos]= num++; 
  if (num==26) return print_solution(board); 
   
  if (board[pos+3]==null && pos%5<2) 
    itera(board.slice(), pos+3, num); // comprueba horizontal +3 
  if (board[pos-3]==null && pos%5>2)  
    itera(board.slice(), pos-3, num); // comprueba horizontal -3 
  if (board[pos-15]==null && pos>14)  
    itera(board.slice(), pos-15, num); // comprueba vertical -15 
  if (board[pos+15]==null && pos<10)  
    itera(board.slice(), pos+15, num); // comprueba vertical +15 
  if (board[pos-12]==null && pos%5>1 && pos>9)  
    itera(board.slice(), pos-12, num); // comprueba diagonal NO -12 
  if (board[pos-8]==null && pos%5<3 && pos>9)  
    itera(board.slice(), pos-8, num); // comprueba diagonal NE -8 
  if (board[pos+8]==null && pos%5>1 && pos<15)  
    itera(board.slice(), pos+8, num); // comprueba diagonal SO +8 
  if (board[pos+12]==null && pos%5<3 && pos<15)  
    itera(board.slice(), pos+12, num); // comprueba diagonal SE +12 
   
} 

var board= [];    
for (var i=0; i<=24; i++) board[i]= null; // dim to 25 elements 

itera(board, 0, 1); // inicio proceso con tablero vacío y empezando en la casilla 0

28 enero, 2009

32 bytes para identificar a IE

try{IE=window=!1}catch(e){IE=!0}
Con el resultado esperado en sólo 32 bytes: IE==1 sólo si se ejecuta desde Internet Explorer.
Gracias a Andrea Giammarchi. Addendum: En Ajaxian hacen referencia a este asunto y se ha abierto una auténtica batalla en los comentarios para conseguir algo aún más corto:
IE='\v'=='v' // El JScript de IE no soporta el tabulador vertical "\v" (12 bytes)
IE=top.execScript?1:0
Addendum: En The Spanner extienden la idea para el resto de navegadores, tratando de encontrar la secuencia más corta de identificar un navegador concreto (via).
FF=/a/[-1]=='a' //Firefox

FF3=(function x(){})[-5]=='x' //Firefox 3

FF2=(function x(){})[-6]=='x' //Firefox 2

IE='\v'=='v' //IE

Saf=/a/.__proto__=='//' //Safari

Chr=/source/.test((/a/.toString+'')) //Chrome

Op=/^function \(/.test([].sort) //Opera

GMail sin conexión

GMail es una aplicación web a la que se le debe el haber supuesto el punto de inflexión tras el cuál la revolución AJaX (o Remote Scripting como siempre se le debió llamar) explotó hasta el punto de hacerse omnipresente. A pesar de la ubicuidad de Flash, disponible en el 95% de los navegadores, y de los esfuerzos (Adobe Flex, Open Laszlo) por dar alternativas simples a la creación de aplicaciones ricas, las tecnologías de siempre (HTML, CSS, Javascript, y XML o JSON) siguen siendo preferidas al ser más abiertas y familiares. GMail abrió los ojos a muchos desarrolladores ante las posibilidades y las ventajas de trabajar sin la necesidad de cargar una y otra vez la página para mostrar cambios, algo que haciamos hasta hace muy poco con total naturalidad con la queja típica de "me funciona lento Internet".

Hoy, el equipo responsable de GMail da un paso más que también puede suponer un antes y un después: han anunciado la disponibilidad de la opción de trabajar con el aunque no se tenga conexión. No hay que subestimar la importancia de ese cambio que ha supuesto una profunda revisión del funcionamiento interno de la aplicación. La nueva característica hace uso, como no podía ser de otra forma, de Google Gears, el programa que extiende las capacidades del navegador aumentando la potencia de las aplicaciones web que corren sobre él. Con Gears, GMail mantiene en una base de datos local los mensajes sincronizados con los servidores de Google para que puedan ser accedidos aún cuando no sea posible realizar una conexión con éstos. Un efecto secundario de este sistema es que la aplicación funcionará perfectamente sin que el usuario perciba ningún problema incluso si la conexión tiende a cortarse con frecuencia.

Aunque un poco a remolque de los productos que libera Google, la comunidad puede verse beneficiada de una nueva funcionalidad para las aplicaciones web que, pese a su utilidad, no es la que se espera de ellas. De nuevo, esta tecnología puede abrir ojos y fomentar su uso en entornos corporativos y puede tener múltiples aplicaciones.

Conviene recordar las posibilidades de Gears (y las de Yahoo! BrowserPlus, que es similar):

  • Disponibilidad para Mac (Firefox y Safari), Windows (IE y Firefox), Linux (Firefox), Android (webkit), Windows Mobile (IE Mobile).
  • Base de datos local basada en SQLite y accesible desde Javascript
  • LocalServer para cachear los archivos estáticos y que las páginas sean accesibles por el navegador incluso sin conexión
  • WorkerPool trae los hilos al navegador para procesos que necesiten largo tiempo para ejecutarse y no bloquear así la experiencia de usuario (como la sincronización con servidores).
  • Servicios de localización geográfica del dispositivo sobre el que se está ejecutando el navegador
  • API de blobs para gestionar datos binarios desde Javascript
  • Acceso a archivos locales a través de la API de Google Desktop
Addendum: Me he olvidado de enlazar el breve artículo Disruptive del gurú Douglas Crackford y su frase:
Espero que los últimos contendientes, incluyendo Air, Silverlight, y JavaFX, también fracasen en desplazar ajax, incluso aunque son principalmente tecnologías superiores. Ninguno de esos pretendientes ofrece un mejor modelo de seguridad que la web, y creo que la habilidad de mezclar componentes de forma segura será la clave para la siguiente generación de avances.

27 enero, 2009

Empezando con CodeIgniter

Nota: He traducido el tutorial de Kohana, derivado de CodeIgniter y al que algunos consideran una mejora considerable sobre éste.
He traducido este excelente tutorial sobre la librería PHP CodeIgniter por Ben Haines.

CodeIgniter es una librería de aplicaciones web para PHP. Permite a los desarrolladores construir aplicaciones web más rápidamente, y ofrece útiles librerías de código y atajos que aceleran las tareas tediosas en PHP. CodeIgniter se basa en un diseño modular (lo que quiere decir que puedes implementar librerías específicas a voluntad) lo que repercute en una mayor velocidad del sistema. Este tutorial intentará mostrar los pasos básicos de instalar la librería, incluyendo como construir una aplicación web básica hola mundo que utiliza un enfoque MVC.

¿Por qué una librería?


Las librerías permiten estructurar las aplicaciones al desarrollarlas ofreciendo clases reusables y funciones que pueden reducir significativamente el tiempo de desarrollo. Algunas pegas de las librerías es que ofrecen clases no necesitadas, añadiendo exceso de código que dificulta encontrar las cosas.

¿Por qué CodeIgniter?




Lo básico de CodeIgniter

CodeIgniter es una librería muy ligera con buen rendimiento. Mientras que resulta perfecta para el principiante (a causa de su pequeña curva de aprendizaje), también resulta perfecta para aplicaciones web grandes y exigentes. CodeIgniter está desarrollada por EllisLab y dispone de una documentación accesible y fácil de comprender. Una lista de razones que hacen de CodeIgniter una librería adecuada:
  • Usa pocos recursos pero ofrece un rendimiento excepcional
  • Enfoque MVC para el desarrollo (aunque permite bastante flexibilidad al utilizar una estructura poco rígida)
  • Genera URLs limpias aptas para motores de búsqueda
  • Fácilmente extensible
  • Funciona sobre PHP 4 (a partir de 4.3.2) y PHP 5
  • Soporta las principales bases de datos incluyendo MySQL (a partir de 4.1), MySQLi, SQL Server, Postgres, Oracle, SQLite y ODBC
  • La seguridad de la aplicación es un objetivo básico
  • Operaciones cacheadas fácilmente
  • Módulos y atajos que ayudan con las operaciones complejas como email, manipulación de imágenes, validación de formularios, subida de archivos, sesiones, aplicaciones multilenguaje y creación de apis para una aplicación
  • La mayoría de módulos sólo se cargan cuando son necesarios, lo que redunda en un drástico recorte de los recursos necesarios

¿Por qué un MVC?


Para los principiantes, MVC significa Modelo, Vista, Controlador. Es un patrón de programación usando para desarrollar aplicaciones web. Este patrón aisla la interfície de usuario y el backend (p.e. la interacción de la base de datos de todo lo demás. Una implementación correcta de esto permite que los desarrolladores modifiquen su interfície de usuario o backend sin afectar a la otra parte. MVC también incrementa la flexibilidad de una aplicación permitiendo la reutilización continua de los modelos o vistas). A continuación se puede encontrar una descripción de MVC.
  • Modelo: El modelo trata con los datos en su origen y con la interacción con la base de datos y contendrá funciones como agregar registros a la base de datos o seleccionar registros específicos de la base de datos. En CodeIgniter el componente modelo no es requerido y puede ser incluido en el controlador.
  • Vista: La vista trata con la visualización de los datos y con la interfície que el usuario controla. En CodeIgniter (o CI) la vista puede ser una página web, una fuente RSS, datos Ajax o cualquier otra "página".
  • Controlador: El controlador actúa como el intermediario entre la vista y el modelo y, como su nombre sugiere, controla lo que se envía desde el modelo hacia la vista. En CI, el controlador también es el lugar donde cargar módulos y atajos.

Un ejemplo de un enfoque MVC sería el de un formulario de contacto.
  1. El usuario interactúa con la vista rellenando un formulario y enviándolo.
  2. El controlador recibe los datos POST del formulario, y envía estos datos al modelo que es quien actualiza la base de datos.
  3. El modelo envía el resultado de la base de datos al controlador.
  4. El resultado es actualizado en la vista y mostrado al usuario.

Esto puede sonar como mucho trabajo que hacer. Pero creeme, cuando se empieza a trabajar con aplicaciones grandes, poder reutilizar modelos o vistas ahorra un montón de tiempo.

Paso 1. Descargar CodeIgniter


Para empezar se necesita descargar CodeIgniter y subirlo a un servidor web. Apuntar el navegador a http://www.codeigniter.com/ y pulsa sobre el gran botón de descarga. Para este tutorial se usará la versión 1.70.



Paso 2. Instalar y explorar CodeIgniter


Una vez descargado, sólo es necesario descomprimir el Zip y renombrar la carpeta "CodeIgniter_1.7.0" al nombre de la aplicación deseada o, en este caso, "ci" y subirla a un servidor con soporte de PHP y MySQL. Ahora que está en el servidor, explicaré para qué son las carpetas y archivos:

  • La carpeta system almacena todos los archivos que hacen que CI funcione
    • La carpeta de aplicación es casi idéntica al contenido de la carpeta de sistema para que que el usuario pueda tener archivos que sean particulares de la aplicación, por ejemplo si un usuario quiere cargar un atajo en una aplicación, lo ubicaría en la carpeta system/application/helpers en lugar de la de system/helpers.
      • La carpeta config almacena todos los archivos de configuración relevantes para la aplicación. Eso incluye qué librerías debe auto-cargar la aplicación y detalles de la base de datos.
      • La carpeta controllers almacena todos los controladores de la aplicación.
      • La carpeta errors almacena todas las páginas de patrones de errores de la aplicación. Cuando un error aparece, se genera una página de error a partir de uno de estos patrones.
      • La carpeta hooks contiene extensiones que modifican el funcionamiento de los archivos del núcleo de CI. Están pensados para los usuarios avanzados de CI.
      • La carpeta language contiene líneas de texto que pueden ser cargadas a través del módulo de lenguaje para crear sitios multilenguaje.
      • La carpeta libraries contiene todas las librerías o módulos específicos para la aplicación.
      • La carpeta models almacena los modelos de la aplicación.
      • La carpeta views almacena las vistas de la aplicación.
    • La carpeta cache almacena los caches generados por el módulo de caché.
    • La carpeta codeigniter almacena los archivos necesarios para que CI funcione.
    • La carpeta database almacena todos los drivers de base de datos y las clases que habilitan las conexiones a bases de datos.
    • La carpeta fonts almacena todas las fuentes que pueden ser usadas por el módulo de manipulación de imágenes.
    • La carpeta helpers contiene los atajos del núcleo de CI, pero es posible ubicar otros atajos personales para que accedan todas las aplicaciones.
    • La carpeta language contiene los archivos de lenguaje del núcleo de CI que usan sus módulos y atajos, pero es posible ubicar carpetas de lenguaje para que accedan todas las aplicaciones.
    • La carpeta libraries almacena las librerías del nucleo de CI, pero es posible ubicar otras librerías personales para que sean accedidas por todas las aplicaciones.
    • La carpeta logs contiene todos los logs (registros) generados por CI.
    • La carpeta plugin almacena todos los plugins que pueden ser usados. Los plugins son casi idénticos a los atajos (helpers). Son funciones dirigidas a ser compartidas por la comunidad.
    • La carpeta scaffolding almacena todos los archivos que hacen que la clase scaffolding (andamiaje) funcione. Scaffolding permite una interfície CRUD (Create-Read-Update-Delete) conveniente para acceder a la información de la base de datos durante el desarrollo.
  • La user_guide guarda la guía de usuario de CI.
  • El archivo index.php es el elemento que gestiona toda la magia de CI y permite cambiar el nombre de las carpetas de sistema y de aplicación.

Paso 3: Configurar CodeIgniter


Conseguir que CI se ponga en marcha y funcione es bastante simple. Principalmente requiere editar unos pocos archivos de configuración.

Se necesita configurar CI para que apunte a la URL base correcta de la aplicación. Para hacerlo, hay que abrir system/application/config/config.php y editar la variable array base_url para que apunte a tu servidor y carpeta CI.
$config['base_url'] = "http://localhost/ci/";

Paso 4: Probando CodeIgniter


Haremos un rápido test para ver si CI está en marcha y funcionando adecuadamente. Dirígete a http://localhost/ci/ y deberías ver lo siguiente.



Paso 5: Configurando CodeIgniter (continuación)


Si está en marcha y funcionando, deberíamos terminar la configuración. Estamos empezando a configurarlo específicamente para nuestra nueva aplicación holamundo. Si quieres usar una base de datos con tu aplicación (cosa que haremos en este tutorial), abre system/application/config/database.php y establece los siguientes elementos a los valores correspondientes. Este código conecta a una base de datos MySQL llamada "holamundo" en localhost con el usuario "root" y la clave "root".
$db['default']['hostname'] = "localhost";
$db['default']['username'] = "root";
$db['default']['password'] = "root";
$db['default']['database'] = "holamundo";
$db['default']['dbdriver'] = "mysql";
Además, como vamos a usar la base de datos un poco, queremos que se cargue automáticamente para no tener que hacerlo cada vez que conectemos. Abre system/application/config/autoload.php y agrega 'database' a la variable array de carga automática de módulos.
$autoload['libraries'] = array('database');
Actualmente, la configuración de CI tendrá un controlador predefinido llamado "welcome.php" que se puede encontrar en la carpeta system/application/controllers. Para este tutorial, bórralo y abre el archivo system/application/config/routes.php y cambia el la variable de ruta predefinida para que apunte al controlador "holamundo".
$route['default_controller'] = "Helloworld"
CI también tiene un archivo de vista que no necesitamos. Abre la carpeta system/application/view/ y elimina el archivo welcome_message.php.

Paso 6: Crea la base de datos Holamundo


Puesto que esto no es un tutorial de MySQL, esta sección será corta. Crea una base de datos llamada "holamundo" y ejecuta el siguiente código SQL mediante phpMyAdmin o cualquier otro cliente MySQL.
CREATE TABLE `data` (
  `id` int(11) NOT NULL auto_increment,
  `title` varchar(255) NOT NULL,
  `text` text NOT NULL,
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=2 ;

INSERT INTO `data` (`id`, `title`, `text`) VALUES(1, 'Hello World!', 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla 
sapien eros, lacinia eu, consectetur vel, dignissim et, massa. Praesent suscipit nunc vitae neque. Duis a ipsum. Nunc a erat. Praesent 
nec libero. Phasellus lobortis, velit sed pharetra imperdiet, justo ipsum facilisis arcu, in eleifend elit nulla sit amet tellus. 
Pellentesque molestie dui lacinia nulla. Sed vitae arcu at nisl sodales ultricies. Etiam mi ligula, consequat eget, elementum sed, 
vulputate in, augue. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae;');

Paso 7: Crea el modelo Holamundo



Los modelos son opcionales en CI, pero está considerada una buena práctica el utilizarlos. Se trata de simples clases PHP que contienen funciones que trabajan con información de la base de datos. Crea un archivo helloworld_model.php en la carpeta system/application/models. En este archivo, crea una clase Helloworld_model, con un constructor Helloworld_model y una función getData.

En la función getData vamos a usar funciones de base de datos Active Record que aceleran el desarrollo cuando se trabaja con CI y bases de datos. Esencialmente se trata de funciones simplificadas para crear consultas.
<?php
class Helloworld_model extends Model {

    function Helloworld_model()
    {
        // Call the Model constructor
        parent::Model();
    }
    
    function getData()
  {
   //Query the data table for every record and row
   $query = $this->db->get('data');
   
   if ($query->num_rows() > 0)
   {
    return $query->result();
   }else{
    //show_error('Database is empty!');
   }
  }

}
?>

Paso 8: Crea el controlador Holamundo



Creemos un controlador que muestre la vista y cargue el modelo. De esa forma, cuando vayas a la dirección http://localhost/ci/index.php/helloworld/, verás datos que vienen de la base de datos. En la carpeta system/application/controllers, crea un archivo llamado helloworld.php. Ahí crearemos una clase que tiene el mismo nombre que el archivo.

Dentro de esta clase, necesitas crear una función llamada "index". Esta es la función que se mostrará cuando no se indique otra (por ejemplo al visitar http://localhost/ci/index.php/helloworld/). Si, por ejemplo, creasemos una función llamada foo, podríamos encontrarla en http://localhost/ci/index.php/helloworld/foo/.

Lo que hay que recordar es cómo CI estructura sus URLs. Es decir: http://host/codeignitordirectory/index.php/class/function

En la función index del controlador necesitamos cargar el modelo, consultar la base de datos, y pasar los datos solicitados a la vista. Para cargar cualquier recurso en CI (como módulos, atajos, vistas o modelos) usamos la clase load. Tras cargar el modelo, podemos acceder a él a través de su nombre y de la función particular deseada. Para pasar datos a la vista, necesitamos asignarla a un elemento de array y pasar el array, lo cuál recrea los elementos del array como una variable en el archivo de vista.
<?php
 class Helloworld extends Controller{
  function index()
  {
   $this->load->model('helloworld_model');

   $data['result'] = $this->helloworld_model->getData();
   $data['page_title'] = "CI Hello World App!";

   $this->load->view('helloworld_view',$data);
     }
 }
?>

Si visitamos http://localhost/ci/index.php/helloworld/ ahora, no funcionará. Eso se debe a que aún no hemos creado el archivo de la vista.



Paso 9: Crea la vista Holamundo


El archivo de vista es lo que el usuario ve y con lo que interactúa, pudiendo ser un segmento de una página o una página entera. Puedes pasar un array de variables a la vista a través del segundo argumento de la función de carga del modelo. Para crear la vista de nuestro tutorial, crea un nuevo archivo llamado helloworld_view.php en la carpeta system/application/view. Ahora, necesitamos crear los elementos normales html, head y body y entonces crear una cabecera y un párrafo para la información que vendrá de la base de datos. Para mostrar todos los registros recibidos de la base de datos, ponemos un bucle foreach que recorra todos los elementos.
<html>
 <head>
  <title><?=$page_title?></title>
 </head>
 <body>
  <?php foreach($result as $row):?>
  <h3><?=$row->title?></h3>
  <p><?=$row->text?></p>
  <br />
  <?php endforeach;?>
 </body>
</html>

Es posible que te hayas dado cuenta de que estamos usando una sintaxis alternativa de PHP que ofrece una forma conveniente de escribir comandos echo y que además ahorra tiempo.

Paso 10: Ta-da y algunos Extras


Cuando visites target="_blank">http://localhost/ci/index.php/helloworld/ deberías ver algo similar a lo siguiente:


Pero aún no hemos terminado. Hay unas pocas cosas que mejoran la experiencia con CodeIgniter - como eliminar ese molesto "index.php" de la URL. Es posible hacerlo creando un archivo .htaccess en la carpeta raíz y añadiendo el siguiente código.
RewriteEngine on
RewriteCond $1 !^(index\.php|images|robots\.txt)
RewriteRule ^(.*)$ ci/index.php/$1 [L]

También necesitarás abrir el archivo config.php de system/application/config/ y editar el elemento index_page asignándole una cadena vacía.
$config['index_page'] = ""; 
Otro truco es activar la habilidad de CI de parsear la sintaxis alternativa de PHP, si no está habilitada por defecto en el servidor. Para conseguirlo, abre el mismo archivo que antes (system/application/config/config.php) y edita el elemento rewrite_short_tags con el valor TRUE.
$config['rewrite_short_tags'] = TRUE;
Y con esto llegamos al final del tutorial. Una aplicación simple de CodeIgniter que permite entender cómo se estructura el código con esta librería, aunque no se pueden ver todas sus ventajas hasta que se empiecen a crear aplicaciones un poco más complejas. Espero que haya sido de utilidad. Addendum: En NetTuts ofrecen 6 trucos u optimizaciones muy interesantes si vas a utilizar la librería.

Liderazgo en MooTools

Aaron Newton es una de las personas más implicadas en el desarrollo de la librería MooTools. Hasta hace poco trabajaba para CNET en el sitio ClientSide, aunque actualmente ha seguido su labor en solitario en clientcide.com. Es el autor del Mootorial, una herramienta excelente para aprender rápidamente cómo funciona MooTools y sus capacidades.

Hace unos días, y ante la insistencia de la comunidad de MooTools respecto a qué pasaba con el proyecto, Aaron explicaba que, a diferencia de jQuery y John Resig, MooTools no tiene un líder con ganas de evangelizar su uso. Valerio Proietti, su autor original prefiere dedicar su tiempo a programar y ser productivo y no a promover el uso de la librería. Es por ello que Aaron ha decidido aprovechar su blog para llenar ese agujero y se ha puesto directamente manos a la obra. Ante las críticas de que el proyecto está parado, aduce que pasa más bien al contrario: la versión 1.2 ha resultado ser tremendamente estable, por lo que se están tomando su tiempo para preparar la nueva versión 1.3 que incluirá:

  • Los métodos $date, $lambda, $try, etc. que actualmente están disponibles en el ámbito global (window), se introducirán en las clases en las que tenga sentido hacerlo para ganar coherencia. Por ejemplo, $lambda pasará a Function.lambda o $date a Date.now. Se mantienen en el global $, $$ y $type se convertirá en typeOf.
  • Reparación de unos cuantos bugs.
  • Delegación de eventos (que puedan ser capturados por elementos más altos en la jerarquía).
  • Opción noCache para Request
  • Una nueva versión de Class con mayor flexibilidad especialmente para los mutators.

Además, lejos del inmovilismo, están apareciendo muchos proyectos satélites que no están incluidos dentro (como Mootools Art de la que hablaré en breve) debido a la filosofía propia de la librería (un framework para desarrollar JavaScript, no una colección de widgets fáciles de instalar). Por ello se sugiere a quien tenga algo que quiera publicar, que lo haga de forma independiente, dado que es complicado que algo entre a formar parte del núcleo de la librería (de hecho la clase Hash se extraerá de dicho núcleo en la versión 1.3). Addendum: Los cambios se anuncian en este post de MooTools.net. Los plugins pasan a llamarse MooTools -more y pueden descargarse aquí.

26 enero, 2009

jQuery 1.3, UI.layout y XUI

Me he retrasado un poco con este artículo, aunque más vale tarde que nunca.

jQuery 1.3


Coincidiendo con el tercer aniversario de la librería, jQuery lanzó hace unos días su versión 1.3 con interesantes novedades.
  • Introducción de Sizzle, el nuevo motor de selección por CSS
  • Live Events: Delegación de eventos para que se mantengan asignados incluso para los nuevos elementos creados.
  • Revisión de jQuery Event: Reescrita totalmente para simplificar la gestión de eventos.
  • Reescritura de la función de inyección de código HTML para acelerarlo lo más posible.
  • Reescritura del cálculo de Offsets.
  • Eliminación del código de identificación del navegador: a partir de ahora se comprobará la disponibilidad de una característica antes de hacer uso de ella.

UI.layout


UI.layout es un plugin para jQuery que nos permite crear layouts en nuestras aplicaciones web, ya sean complejos o sencillos. Con este plugin podemos añadir toolbars, menús, paneles de ayuda, status bars, ... Además cuenta con las siguientes características: sencillo, personalizable (CSS, botones), redimensionable, extensible, colapsable, ocultable, cabeceras y pies de página por región, hotkeys, e integrable con cualquier widget o plugin jQuery.



Siempre resulta atractivo poder disponer de otras formas de distribución del contenido distintas del CSS. Los programadores están más acostumbrados a especificar distribuciones de contenido basados en zonas (alineaciones al lateral o al área disponible, o bien divisiones horizontales o verticales del espacio disponible) por lo que herramientas así siempre pueden resultar interesantes en lugar de pegarse con CSS. Visto en sentidoweb.com y WebAppers.

XUI librería javascript para aplicaciones de móviles


Aunque los desarrolladores de librerías ya realizan un esfuerzo considerable por reducir al máximo el tamaño de su código, la necesidad de que incluyan código para identificar el navegador sobre el que funcionan e introduzcan código de compatibilidad implica un coste en espacio y tiempo de ejecución que en dispositivos limitados como los móviles resulta un lastre significativo. Además, el entorno es distinto (menos espacio, limitación de velocidad, ...) por lo que las necesidades son distintas. XUI está orientado a navegadores móviles de primera clase como WebKit (iPhone), Fennec (Firefox Mobile) u Opera (aunque probablemente se incluya también IE Mobile y BlackBerry en el futuro). Además parece que hay un proyecto (xui-app) para crear un entorno MVC sobre el que desarrollar aplicaciones web móviles multiplataforma. El código ocupa tan sólo 6KB y se pueden ver un par de ejemplos a continuación. Via Ajaxian.
x$('button').on( 'click', function(){ alert('boton pulsado!') });
x$('#box5').css({ backgroundColor:'blue', width:'100px', border:'2px solid red' });
x$('#box').tween([{ left:100px, backgroundColor:'green', duration:.2 }, { right:100px }]);

IE8 en el punto de mira

Ajaxian se hace eco de un chat online con el equipo de Internet Explorer. Resumiendo algunos aspectos de la oveja negra de los navegadores:

  • El objetivo de soporte de CSS para IE8 será la versión CSS2.1, de la versión 3.0 sólo soportarán el texto vertical. Da igual que el resto de navegadores estén infinitamente más avanzados.
  • IE8 no dará soporte a la propiedad border-radius para redondear los bordes. Chris Wilson (el responsable del equipo) confirma que la gente está insistiendo mucho en esto, pero, de momento, lo dejan para la siguiente versión después de IE8.
  • No hay un roadmap para IE9 pero probablemente incluya soporte nativo de SVG (gráficos vectoriales que, de nuevo, ya incluyen los principales competidores desde hace tiempo).
  • También es probable que en el futuro se incluya un motor optimizado de Javascript. Todos los demás navegadores ya están haciendo progresos enormes en ese aspecto dado el auge de las aplicaciones web: Safari está en marcha con SquirrelFish y ahora SquirrelFish Extreme como reacción al motor V8 de Chrome, y Mozilla con su ScreamingMonkey. Es de suponer que la presión les hará plantearse esta opción, pero no hay que olvidar que la historia de Microsoft está plagada de decisiones de recorrer su propio camino, distinto a los demás, aunque resulte evidente que sea peor para la comunidad...
  • El soporte para Canvas también debería estar contemplado en una futura versión...
Aunque suene un poco bestia siempre he pensado que la solución para el pasotismo de Microsoft a la comunidad de desarrolladores web sería integrar otro motor (webkit de Safari o gecko de Mozilla) aprovechando las posibilidades de ActiveX. Así, si el usuario se empeña en usar IE, no hay problema... ¿Alguien se atreve con un gusano benigno?

24 enero, 2009

Resolviendo un captcha en el navegador

ShaunF ha publicado un script de GreaseMonkey (la extensión de Firefox que permite modificar el comportamiento de páginas web específicas). La gracia del código, que puede probarse aquí, es que toma un captcha del sitio de subida de archivos MegaUpload.com y lo resuelve utilizando exclusivamente Javascript.

John Resig (autor de jQuery) hace un análisis de la técnica utilizada:

  • Primero el autor aprovecha la nueva etiqueta canvas incluida en los navegadores modernos para inyectar la imagen del canvas y poder acceder a nivel de pixel a ésta.
  • Con esa información, se delimitan las tres letras y se reduce cada letra a un pequeño rectángulo de puntos activos o inactivos.
  • Esos rectángulos se utilizan para alimentar una red neural implementada enteramente con Javascript y que hace las veces de reconocedor óptico de carácteres (OCR).
Aunque la imagen del captcha de MegaUpload es muy simple facilitando el trabajo y los captchas suelen ser mucho más complejos, este trabajo demuestra claramente las posibilidades que se abren con las tecnologías disponibles en una simple página web. Via Ajaxian.

23 enero, 2009

Cómo envejece una base de datos

En este artículo de Peter Harkins titulado Rules of Database App Aging se indican los síntomas que padece una base de datos cuando sufre los cambios de la aplicación a la que sirve como contenedor de información:

  1. Todos los campos se vuelven opcionales. De repente empiezan a aparecer campos que no se conocen y que deben terminar en la base de datos. Las restricciones de obligatoriedad se relajan para dar cabida a todo tipo de información que no se había previsto, perdiendo su inmaculado NOT NULL. Aparecen cláusulas de guarda por todos sitios y los left joins dan paso a outer joins. Este es el efecto más evidente sobre los datos hasta el punto de que es posible adivinar la edad de una base de datos por la cantidad de campos que retienen la restricción NOT NULL.
  2. Todas las relaciones se vuelven muchos a muchos. De repente aparecen personas que necesitan dos registros de localización, o alguien se da cuenta que las categorías no son mutuamente exclusivas. Las relaciones definen las bases de datos modernas y en cuanto la aplicación empieza a usarse, surgen fuertes necesidades de urgar con su estructura, saltándose una normalización o duplicando un registro para mejorar el rendimiento.
  3. Los textos explicativos también crecen. Los cambios introducidos exigen explicaciones que no estaban en las descripciones originales.
hasta que llega el día de reconstruir la aplicación desde cero, en el que algunos NULLs regresan, se devuelve la normalización de los datos y se simplifican las relaciones a uno-a-muchos, consiguiendo la perseguida consistencia. Y todo para que justo cuando entre en producción, a algún político de izquierdas le dé por presentarse de nuevo por otro partido de forma que no tenga cabida en la recién estrenada base de datos…

Ese es el motivo por el que las bases de datos orientadas al documento (CouchDB, SimpleDB,...) y sin una estructura definida nos parecen cada vez más y más atractivas.

Jugando con APIs de AJAX

No hay mejor forma de aprender que jugar con los parámetros y llamadas de una API. Ben Lisbakken lo entiende así y ha publicado Ajax API Playground, una herramienta imprescindible para aprender rápidamente cómo sacar provecho de los recursos que ofrece Google como Maps, Search, Feeds, Calendar, Visualization, Language, Blogger, Libraries o Earth y disfrutar como un chino. Más de 170 ejemplos disponibles que pueden ser editados para experimentar con todas las opciones disponibles.

Fielding responsabiliza a los navegadores

CSRF no es un problema de la Web. Un servicio web bien diseñado debe ser capaz de recibir peticiones dirigidas por cualquier host, por diseño, con una autenticación apropiada en caso necesario. Si los navegadores crean un agujero de seguridad porque permiten que los scripts dirijan peticiones automáticamente a sitios de terceros con credenciales de seguridad almacenadas, sin ningún tipo de intervención o configuración por parte del usuario, entonces la solución obvia al problema está en el mismo navegador. Fuente

Roy Fielding es el autor en su tesis doctoral del trabajo Architectural Styles and the Design of Network-based Software Architectures que describe REST, un principio clave de la arquitectura de la world wide web. Via Simon Willison.

21 enero, 2009

ActiveRecord.js

Ryan Johnson de Aptana publicó hace unos días un artículo sobre la beta de ActiveRecord.js, que es un mapeador de objetos relacionales (ORM) de fuente abierta que soporta múltiples entornos JavaScript:

  • Google Gears (persistencia en el lado del cliente)
  • En la memoria (si no hay servidor SQL en el cliente)
  • Adobe AIR (persistencia en el lado del cliente)
  • SQLite y MySQL (via Aptana Jaxer)
  • entornos adicionales (como HTML5) que se espera que aparezcan funcionando con la comunidad en el proyecto

ActiveRecord.js abstrae los comandos SQL subyacentes de forma que los desarrolladores JavaScript puedan tener una API unificada para almacenar, encontrar, seleccionar y recuperar objetos y sus datos usando el patrón ActiveRecord popularizado por la comunidad de Ruby on Rails.

Donde otros proyectos han buscado portar la implementación directa de ActiveRecord con JavaScript, el enfoque aquí es diferente. Los aficionados existentes a ActiveRecord, acostumbrados al vocabulario ultraconciso de la implementación de Rails encontrarán en su lugar algo bien adaptado a los desarrolladores Javascript, adaptando los patrones refinados por la comunidad Rails (y algunas influencias de Django) en APIs potentes y fáciles de usar.
// define usuario
var User = ActiveRecord.define('users',{
    username: '',
    email: ''
});

// indica la relación con artículos
User.hasMany('articles');

// crea un usuario
var ryan = User.create({
    username: 'ryan',
    email: 'rjohnson@aptana.com'
});

// define artículo
var Article = ActiveRecord.define('articles',{
    name: '',
    body: '',
    user_id: 0
});
// indica la relación inversa
Article.belongsTo('user');

// crea un articulo relacionado con el usuario creado
var a = Article.create({
    name: 'Announcing ActiveRecord.js',
    user_id: ryan.id
});
// modifica el nombre del artículo
a.set('name','Announcing ActiveRecord.js!!!');
a.save();

// obtiene el usuario del artículo
a.getUser() == ryan;
// obtiene la lista de artículos del usuario
ryan.getArticleList()[0] == a; 
La librería viene en un sólo archivo sin dependencias externas y se ejecuta en el cliente en todos los navegadores con o sin acceso a bases de datos SQL y puede ser usado en el servidor con MySQL o SQLite via Aptana Jaxer, el servidor abierto orientado a Ajax que permite usar Javascript en el servidor. Las características de esta beta incluyen validaciones de datos, creación de esquemas / migraciones y relaciones entre modelos. Como beta es bastante estable, pero sus autores esperan un uso más extendido y las aportaciones de los usuarios para llamarla 1.0. También están trabajando con gente de Google, Mozilla, y Adobe para conseguir soporte para entornos Javascript en el navegador, en dispositivos móviles, en el escritorio y en el servidor.

Puesto que uno de los usos de esta librería es soportar aplicaciones de cliente con estados (usando HTML, HTML5, Gears, Adobe AIR, etc.) tienen características que las librerías para el servidor (Jaxer) no necesitan soportar. Una de les características más vistosas es la sincronización de datos. Usando la implementación actual, se pueden encontrar registros o conjuntos enteros de resultados y conseguir que esos objetos reciban actualizaciones automáticas si los datos que contienen son modificados por otras consultas, o si registros contenidos en el conjunto de resultados son destruidos o creados. Esto es de gran utilidad cuando se construyen interfícies de usuario que dependen de datos actualizados. Aunque la sincronización entre cliente y servidor no está soportada todavía, se contemplará en el futuro.

ActiveRecord.js es parte de ActiveJS, una robusta librería MVC creada explícitamente para aplicaciones Ajax y Javascript (y que funciona con otras librerías Ajax).

Para disfrutar de la simplicidad de ActiveRecord.js:

Algunas notas:
  • No todos los tests unitarios funcionan con IE ahora mismo
  • Pronto se implementará un hack de persistencia para IE (cookies / form / etc)
  • Las relaciones Muchos a Muchos aún han de ser implementadas
  • Todas las validaciones incorporadas con Rails serán portadas (al igual que ActsAsList y ActsAsTree)

La sincronización de datos entre el cliente y el servidor aún es una cuestión abierta. En el equipo están intentando que se cambie la especificación de HTML 5 para que soporte consultas SQL síncronas desde Web Workers (hilos Javascript) asíncronos, y no soportarán consultas SQL asíncronas a menos que se ratifique ese cambio. También incluye soporte experimental de la especificación SQL de HTML 5 tal y como la implementa Safari, aunque resulta muy difícil de utilizar.

20 enero, 2009

Javascript más Seed igual a Linux Shell

Ryan Paul de publica en ArsTechnica un artículo explicando la posibilidad de crear aplicaciones de escritorio para Linux gracias a Seed. Además desde Seed se tiene acceso a todas las librerías que tienen datos GIR disponibles: Cairo, Clutter, Avahi, GTK+, GConf, OpenGL, GooCanvas, WebKit, Poppler, Pango, libsoup, libnotify, y libxml2.

Por ejemplo, el código siguiente es un script tradicional para Linux que crea una nueva ventana (gracias a GTK) e incluye un botón que muestra el típico hola mundo! al pulsarse:

#!/usr/bin/env seed

// Importa las bibliotecas usadas por el programa
Seed.import_namespace("Gtk");

// Inicializa GTK+
Gtk.init(null, null);

// Crea la ventana de aplicación principal y establece el título
var window = new Gtk.Window({title: "Hola mundo"});
// Hace que el programa termine cuando se cierre la ventana
window.signal.hide.connect(Gtk.main_quit);

// Crea un botón con etiqueta
var button = new Gtk.Button({label: "haz click"});

// Hace que el botón muestre texto cuando se pulse
// Pasa una función anónima al gestor de señales
button.signal.clicked.connect(function(w) {
  Seed.print("Hola mundo!");
});

// Agrega el botón a la ventana y lo muestra todo
window.add(button);
window.show_all();

// Inicia el bucle principal de GTK+ y con él el programa
Gtk.main();

Via Ajaxian.

Un par de comandos para Ubiquity

He decidido probar a crear un par de comandos para Ubiquity, la extensión de Firefox que permite acceder a información y lanzar comandos desde el mismo navegador. Usa Javascript (cómo no) como lenguaje y la especificación de comandos es relativamente sencilla cuando se conoce la URL en la que realizar la petición.

Los comandos creados permiten consultar la definición de la Real Academia de la Lengua de un término y también consultar la disponibilidad de un dominio (si no se indica extensión del primer nivel, se asume .com).

Definición de un término

CmdUtils.CreateCommand({
  name: "drae",
  icon: "http://www.rae.es/favicon.ico",
  author: {name: "Digitta"},
  takes: {"palabra": noun_arb_text},
  description: "Buscar el término en el diccionario de la Real Academia",
  preview: function(pblock, cmd){
    pblock.innerHTML = "Definir el término,según el diccionario de la RAE: " + cmd.text;
    CmdUtils.previewGet(pblock,
               "http://buscon.rae.es/draeI/SrvltGUIBusUsual?TIPO_BUS=0&LEMA=" + cmd.text.toLowerCase(),
               null,
               function (a) {pblock.innerHTML=(a);}
               );

  },
  execute: function(cmd){
    var search = cmd.text;
        var newCmd = search.replace(/\s+/g, "+");
    var url = "http://buscon.rae.es/draeI/SrvltGUIBusUsual?TIPO_BUS=0&LEMA=" + newCmd ;
    openUrl(url);
    //    Utils.openUrlInBrowser(url);
  }
});

Consulta de disponibilidad de un dominio

CmdUtils.CreateCommand({
  name: "dns",
  icon: "http://www.networksolutions.com/favicon.ico",
  author: {name: "Digitta"},
  takes: {"dominio": noun_arb_text},
  description: "Comprobar la disponibilidad de uno o más dominios",
  preview: function(pblock, cmd){
    pblock.innerHTML = "DNS: " + cmd.text;
    CmdUtils.previewGet(pblock,
                        "http://www.easydomaincheck.com/checkdomain4.php?domains=" + cmd.text.toLowerCase() +(!~cmd.text.toLowerCase().indexOf('.')?'.com':''),
               null,
               function (a) {pblock.innerHTML=a.substr(a.indexOf('<table'),a.indexOf('</table>')+8-a.indexOf('<table'));}
               );

  },
  execute: function(cmd){
    var search = cmd.text;
        var newCmd = search.replace(/\s+/g, "+");
    var url = "http://www.easydomaincheck.com/checkdomain4.php?domains=" + newCmd +'%0A' + newCmd + '.com';
    openUrl(url);
    //    Utils.openUrlInBrowser(url);
  }
});

Instalación


Si lo que quieres es instalar los comandos, sigue estas instrucciones.

12 enero, 2009

Una implementación de "isArray" y un "getContent" local

Es conocida la problemática que existe en Javascript para algo tan simple como comprobar si una variable es realmente un Array (Matriz/Arreglo). En Perfection Kills proponen una implementación simple de la comprobación de si una variable es un Array que parece más robusta que las que se han usado hasta ahora:

typeof null; // "object"
typeof []; // "object"
var arr = []; 
arr instanceof Array; // true
arr.constructor == Array; // true, pero da problemas entre frames
arr.constructor === Array; // false
typeof myArray.sort == 'function' // si tiene definida la función sort
// finalmente la opción que se ha demostrado más fiable es:
function isArray(o) {
  return Object.prototype.toString.call(o) === '[object Array]'; 
}
Por otro lado, Andrés Nieto ha reescrito una función de CSSGallery.info para que sea independiente y no necesite ninguna librería. Lo que hace esta función es cargar de forma transparente un recurso mediante Ajax, identificando si se trata de un recurso local (file:///archivo) o uno remoto tradicional (http://site/camino/archivo). Resulta muy útil para principiantes cuando descargan algo para probarlo en local.
function get_content(url,update) {
  if ( document.location.protocol == "file:" ) {
    var ifr = document.createElement("iframe");
    ifr.src = url;
    ifr.onload = function() {
 document.getElementById(update).innerHTML = this.contentWindow.document.body.innerHTML;
    }
    document.getElementsByTagName("body")[0].appendChild(ifr);
  } else {
    var ajax = (XMLHttpRequest)?new XMLHttpRequest():new ActiveXObject('Microsoft.XMLHTTP');
    ajax.open('GET', URL);
    ajax.onreadystatechange = function(){
  document.getElementById(update).innerHTML = ajax.responseText;
    };
    ajax.send(null);
  }
}

09 enero, 2009

Estética en la documentación de código

Siempre se ha dicho que los programadores somos muy malos diseñando. Siempre he sospechado que se trata de otra de esas generalizaciones peligrosas...

Hoy, Atul Varma publica una excelente idea: usar Javascript para presentar al vuelo la documentación de un archivo de código junto con el mismo código en dos columnas separadas tal y como puede verse a continuación...



link
. código original del ejemplo.

La idea no puede ser más acertada, ya que la mayoría de herramientas actuales exigen una etapa inevitable para generar la documentación en formato HTML (como si se estuviese compilando un ejecutable). Internamente hace uso del estándar WikiCreole para el formato.

Via Ajaxian.

05 enero, 2009

UniversalComet, el navegador como servidor

Malte Ubl ha creado UniversalComet, una prueba conceptual de una implementación de Comet (con una petición continua (polling) JSON-P (javascript callback) entre dominios) usando para ello Google App Engine (se usa un polling tradicional porque App Engine no permite conexiones prolongadas y hace un timeout). En este caso, el servidor de la página no es el mismo que el que ofrece el servicio de conexión Comet.

Cada página abierta recibe un identificador único que se utiliza con el fin de recibir las comunicaciones de forma unívoca. La propiedad window.name se usa para almacenar dicho ID. UniversalComet forma parte de Joose, un sistema de meta objetos para Javascript. La librería Dojo ofrece características similares aunque Joose está más enfocada en este tipo de características y funciona con otras librerías como jQuery. La técnica usada en este ejemplo hace uso de otra descrita en este blog hace unas semanas.

Demo incrustada:
* puedes abrir más ventanas para comprobar como los mensajes emitidos en cualquier de ellas se reciben por todas las demás...

Cada página abierta mantiene una conexión con el servidor para recibir actualizaciones (necesarias para un chat o una web de información sobre valores de bolsa). Si Google Gears está disponible (aunque no es necesario para que funcione), se usa una única conexión a nivel de navegador. El código es realmente sencillo:

// es necesario cargar primero la librería:
// <script type="text/javascript" src="http://universal-comet.appspot.com/static/client-server-mini.js"></script>

var server = new Addressable.Server();
 
server.onmessage = function (message) {
  alert(message)
}
 
server.connect(function (id, url) {
  // send url to you server using AJAX
})

Servicios web sobre el sistema DNS

Via Simon Willison encuentro esta web de David Leadbeater con una descripción de un servicio implementado por él para acceder a resumenes de artículos de la Wikipedia. Pero lo curioso de su implementación no reside en lo que hace sino en cómo lo hace: en lugar de usar el método habitual e implementar una interfície REST o la infumable SOAP, decide aprovechar el sistema de conversión de nombres de dominio (DNS) y aprovecharlo como un sistema para unir claves (la consulta del término) a descripciones...

Así que en foo.wp.dg.cx tiene implementado un servidor DNS que devuelve los resultados como registros TXT: Las respuestas están limitadas a 430 bytes y sólo usa UDP en lugar de una sesión TCP (más lenta), aunque por otra parte el resultado queda cacheado en el cliente DNS del usuario, debe soportar Unicode, acepta UTF-8 como entrada y es mucho más rápido que el tradicional HTTP.

Para probarlo se puede realizar una petición desde la consola:

linux$ host -t txt dns.wp.dg.cx

windows> nslookup -type=TXT dns.wp.dg.cx
con el resultado en ambos casos:

"DNS may refer to: Domain Name System, Internet system to translate names into IP addresses, Direct numerical simulation, 3,5-Dinitrosalicylic acid, Dinas Powys railway station, Wales (National Rail station code DNS), Doctor of Nursing Science \226\128\148 see Doctorate in Nursing, Deviated septum or deviated nasal septum, a physical disorder of the nose involving a displacement of the... http://a.vu/w:DNS"

Leadbeater también ofrece el servicio sobre HTTP (http://js-wp.dg.cx/js/dns) con un script greasemonkey de ejemplo que hace uso del servicio, y con una prueba con JSONP (javascript callback). También existe una presentación del servicio aquí.

No deja de ser una innovación en cuanto a implementación de un servicio web, aunque debido a la naturaleza del sistema DNS no pueda aprovecharse directamente desde el navegador...

Últimos links en indiza.com