Contenido

Protocolo relativo de URLs

28 oct

+ 14

Paul Irish publica un interesante truco para facilitarnos el trabajo con las URL’s de nuestras aplicaciones web.

<img src="//domain.com/img/logo.png">

De esta forma, el navegador selecciona por nosotros el protocolo que debe usar, que en todo caso será el mismo en el que estemos corriendo la aplicación. Ideal para los casos en los que disponemos de secciones en HTTPS y otras en HTTP, para evitar el molesto mensaje de error.

Al igual que si estamos usando el protocolo file:// desde nuestra máquina, tambien usará esa ruta de ficheros dentro de nuestro disco duro para intentar cargar la la URL indicada.

En los ficheros CSS tambien podemos usar esta técnica, aunque en Internet Explorer 7 y 8 provoca un fallo que hace que el fichero se descargue dos veces (¬¬).

.omgomg { background: url(//websbestgifs.net/kittyonadolphin.gif); }

Técnicamente se llama “Relative Reference” y está especificada en el RFC 3986.

¿Comas antes o después?

26 oct

+ 16

En CSS Trick publican un artículo en relación a un Tweet de Marc Grabanski que pregunta:

¿Comas antes o después de la línea en objetos JSON para definiciones múltiples?

Básicamente se refiere a donde colocamos la coma a la hora de generar estructuras JSON de varios elementos.

// commas antes
var vampyre = {
    teeth: 'sharp'
  , blood: 'stale'
  , age: 320
}

// commas despues
var vampyre = {
    teeth: 'sharp',
    blood: 'stale',
    age: 320
}

Yo personalmente suelo ponerlas detrás,  aunque leyendo el artículo he descubierto las ventajas de ponerlas delante. Por ejemplo a la hora de comentar la última línea, que te obliga a borrar la coma de la última posición no comentada.

// commas despues
var vampyre = {
    teeth: 'sharp',
    blood: 'stale', // Esta coma hay que borrarla
 //   age: 320
}

Ambas son dos forma correctas de declarar variables, o definir objetos JSON. ¿Cual usas tu?

Estadísticas de uso de jQuery en la red

26 oct

+ 9

Creo que a estas alturas no hay nadie que dude que jQuery se ha convertido en la librería Javascript más usada de Internet, pero ¿realmente sabemos en que medida es esta afirmación cierta?

jquery
(Ver Imagen)

La gente de BuiltWith ha sacado unas estadísticas procesado en HTML de hasta un millón de sitios y ha obtenido los gráficos que vemos sobre estas líneas, que indican el incremento en el tiempo de número de sitios web que usan jQuery en 3 rangos de páginas diferentes (10.000, 100.000 y 1 millón).

javascript
(Ver Imagen)

Otra gráfica interesante es la distribución del Javascript que nos encontramos en el millón de sitios webs utilizados para sacar la gráfica. Podemos ver como jQuery sigue siendo la librería más usada frente a SWFObject como interfaz para elementos flash.

jDoctest, saca partido a la documentación de tus scripts

26 oct

+ 1

jDoctest es una librería basada en el módulo de documentación de Python que permite aprovechar la documentación de nuestros scripts para realizar pruebas sobre nuestros scripts.

La idea es muy sencilla, tu comentas tu código, con un formato definido por la librería, en la documentación pones ejemplos de código que permitan probar ciertos puntos de tu script. Al cargar la jDoctest testeará que el código funciona como debería.

Compatibilidad

La librería funcionará con la mayoría de navegadores, el autor avisa de que Internet Explorer no está soportado debido a la diferente implementación de la función eval().

Instalación

Como todas las librerías Javascript, la instalación no es más complicada que cargar los ficheros necesarios en nuestro HTML.

<script src="jquery.js"></script>
<script src="jdoctest.js"></script>
<script>
  jDoctest.testSource( "imagefile.js" );
</script>

Preparando nuestro código

Nuestro código ha de estar debidamente comentado y para ello usaremos una sintáxis similar a esta para que la librería detecte los comentarios y pueda ejecutar las pruebas.


var ImageFile = function( url ) {
    /**class:ImageFile( url )

    A container for an image file.

        >>> var img = new ImageFile( "_static/jdoctest.png" );
        >>> img.url;
        '_static/jdoctest.png'
    */
    this.url = String( url );
};
ImageFile.prototype = {
    fetchData: function() {
        /**:ImageFile.prototype.fetchData()

        Requests the server for the image file. When the request is
        complete, it also sets the ``size`` and ``modified`` attributes
        of the object.

            >>> img.fetchData();
            >>> wait(function() { return img.data; });
            >>> img.size;
            30295
            >>> img.modified; //doctest: +SKIP
            Sat Sep 25 2010 19:57:47 GMT+0900 (KST)
        */
        $.get( this.url, function( data ) {
            this.data = data;
            this.size = data.length;
            this.modified = new Date(); // Not Implemented Yet
        });
    }
};

El resultado aparecerá en la consola de Firebug aunque está preparado para funcionar con QUnit. Y nos mostrará el resultado de los tests que hayas informado.

Si estás interesado en saber más sobre la librería, te recomiendo que le eches un vistazo a la documentación disponible por que permtie hacer cosas interesantes.

Convierte las rutas de tu WordPress en relativas

26 oct

+ 8

456 Berea St publica un pequeño script para convertir las url’s absolutas de nuestro WordPress en relativas. El script se basa en el uso de una expresión regular que elimina el protocolo y el dominio y nos deja la url recortada allá donde la usemos.

function make_href_root_relative($input) {
    return preg_replace('!http(s)?://' . $_SERVER['SERVER_NAME'] . '/!', '/', $input);
}

Esta función nos permitirá convertir cualquier url que le pasemos como parámetro, si además usamos el filtro asociado a the_permalink(), esto se propagará por la aplicación y reemplazará la mayoría de url’s que usen este método.

function root_relative_permalinks($input) {
    return make_href_root_relative($input);
}
add_filter( 'the_permalink', 'root_relative_permalinks' );

Una forma rápida de relativizar tus url’s :D

Mide el tiempo de carga de tu página con Google Analytics

25 oct

+ 6

Las estadísticas nunca están de más y disponerlas todas reunidas donde puedan ser cruzadas, nos permitirá realizar combinaciones de lo más variopintas. El tiempo de carga de la página es algo que por norma general no suele estar entre la mayoría de servicios de estadísticas, pero gracias al ingenio y la fléxibilidad de Google Analytics puedes integrar este dato en tus estadísticas de Google Analytics.

landing_page_time copia
(Ver Imagen)

Estos gráficos indican el tiempo en milisegundos que ha tardado la página en cargarse.

<html>
<head>
 <script type="text/javascript">
 //<![CDATA[
    var page_load_start = new Date();
    var _gaq = _gaq || [];
    window.onload =  function() {
      var page_load_end = new Date();
      var load_time = page_load_end.getTime() - page_load_start.getTime();
      load_time = parseInt( load_time / 100 )*100;
      _gaq.push(["_setCustomVar",1,'landingPageTime',load_time,2]);
      _gaq.push(["_setAccount","UA-xxxxxxxx-y"]);
      _gaq.push(["_trackPageview"]);
    };
 //]]>
 </script>
 <!-- Here goes the rest of your head section --/>
</head>
....
<body>
<!-- Your web page goes in here --/>
<script type="text/javascript">
 //<![CDATA[
    (function() {
      var ga = document.createElement('script');
      ga.type = "text/javascript"; ga.async = true;
      ga.src  = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
      var s = document.getElementsByTagName('script')[0];
      s.parentNode.insertBefore(ga,s);
    })();
 //]]>
 </script>
</body>
</html>

Como podemos ver, simplemente inicializamos un contador para obtener el tiempo completo desde que se inicializa hasta que la página está cargada, concretamente en el evento onload(). No creo que sea un sistema muy exácto, pero nos dará un valor de referencia que poder usar en nuestras estadísticas.

Integra un ORM con Javascript y WebSQL

25 oct

+ 6

Inspirado en el modelo de Django, ORM-HTML5 nace para ayudarnos con la tarea de trabajar con estructura de datos almacenadas en la base de datos que HTML5 nos integra en el navegador, concretamente con WebSQL.

ORM (Mapeo objeto-relacional)

La técnica de programación que usamos para mapear los datos de una base de datos a objetos que podemos usar en nuestros scripts es la que conocemos como ORM (Object-Relational mapping).

Esta técnica, muy usada en la mayoría de frameworks de los diferentes lenguajes de programación ha permitido que la tarea de trabajar con objetos relacionados con la base de datos se simplifique sustancialmente.

ORM-HTML5

La nueva versión de HTML dispone de un apartado dedicado al almacenamiento en local, para ello usará un sistema basado generalmente en SQLite, que nos permitirá alojar una serie de datos que podremos usar en nuestros scripts sin necesidad de interactuar con el servidor, necesariamente.

ORM-HTML5, es una implementación más, desarrollada por JM Robles,  y que nos permite disfrutar de esta técnica en nuestras páginas web.

Instalación

Como cualquier otra librería javascript bastará con cargar el fichero orm.js desde nuestra página.

<script language="JavaScript" src="orm.js"></script>

Definiendo el modelo

<script language="JavaScript">
   function Client(db){
        this.base = ModelBase;
        this.base("client");         // Name of table
               // Specifies the fields:
               //             name:       string not null
               //             surname:    string
               //             age:        integer
        this.fields = ["snName", "sSurname", "iAge"];
               // Preload objects in table
        this.predata = [   {id:1, name: 'John' , surname: 'Smith', age: 20 },
                           {id:2, name: 'Ana' , surname: 'Castillo', age: null} ];
        // Initialiaze
        this.init(db);
    }
    // Create DB Manager
    dbm = new DBM('ERP');
    // Register your models
    dbm.register(['Client']);
</script>

El modelo define la estructura de tablas que se crearán en la base de datos al aplicar el método  DBM.register().

Usarlo

<script language="JavaScript">
 var c = new Client(dbm);
 c.name = 'David';
 c.surname = 'Lohan';
 c.age = '30';
 c.save(function (result) { if (result) alert('save ok'); });
</script>

De esta forma, estaremos cargando datos en la base de datos a la vez de disponer del objeto Client del que podremos disponer en nuestro código.

Alternativas a ORM-HTML5

TwitterWeek – 2010-10-24

24 oct

+ 3

En mi twitter he publicado estos enlaces que creo os pueden interesar.

Saludos

Foreach asíncrono en Javascript

22 oct

+ 5

Zef Hemel publicó hace unos días un script capaz de convertir el ya conocido forEach() de Javascript en una versión asíncrona de la misma.

forEach()

Como ya sabemos desde la revisión 1.6 de Javascript (Firefox, Netscape 7/8,  Opera 7+) el objeto Array dispone de un método que permite recorrer sus elementos de una forma sencilla y recursiva, permitiéndonos definir una funcionalidad que será ejecutada para cada una de las posiciones del Array.

var _array = ["casa", "coche", "pelota"];

_array.forEach(function(item){
 console.log("_array contiene ->" + item);
});

Por el momento, no todos los navegadores disponen de ellos, y la mayoría de frameworks JS se encargan de definir su propia versión para facilitar el desarrollo. Mozilla Developer Center ofrece una versión interesante:

if (!Array.prototype.forEach)
{
  Array.prototype.forEach = function(fun /*, thisp */)
  {
    "use strict";

    if (this === void 0 || this === null)
      throw new TypeError();

    var t = Object(this);
    var len = t.length >>> 0;
    if (typeof fun !== "function")
      throw new TypeError();

    var thisp = arguments[1];
    for (var i = 0; i < len; i++)
    {
      if (i in t)
        fun.call(thisp, t[i], i, t);
    }
  };
}

El problema es que este sistema es completamente síncrono, osea realiza una funcionalidad y luego otra, mientras haya elementos en el Array. Para esto, Zef, presenta la siguiente propuesta:

function asyncForEach(array, fn, callback) {
  array = array.slice(0);
  function processOne() {
    var item = array.pop();
    fn(item, function(result) {
        if(array.length > 0) {
          setTimeout(processOne, 0); // schedule immediately
        } else {
          callback(); // Done!
        }
      });
  }
  if(array.length > 0) {
    setTimeout(processOne, 0); // schedule immediately
  } else {
    callback(); // Done!
  }
};

Básicamente se trata de una fnción que se llama a si misma recursivamente por cada elemento del Array. Para evitar que el navegador nos alerte de una ejecución muy larga, con Arrays de 1000 elementos o más, se usa el viejo truco del setTimeout() que permite ejecutar funcionalidades por un tiempo indefinido.

A raiz de este artículo han ido apareciendo implementaciones varias usando la misma técnica:

Al igual que Zef, opino que esta funcionalidad es muy pesada y consume una gran cantidad de recursos, pero nos permite trabajar con una cántidad de datos de forma asíncrona. Por lo tanto, a usarla con cabeza :D

Actualización:

Chuso me avisa de un artículo que ha escrito hace unos días sobre el tema, quizás te pueda interesar.

Convierte una aplicación web en nativa para iPhone/iPad

22 oct

+ 2

La muestra de que las aplicaciones web móviles son el futuro y de que la conectividad que ellas permiten están haciendo que la mayoría de negocios se esten migrando a Internet es la facilidad con la que navegadores móviles como Safari Mobile nos permiten transformar una página web en una aplicación nativa para estos dispositivos (al menos en apariencia).

iphone-app
(Ver Imagen)

En matt.might.net publican una serie de parámetros que deberemos conocer para conseguir que la apariencia de nuestra página sea prácticamente igual a la de cualquier aplicación nativa que descarguemos de la App Store y sin necesidad de tener que convertirla a Object C.