Archivo de la etiqueta: JavaScript

js-icon

Javascript: Eliminar un item de un array por su nombre

Pongan esto en su codigo:

Array.prototype.removeItem = function (a) {
    for (var i = 0; i < this.length; i++) {
      if (this[i] == a) {
        for (var i2 = i; i2 < this.length - 1; i2++) {
          this[i2] = this[i2 + 1];
        }
        this.length = this.length - 1;
        return;
      }
    }
  };

Y ya podemos eliminar elementos del array:

var frutas = ['manzana', 'banana', 'pera'];
frutas.removeItem('banana');
console.log(frutas); // Entrega ['manzana', 'pera']

Chau!

js-icon

Boilerplate (esqueleto) de plugin jQuery de la casa y en español ;)

Hola!. Me complace anunciar que pongo a disposición de todo el que quiera hacer plugins de jQuery, el boilerplate que he estado usando en los últimos años.

Es otro boilerplate como los demas, con la diferencia que al estar usandolo todo el tiempo lo fui puliendo poco a poco. Pero mucho mas importante: está en español XD

Pase pasen y vean https://github.com/capynet/jQueryPluginBoilerplate

Chau!

PHP

Detectar el navegador y toda su información desde PHP o Javascript

Hola, les hago una intro bien corta y pasamos al código.

Browscap es un proyecto que recoge la información de todos los navegadores web en una base de datos que distribuye de forma gratuita y en varios formatos.

PHP tiene soporte nativo para hacer uso de esta DB, pero debido a un par de limitaciones que PHP aun no ha solventado en su API, en GitHub un usuario creó una soluciona basada también en la DB de Browscap pero mucho mas robusta y fácil de usar.

Bien, llegados a este punto sabemos que lo que necesitamos usar es Browscap junto a la librería que se creó para explotarla.

Para mas información, toda la documentación completa de php-browscap la pueden encontrar aquí. Yo me centro en una implementación mucho mas simple porque realmente creo que de los 40 datos que entrega sobre el navegados, con apenas 7 tenemos el 99% de los casos cubiertos.

Acá tienen un ejemplo funcionando para que vean lo rápido y certero que es a la hora de conseguir la info del browser (pruébenlo con mas de uno)

Ok, pongamos algo de código que sino todo esto es muy aburrido:
Vamos a aprovechar esta librería bajo dos situaciones. en PHP y en JS

En PHP

Descarguen la librería php-browscap via Composer o a mano. Pueden saber mas sobre como descargarla aquí
Ahora que la tenemos creamos un archivo index.php para usarla.

<?php
require 'vendor/autoload.php';
use phpbrowscap\Browscap;
$bc = new Browscap('cache');
/** @var stdClass $current_browser */
$current_browser = $bc->getBrowser();
?>

Fácil, no?. Ok ya tenemos un stdClass en $current_browser con toda la información disponible del browser que llame a index.php

Aplicaciones?

Puedes por ejemplo tomar decisiones del tipo

<?php
$curr_br = $current_browser->Browser;
$CoolBrowsers = $curr_br == 'Chrome' || $curr_br == 'Firefox';
if ($CoolBrowsers) {
  add_asset('css', 'just-for-cool-browsers.css');
  $output = renderAdvancedLayout();
}
else {
  add_asset('css', 'just-for-bad-bad-browsers.css');
  $output = renderBasicLayout();
}
?>

También puedes detectar si están accediendo desde un móvil o una tablet, incluso saber si es Android, IOS, la version del SO, etc. Con toda esta información a resumidas cuentas puedes entregar un contenido muy preciso.

Beneficios

Estas entregando contenidos a medida, ergo necesitas entregar menos HTML, CSS, Js y las imágenes mas adecuadas al navegador. Esto finalmente se traduce en menos procesamiento del lado del servidor, lo que se entrega pesa menos KB y el navegador tarda menos en leer y renderizar todos los recursos (en especial JS).

En JS

Por ultimo me gustaría compartir un tip para poder aprovechar la detección de browsers en JS:
A ver, con js podemos detectar el browser usando un poco de expresiones regulares, pero llegar al detalle y la precisión a la que llega browscap es virtualmente imposible. Dicho esto, comentar que se puede entregar toda la información del browser detectado desde php simplemente haciendo esto:

<script type="application/javascript">
  var browser = <?php= json_encode($current_browser = $bc->getBrowser()); ?>;
  alert(browser.Browser);
  alert(browser.Version);
</script>

Hasta la próxima!

Node.js

Tutorial: implementar un servicio RESTful public API de modelos Mongoose en Node.js

Hola!, He terminado de hacer un ejemplo de como implementar una API pública tipo RESTful en una APP creada con express.
La idea detrás de esta app de ejemplo es la de crear automagicamente todas las URL necesarias para poder gestionar un modelo de Mongoose (aka recurso).

Su uso es realmente simple. Dentro de la carpeta “models” creas un nuevo modelo/entidad, tocas un par de detalles mas, y tienes una API publica completa de ese nuevo recurso :)

Ya no doy mas vueltas, acá la tienen:

https://github.com/capy/Simple-API-style

Chau!

Node.js

Node.js/express: Gestionar las URL de tu proyecto mas eficientemente.

Normalmente cuando haces una aplicación usando express, por comodidad tiendes a poner todas las definiciones de las url’s en la raíz del proyecto:

var express = require('express');
var app = express();
//...
//Configuraciones varias
//...
app.get("/users", function (req, res) {
    return res.render("list users");
});
app.get("/user/:uid", function (req, res) {
    return res.render("show an user");
});
app.get("/articles", function (req, res) {
    return res.render("list articles");
});
app.get("/article/:id", function (req, res) {
    return res.render("show an article");
});
app.get("/article/new", function (req, res) {
    return res.render("new article");
});
http.createServer(app).listen(app.get('port'), function () {
    console.log("http://localhost:" + app.get('port'));
});

Pero esto a la corta se vuelve algo inmanejable. La solución es adoptar un patrón que nos permita extraer las URL a archivos en los que poder juntar las url que se refieran a algo en común (en este ejemplo usuarios por un lado y articles por otro.).

Manos a la obra

crea un directorio llamado routes, crea los archivos “users.js” y “articles.js” y llévate allí las urls.
En el lugar que estaban las URL (dentro de app.js o server.js, como sea que lo hayas llamado.) pon:

var routePath = __dirname + '/routes/';
fs.readdirSync(routePath).forEach(function (file) {
    require(routePath + file)(app);
});

Este snippet se va a encargar de cargar todos los archivos que haya en la carpeta routes. Si te fijas bien vas a ver que está haciendo un require pero le pasa “(app)” al final de este. Eso es porque dentro de nuestros archivos de rutas vamos a devolver funciones que van a ejecutarse ni bien sean cargadas.

Lo ultimo que nos queda es definir la estructura que debe tener cada archivo que esté alojado en routes. Como ya no están en la raíz, vamos a encapsular estas definiciones de rutas dentro de una función, que es la que se va a encargar de hacernos llegar a app (que es la instancia de express que va a recibir nuestras rutas):

users.js:

module.exports = function (app) {
    app.get("/users", function (req, res) {
        return res.render("list users");
    });
    app.get("/user/:uid", function (req, res) {
        return res.render("show an user");
    });
};

articles.js:

module.exports = function (app) {
    app.get("/articles", function (req, res) {
        return res.render("list articles");
    });
    app.get("/article/:id", function (req, res) {
        return res.render("show an article");
    });
    app.get("/article/new", function (req, res) {
        return res.render("new article");
    });
};

Como podemos ver, en cada uno de los archivos que contienen las rutas, hemos metido las rutas dentro de module.exports = function (app){}. Esto sumado a que a cada archivo cargado se le estaba pasando la app por medio del require (require(routePath + file)(app);) todo cobra sentido.

Ya hemos acabado, ya puedes crear tantos archivos .js como tu corazón y lógica dicten, que se van a cargar sin problemas.

Chau!

1263055255_application-javascript

Generar propiedades de un objeto (JSON) dinámicamente.

El caso es el siguiente: Tenemos un objeto al que queremos crearle propiedades anidadas pero nos gustaría no tener que preocuparnos de si sus parent existen. por ejemplo, si tuviera un objeto “miObjeto” y quisiera crearle una función en miObjeto.modulos.ctools.watcher, primero tendría que crear ese path. eso o podemos usar esta función:

/**
 * Genera propiedades de un objeto (JSON) dinamicamente.
 * @returns objeto extendido.
 */
function extend(base, ns_string) {
    var parts = ns_string.split('.'),
        pl, i;
    pl = parts.length;
    for (i = 0; i < pl; i++) {
        //create a property if it doesnt exist
        if (typeof base[parts[i]] == 'undefined') {
            base[parts[i]] = {};
        }
        base = base[parts[i]];
    }
    return base;
}

Y listo, ya podemos extender nuestro objeto de forma dinámica:

var miObjeto = {};
//console.log("Esto va a dar error porque 'modulos.ctools.watcher' no existe");
//console.log(miObjeto.modulos.ctools);
extend(miObjeto, 'modulos.ctools.watcher');
extend(miObjeto, 'settings.general');
miObjeto.modulos.ctools.watcher = function () {
    console.log("Soy una función!");
};
console.log(miObjeto);

Resultado:
resultado-objeto-propiedades-dinamicas
Chau!

Node.js

Hacer proxy con Apache para aplicaciones node.js

Tenemos una app desarrollada en nodejs que corre en el puerto 4000 de nuestro servidor y queremos exponerla por el puerto 80 para que la gente pueda usarla. El problema obvio es que por lo general tenemos corriendo un apache, nginx o cualquier otro servidor http.

La solución es usar los módulos de proxy que incluyen cada uno de estos servidores web. Hoy puntualmente lo vamos a hacer con Apache.

Habilitamos los modulos proxy y proxy_http para permitir el reenvío de peticiones HTTP y HTTPS:

sudo a2enmod proxy
sudo a2enmod proxy_http

Luego nos queda crear un vhost:

sudo nano /etc/apache2/sites-available/mipaginaweb.com

Y ponerle lo siguiente:

<virtualhost *:80>
    ServerName mipaginaweb.com
    ServerAlias www.mipaginaweb.com
    ProxyRequests off
    <proxy *>
        Order deny,allow
        Allow from all
    </proxy>
    <location "/">
        ProxyPass http://localhost:4000/ retry=0
        ProxyPassReverse http://localhost:4000/
    </location>
</virtualhost>

Habilitamos nuestro nuevo vhost:

sudo a2ensite mipaginaweb.com

Hemos terminado. reiniciamos apache y a correr!

sudo service apache2 restart

Bonus: si estas en un entorno de desarrollo y quieres acceder a mipaginaweb.com, edita tu archivo hosts (sudo nano /etc/hosts) y añade tu nuevo dominio:

127.0.0.1 localhost
127.0.0.1 mipaginaweb.com www.mipaginaweb.com
js-icon

Olvídate de Powerpoint y comenza a usar impress.js

La primera vez que vi un slide parecido a impress.js fue en la DrupalCamp del año pasado (2011). En ese caso lo que vi era Prezi.

Tanto impress.js como Prezi son aplicaciones que nos permiten hacer slides pero de una forma mucho mas atractiva haciendo uso de zoom, rotación, perspectiva y alguna que otra cosita mas.

Es solo verlo para entender el potencial de este tipo de herramientas:
En Chrome o Safari abran este link y usen las flechas izquierda y derecha o simplemente la barra espaciadora para avanzar.

A que esta bueno!?

Para poder implementar esta libreria tenemos dos opciones. La fácil y la divertida.

La fácil es usar una app llamada “Impressionist”  que ha desarrollado Harish Sivaramakrishnan y que es la mar de simple. Solo tenes que ir agregando slides y en cada una de ellas vas colocando el texto o imagenes y finalmente podes descargar el slide terminado.

Link: http://hsivaram.com/impressionist/0.1/

La forma divertida: Hagamoslo nosotros :D

Vamos a hacer una implementación bien simple:

<div id="impress">
    <div class="step slide" data-x="1000" data-y="">
        Comenzamos con un tipico y aburrido slide
    </div>
    <div class="step slide" data-x="2000" data-y="">
        Hasta el siguiente mismo tipo de aburrido slide...
    </div>
    <div class="step" data-x="3000" data-y="" data-scale="20">
        Pero la cosa pueda cambiar a mejor cuando hacemos zoom
    </div>
    <div class="step" data-x="4000" data-y="3000" data-rotate="90" data-scale="5">
        <p>O cuando nos desplazamos haciendo giros</p>
    </div>
    <div class="step" data-x="5500" data-y="2100" data-rotate="180" data-scale="10">
        <p>Y si encima aplicamos un buen zoom, podemos obtener cosas muy locas</p>
    </div>
    <div class="step" data-x="9000" data-y="5000" data-scale="1" data-z="-500" data-rotate="190"
         data-rotate-x="" data-rotate-y="0">
        Ah y tambien se puede hacer cosas en 3D
    </div>
    <div class="step" data-x="9000" data-y="5000" data-scale="1" data-z="-3000" data-rotate="190"
         data-rotate-x="" data-rotate-y="90">
        <img src="http://ecapy.com/Archivos/impress.js/logo-capy-morado.png"/>
    </div>
</div>
<script src="impress.js"></script>
<script>impress().init();</script>

Pueden verlo en funcionamiento pinchando acá.

Del código anterior no hay que explicar mucho, pero aclaro que:

  • Los “step” deben estar dentro del id #impress y a su vez este id es obligatorio.
  • Cada step es un div que utiliza propiedades para configurar la posición en la que esta colocado, el tamaño, la rotación, etc. las propiedades disponibles al día de hoy son:
    • data-x, data-y, data-z para el posicionamiento;
    • data-rotate-x, data-rotate-y, data-rotate-z, data-rotate para manipular la rotación.
    • data-scale para el escalado/tamaño.
  • Ya por ultimo solo estamos incluyendo impress.js e inicializandolo.

Chau!