<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0"><channel><atom:link rel="hub" href="http://tumblr.superfeedr.com/" xmlns:atom="http://www.w3.org/2005/Atom"/><description>Tech entrepreneur. Founder of YoteConozco. Plone / Python project leader &amp; programmer at Semic.</description><title>Marc Pampols</title><generator>Tumblr (3.0; @mpampols)</generator><link>http://marcpampols.com/</link><item><title>Node.js y Heroku</title><description>&lt;p&gt;Con la intención de renovarme un poco, decidí aprender lo básico de node.js y abrirme una cuenta en Heroku para probar y subir alguna pequeña aplicación en &amp;#8220;el cloud&amp;#8221;.&lt;/p&gt;
&lt;p&gt;Tras buscar un poco de información sobre node.js, me topé con un &lt;a href="https://www.youtube.com/watch?v=E1FcQPYoZZk" title="Taller nodejs con nacho soto" target="_blank"&gt;taller en video de Nacho Soto&lt;/a&gt; que muestra paso a paso como crear un chat multiusuario y al final subirlo a Heroku. ¡Perfecto! aunque el tio va algo acelerado (o quizás sea la edad&amp;#8230;) me pareció un punto de partida genial, y lo recomiendo.&lt;/p&gt;
&lt;h2&gt;Heroku&lt;/h2&gt;
&lt;p&gt;El primer paso es darte de alta en Heroku, puedes hacerlo con una cuenta gratuita si le vas a dar poco uso o simplemente quieras trastear un poco, como es mi caso. Luego hay que instalar el &lt;a href="https://toolbelt.heroku.com/" target="_blank"&gt;Heroku Toolbelt&lt;/a&gt;, que incluye el cliente necesario, y en la página de  &lt;a href="https://devcenter.heroku.com/articles/nodejs" target="_blank"&gt;Getting Started with Node.js on Heroku/Cedar&lt;/a&gt; está todo lo necesario para empezar.&lt;/p&gt;
&lt;p&gt;La gracia de Heroku es que puedes subir tu aplicación con sencillos comandos de Git, y a partir de ahí ya corre en su infraestructura de servidores, todo sin tener que preocuparte de instalar o configurar nada relacionado con sistemas operativos, librerias y demás. Con un simple &amp;#8220;git push heroku master&amp;#8221; se hace el deploy. Evidentemente hay que tener en cuenta algunas cosas como la configuración del puerto a utilizar, pero está todo muy bien indicado en las guías de &lt;a href="https://devcenter.heroku.com" target="_blank"&gt;&lt;a href="https://devcenter.heroku.com"&gt;https://devcenter.heroku.com&lt;/a&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;El siguiente es un ejemplo del output al lanzar el comando git push:&lt;/p&gt;
&lt;pre&gt;$ git push heroku master
Counting objects: 17, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (7/7), done.
Writing objects: 100% (9/9), 684 bytes, done.
Total 9 (delta 4), reused 0 (delta 0)

-----&amp;gt; Heroku receiving push
-----&amp;gt; Node.js app detected
-----&amp;gt; Resolving engine versions
       Using Node.js version: 0.4.7
       Using npm version: 1.0.106
-----&amp;gt; Fetching Node.js binaries
-----&amp;gt; Vendoring node into slug
-----&amp;gt; Installing dependencies with npm
...
&lt;/pre&gt;
&lt;h2&gt;Node.js&lt;/h2&gt;
&lt;p&gt;Node.js es un entorno de programación y una librería para crear servidores web con entrada/salida asíncrona y dirigida por eventos. Funciona con el motor JavaScript V8 creado por Google.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;¿Cuando podemos usar Node.js y para qué?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Node está construido con la idea de crear aplicaciones que necesiten una conexión persistente del navegador del cliente hacia el servidor, uno de los ejemplos es un chat, donde tenemos que recibir las actualizaciones de los mensajes lo más rápido posible, y Node permite hacerlo además de forma bastante óptima.&lt;/p&gt;
&lt;p&gt;Se utiliza también una técnica llamada &amp;#8220;Long-polling&amp;#8221;, una técnica que permite enviar datos del servidor al cliente, pero si el servidor no tiene datos que enviarle, en lugar de enviar una respuesta vacía (que es lo que haría con el &amp;#8220;polling&amp;#8221;), el servidor mantiene la petición del cliente hasta que tiene información nueva para enviarle. En la programación AJAX es conocido como &lt;a href="https://es.wikipedia.org/wiki/Comet" title="Programación Comet" target="_blank"&gt;Programación Comet&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Node es una buena opción para crear aplicaciones colaborativas, chats, y en definitiva, servicios en los que el cliente debe ver mucha información nueva sin tener que refrescar la página.&lt;/p&gt;
&lt;p&gt;Node es óptimo porque cada petición necesita solo unos pocos ciclos de CPU, ya que el bucle de eventos está bloqueado durante la ejecución de una funcion.&lt;/p&gt;
&lt;h2&gt;Chat en Node.js&lt;/h2&gt;
&lt;p&gt;Tras subir el chat a Heroku, se puede utilizar desde la siguiente URL:&lt;br/&gt;&lt;a href="http://high-cloud-1518.herokuapp.com/" target="_blank"&gt;&lt;a href="http://high-cloud-1518.herokuapp.com/"&gt;http://high-cloud-1518.herokuapp.com/&lt;/a&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Y en el siguiente repositorio de Github he dejado el código fuente del mismo:&lt;br/&gt;&lt;a href="https://github.com/mpampols/nodejs-chat" target="_blank"&gt;&lt;a href="https://github.com/mpampols/nodejs-chat"&gt;https://github.com/mpampols/nodejs-chat&lt;/a&gt;&lt;/a&gt;&lt;/p&gt;</description><link>http://marcpampols.com/post/23798707435</link><guid>http://marcpampols.com/post/23798707435</guid><pubDate>Sat, 26 May 2012 17:16:11 +0200</pubDate></item><item><title>Tutorial sobre caching</title><description>&lt;a href="http://www.mnot.net/cache_docs/"&gt;Tutorial sobre caching&lt;/a&gt;: &lt;p&gt;Un documento que resume muy bien los distintos tipos de cache en desarrollo web. Qué son, cómo funcionan, y cómo se implementan. Aunque bastante básico, ayuda a tener una buena base de conocimiento.&lt;/p&gt;</description><link>http://marcpampols.com/post/23501685647</link><guid>http://marcpampols.com/post/23501685647</guid><pubDate>Tue, 22 May 2012 00:02:44 +0200</pubDate></item><item><title>RESS, Responsive Design + Server Side Components</title><description>&lt;a href="http://www.netmagazine.com/tutorials/getting-started-ress"&gt;RESS, Responsive Design + Server Side Components&lt;/a&gt;: &lt;p&gt;Tutorial que enseña los conceptos básicos de RESS (Responsive Design + Server Side Components), y cómo puedes construir una página &lt;em&gt;responsive&lt;/em&gt; que funcione bien en resoluciones pequeñas con la ayuda de tecnologías server-side.&lt;/p&gt;</description><link>http://marcpampols.com/post/23341461167</link><guid>http://marcpampols.com/post/23341461167</guid><pubDate>Sat, 19 May 2012 11:34:14 +0200</pubDate></item><item><title>Instalar Haskell GHC en Ubuntu</title><description>&lt;p&gt;Decidí probar Haskell, siempre me habia picado la curiosidad por conocer un poco el lenguaje, y quedé sorprendido por lo bonito que parece ser.&lt;/p&gt;
&lt;p&gt;Lo instalé en una máquina virtual con Ubuntu 11.10 con los siguientes pasos:&lt;/p&gt;
&lt;p&gt;Primero, las dependencias:&lt;/p&gt;
&lt;pre&gt;$ sudo apt-get install libgmp3-dev freeglut3 freeglut3-dev&lt;/pre&gt;
&lt;ul&gt;&lt;li&gt;libgmp3-dev: Multiprecision arithmetic library developers tools &lt;/li&gt;
&lt;li&gt;freeglut3: OpenGL Utility Toolkit &lt;/li&gt;
&lt;li&gt;freeglut3-dev: OpenGL Utility Toolkit development files &lt;/li&gt;
&lt;/ul&gt;&lt;div&gt;&lt;br/&gt;Luego, bajamos la última versión, que ahora mismo es la 7.4.1:&lt;/div&gt;
&lt;pre&gt;$ wget &lt;a href="http://www.haskell.org/ghc/dist/7.4.1/ghc-7.4.1-i386-unknown-linux.tar.bz2"&gt;http://www.haskell.org/ghc/dist/7.4.1/ghc-7.4.1-i386-unknown-linux.tar.bz2&lt;/a&gt;&lt;/pre&gt;
&lt;p&gt;&lt;span&gt;&lt;br/&gt;Descomprimir y instalar, como cualquier otro paquete:&lt;/span&gt;&lt;/p&gt;
&lt;pre&gt;$ tar -xvvf ghc-7.4.1-i386-unknown-linux.tar.bz2&lt;/pre&gt;
&lt;pre&gt;$ cd ghc-7.4.1&lt;/pre&gt;
&lt;pre&gt;$ ./configure&lt;/pre&gt;
&lt;p&gt;&lt;br/&gt;Pero llegado este punto, da el siguiente error:&lt;/p&gt;
&lt;pre&gt;libgmp.so.3: cannot open shared object file: No such file or directory&lt;/pre&gt;
&lt;p&gt;&amp;#8230; que se arregla creando un symlink:&lt;/p&gt;
&lt;pre&gt;sudo ln -s /usr/lib/libgmp.so /usr/lib/libgmp.so.3&lt;/pre&gt;
&lt;pre&gt;$ sudo make install&lt;/pre&gt;
&lt;p&gt;&lt;br/&gt;Y una vez instalado, lanzamos el GHCi, el entorno interactivo del compilador GHC que hemos instalado, y probamos con un simple &amp;#8220;Hello world&amp;#8221; ejecutando el ghci.&lt;/p&gt;
&lt;pre&gt;rockhound@ubuntu:~/ghc-7.4.1$ ghci
GHCi, version 7.4.1: &lt;a href="http://www.haskell.org/ghc/"&gt;http://www.haskell.org/ghc/&lt;/a&gt;  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Prelude&amp;gt; "Hello world!"
"Hello world!"&lt;/pre&gt;
&lt;p&gt;&lt;br/&gt;Es un lenguaje curioso, funciona básicamente con llamadas a funciones. El compilador principal es el que he instalado, GHC, que está formado por ghc, el encargado de compilar, y ghi, el intérprete ghci.&lt;/p&gt;
&lt;p&gt;Para terminar, un enlace interesante si quieres aprender un poco de Haskell: &lt;a href="http://www.haskell.org/haskellwiki/Learn_Haskell_in_10_minutes"&gt;&lt;a href="http://www.haskell.org/haskellwiki/Learn_Haskell_in_10_minutes"&gt;http://www.haskell.org/haskellwiki/Learn_Haskell_in_10_minutes&lt;/a&gt;&lt;/a&gt;&lt;/p&gt;</description><link>http://marcpampols.com/post/21589314147</link><guid>http://marcpampols.com/post/21589314147</guid><pubDate>Sun, 22 Apr 2012 20:58:42 +0200</pubDate><category>haskell</category></item><item><title>¿Tienes un secreto de estado y temes por tu vida?</title><description>&lt;p&gt;Este servicio web puede ser de tu interés.&lt;/p&gt;
&lt;p&gt;Dead Man&amp;#8217;s Switch:&lt;br/&gt;&lt;a href="http://www.deadmansswitch.net/" target="_blank"&gt;&lt;a href="http://www.deadmansswitch.net/"&gt;http://www.deadmansswitch.net/&lt;/a&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Pero vamos por partes. Primero: ¿Qué significa esa expresión?&lt;/p&gt;
&lt;p&gt;La expresión &amp;#8220;Dead Man&amp;#8217;s Switch&amp;#8221; proviene de un sistema que se utiliza para detectar si un humano es incapaz de controlar una máquina en algún momento. Por ejemplo, los conductores de tren pueden tener un pedal que si en algún momento deja de ser pulsado, se activarán los mecanismos de freno.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.flickr.com/photos/wsdot/6636372829/" title="Dead man's switch by WSDOT, on Flickr"&gt;&lt;img align="middle" alt="Dead man's switch" height="320" src="http://farm8.staticflickr.com/7173/6636372829_3aed8b0c91_n.jpg" width="213"/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Hay multitud de variantes y casos de uso, y uno de ellos es el que han implementado en el servicio web &lt;a href="http://deadmansswitch.net" target="_blank"&gt;deadmansswitch.net&lt;/a&gt;, que se traduce de la siguiente manera.&lt;/p&gt;
&lt;p&gt;Podemos escribir y preprogramar una serie de mensajes, cada uno con sus correspondientes destinatarios. Dichos mensajes se encuentran cifrados en el servidor para que nadie pueda leerlos. Si en algún momento nos sucede algo, el dispositivo se activará y enviará los mensajes que hemos preparado. Se activará tras no detectar actividad por parte nuestra, de esta forma, nuestros secretos serán liberados. Se trata de una especie de seguro de vida.&lt;/p&gt;
&lt;p&gt;Tras guardar nuestros secretos, el servicio nos enviará correos electrónicos para comprobar que seguimos vivos pidiendo que cliquemos en un simple enlace. Si pasado un tiempo no damos señales de vida, la aplicación de Dead Man&amp;#8217;s Switch enviará nuestros mensajes a los destinatarios programados. Así de simple.&lt;/p&gt;
&lt;p&gt;No es un sistema perfecto, ya que pueden robarnos el acceso a nuestro correo electrónico y evitar que nuestros secretos sean revelados, pero es una buena primera implementación en el mundo digital.&lt;/p&gt;</description><link>http://marcpampols.com/post/21167086728</link><guid>http://marcpampols.com/post/21167086728</guid><pubDate>Sun, 15 Apr 2012 22:32:22 +0200</pubDate></item><item><title>Los Secretos de Silicon Valley (Inglés)
Una charla de Steve...</title><description>&lt;iframe width="400" height="300" src="http://www.youtube.com/embed/ZTC_RxWN_xo?wmode=transparent&amp;autohide=1&amp;egm=0&amp;hd=1&amp;iv_load_policy=3&amp;modestbranding=1&amp;rel=0&amp;showinfo=0&amp;showsearch=0" frameborder="0" allowfullscreen&gt;&lt;/iframe&gt;&lt;br/&gt;&lt;br/&gt;&lt;h2&gt;Los Secretos de Silicon Valley (Inglés)&lt;/h2&gt;
&lt;p&gt;Una charla de Steve Blank en la que explica cómo empezó realmente Silicon Valley.&lt;/p&gt;</description><link>http://marcpampols.com/post/21151543052</link><guid>http://marcpampols.com/post/21151543052</guid><pubDate>Sun, 15 Apr 2012 18:13:00 +0200</pubDate></item><item><title>The Business Model Canvas</title><description>&lt;a href="http://www.businessmodelgeneration.com/canvas"&gt;The Business Model Canvas&lt;/a&gt;: &lt;p&gt;Una herramienta en PDF y con licencia Creative Commons, que te permite describir y diseñar un modelo de negocio.&lt;/p&gt;
&lt;p&gt;&lt;img height="461" src="http://www.businessmodelgeneration.com/images/canvas_hero.png" width="550"/&gt;&lt;/p&gt;</description><link>http://marcpampols.com/post/20917398628</link><guid>http://marcpampols.com/post/20917398628</guid><pubDate>Wed, 11 Apr 2012 22:00:40 +0200</pubDate></item><item><title>El arte de destrozar objetos en 3D
El video es una demostración...</title><description>&lt;iframe width="400" height="300" src="http://www.youtube.com/embed/u_2qKQpxCRw?wmode=transparent&amp;autohide=1&amp;egm=0&amp;hd=1&amp;iv_load_policy=3&amp;modestbranding=1&amp;rel=0&amp;showinfo=0&amp;showsearch=0" frameborder="0" allowfullscreen&gt;&lt;/iframe&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;&lt;strong&gt;El arte de destrozar objetos en 3D&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;El video es una demostración técnica de RayFire, un plugin para 3dsMax (una de las más conocidas aplicaciones de modelado y animación 3D de Autodesk) para, simplemente, destrozar todo tipo de objetos 3D.&lt;/p&gt;</description><link>http://marcpampols.com/post/20844074398</link><guid>http://marcpampols.com/post/20844074398</guid><pubDate>Tue, 10 Apr 2012 17:18:30 +0200</pubDate></item><item><title>¿Cuál es la aplicación número 1 en descargas gratuitas de...</title><description>&lt;img src="http://25.media.tumblr.com/tumblr_m1rrgzJ4yO1r84ls9o1_500.jpg"/&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;¿Cuál es la aplicación número 1 en descargas gratuitas de la AppWorld de BlackBerry?&lt;/p&gt;
&lt;p&gt;La biblia.&lt;/p&gt;</description><link>http://marcpampols.com/post/20248169756</link><guid>http://marcpampols.com/post/20248169756</guid><pubDate>Sat, 31 Mar 2012 23:53:22 +0200</pubDate></item><item><title>Subscripción de usuarios a objetos Plone con envío de notificaciones.</title><description>&lt;p&gt;He añadido un Gist público en Github con 3 funciones que pueden ser útiles si estás creando un sistema de suscripción a objetos de Plone, con envío de notificaciones por correo y opción de darse de baja a través de un enlace con un hash personalizado.&lt;/p&gt;
&lt;p&gt;La idea es crear un tipo de contenido de Plone con un campo para guardar los suscriptores. Primero, una función add_subscriber() para añadirlos, que puede ser llamada desde cualquier acción en la web. Luego está la función sendEmail() que envía la notificación de, por ejemplo, actualización, a todos los suscriptores del objeto.&lt;/p&gt;
&lt;p&gt;El correo enviado contiene un enlace con el objeto al que el usuario se ha suscrito, y un string secreto que nos permite comprobar que sólo el receptor del correo podrá darse de baja.&lt;/p&gt;
&lt;p&gt;La función do_unsubscribe nos sirve para comprobar dicho string cuando el usuario hace click en el enlace, y darle de baja eliminando su cuenta de correo de dicho objeto Plone.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Add / Remove Plone object subscribers and send a notification email on state change:&lt;/em&gt;&lt;br/&gt;&lt;a href="https://gist.github.com/2265553"&gt;&lt;a href="https://gist.github.com/2265553"&gt;https://gist.github.com/2265553&lt;/a&gt;&lt;/a&gt;&lt;/p&gt;</description><link>http://marcpampols.com/post/20226818731</link><guid>http://marcpampols.com/post/20226818731</guid><pubDate>Sat, 31 Mar 2012 17:14:06 +0200</pubDate><category>plone</category><category>python</category></item><item><title>Importar datos CSV en Plone</title><description>&lt;p&gt;He subido un pequeño script en Python en el Github Gist, que pertenece a una vista de un producto de Plone, y que puede utilizarse como base para importar datos de un fichero CSV en tipos de contenido.&lt;/p&gt;
&lt;p&gt;Muy sencillo para tener una idea de cómo hacerlo, y fácilmente adaptable a la necesidad de cada uno.&lt;/p&gt;
&lt;p&gt;Import CSV data to Plone content type: &lt;a href="https://gist.github.com/2256740"&gt;&lt;a href="https://gist.github.com/2256740"&gt;https://gist.github.com/2256740&lt;/a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;pre&gt;# -*- coding: utf-8 -*-
import datetime
import urllib

from Acquisition import aq_inner

from zope import interface
from zope import schema

from zope.app.pagetemplate import viewpagetemplatefile
from zope.app.component.hooks import getSite

from Products.CMFCore.utils import getToolByName
from Products.Five import BrowserView
from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile

from Products.statusmessages.interfaces import IStatusMessage

# Control BadRequest errors (duplicate id's found)
try: from zExceptions import BadRequest
except ImportError: BadRequest = 'BadRequest'

# Control errors caused by WebDAV open objects in Plone durint import
from Products.CMFDefault.exceptions import ResourceLockedError

import StringIO
import csv

class Import(BrowserView):

    # Template where we show the import results
    template = viewpagetemplatefile.ViewPageTemplateFile('import.pt')

    # Import function
    def render(self):
        plone_utils = getToolByName(self.context, 'plone_utils')
        workflowTool = getToolByName(self.context, "portal_workflow")

        # Read the CSV file
        csv_contents = str(self.context)
        f = StringIO.StringIO(csv_contents)
        file = f.read()
        csv_reader = csv.reader(file.splitlines(), delimiter=';')

        # Counting successful and failed register imports
        stats_ok = 0
        stats_failed = 0

        # Set the name of the content type to create
        content_type = "Name of the Content Type"

        headers = 0
        for field in csv_reader:
            if (headers == 1):
               
                # Set the csv values to new python variables and do the proper processing for each register
                obj_id          = plone_utils.normalizeString(unicode(field[0]))
                obj_title       = str(field[1])
                obj_descripcion = str(field[2])
                
                # Try to create the object in Plone
                try:
                    subfolder_item[1].invokeFactory(content_type, obj_id)
                    obj_newObject = getattr(self, obj_id)
                    obj_newObject.setTitle(obj_title)
                    obj_newObject.setDescription(obj_description)
                    obj_newObject.reindexObject()
                    stats_ok += 1

                    except BadRequest:
                        print "Can't create object."
                        stats_failed += 1

                    except ResourceLockedError:
                        print "Can't create object, locked entry by WebDAV."
                        stats_failed += 1

            if (headers == 0):
                headers = 1

        return str("Import process results: CREATED: " + str(stats_ok) + " FAILED: " + str(stats_failed))

    def __call__(self):
        return self.render()
&lt;/pre&gt;</description><link>http://marcpampols.com/post/20191828115</link><guid>http://marcpampols.com/post/20191828115</guid><pubDate>Sat, 31 Mar 2012 00:52:59 +0200</pubDate><category>plone</category></item><item><title>Tuenti Programming Challenge 2</title><description>&lt;a href="https://contest.tuenti.net/"&gt;Tuenti Programming Challenge 2&lt;/a&gt;: &lt;p&gt;Competición anual de programación de Tuenti. En mi opinión mucho más divertida que la ‘Facebook HackerCup’. Tienes 20 problemas por resolver y una semana de tiempo, y los mejores 15 podrán visitar las oficinas de Tuenti en Madrid.&lt;/p&gt;</description><link>http://marcpampols.com/post/20191489770</link><guid>http://marcpampols.com/post/20191489770</guid><pubDate>Sat, 31 Mar 2012 00:46:47 +0200</pubDate><category>programación</category><category>competición</category></item><item><title>Adapta los gráficos de tu web para las pantallas con Retina Display</title><description>&lt;p&gt;En la salida del iPhone 4, Apple presentó su nueva tecnología Retina Display, en la que simplemente aumenta la densidad de píxeles en las pantallas y así se logra una calidad de imagen que en comparación a las anteriores, es bastante notable.&lt;/p&gt;
&lt;p&gt;Hasta ahora, estabamos acostumbrados a diseñar con 72 dpi, pero la pantalla Retina puede mostrar 326 dpi en el caso del iPhone 4 / 4S, y 264&amp;#160;en el nuevo iPad.&lt;/p&gt;
&lt;p&gt;Para aprovechar la nueva pantalla, podemos diseñar nuestras aplicaciones web con imágenes a dichas densidades, pero conservando también las de 72 dpi.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1. Detectar el pixel ratio&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;El primer paso es lograr detectar el pixel ratio del dispositivo visitante, un dato que podemos leer utilizando las &lt;a href="http://www.w3.org/TR/css3-mediaqueries/" target="_blank"&gt;Media Queries de CSS3&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Entonces, podemos crear un nuevo fichero CSS para utilizar exclusivamente en este caso, por ejemplo: retina-display.css, y para poder cargarlo, podemos utilizar la siguiente Media Query:&lt;/p&gt;
&lt;pre&gt;&amp;lt;link rel='stylesheet' href='retina-display.css' &lt;br/&gt;      media='only screen and (-moz-min-device-pixel-ratio: 2), &lt;br/&gt;             only screen and (-o-min-device-pixel-ratio: 2/1), &lt;br/&gt;             only screen and (-webkit-min-device-pixel-ratio: 2), &lt;br/&gt;             only screen and (min-device-pixel-ratio: 2)' /&amp;gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;&lt;br/&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2&lt;/strong&gt;&lt;strong&gt;. Adaptar las imágenes&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;En las &lt;em&gt;naming conventions&lt;/em&gt; del SDK de Apple, se sugiere que los ficheros para la Retina Display, tengan el sufijo &amp;#8220;@2x&amp;#8221;. Si nuestra imagen original se llama &amp;#8220;logo-site.png&amp;#8221;, la versión Retina se puede llamar &amp;#8220;logo-site@2x.png&amp;#8221;&lt;/p&gt;
&lt;p&gt;En cuestión de tamaño, si la imagen tiene una resolución de 50x50 pixeles, la versión Retina deberá tener 100x100.&lt;/p&gt;
&lt;p&gt;&lt;br/&gt;&lt;strong&gt;3. Añadir las nuevas imágenes en nuestra hoja de estilos.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Si antes hemos creado el fichero retina-display.css, ahora podemos indicar en el fichero las nuevas imágenes adaptadas. Siguiendo el ejemplo anterior:&lt;/p&gt;
&lt;pre&gt;#home #header .logo 
{
    background-image:url(assets/img/images/logo-site@2x.png);&lt;br/&gt;    background-size: 50px 50px;&lt;br/&gt;}&lt;/pre&gt;
&lt;p&gt;Necesitamos añadir la propiedad background-size para volver a adaptar el tamaño de las imágenes.&lt;/p&gt;</description><link>http://marcpampols.com/post/19912647535</link><guid>http://marcpampols.com/post/19912647535</guid><pubDate>Sun, 25 Mar 2012 22:39:19 +0200</pubDate><category>retina display</category><category>media query</category><category>css3</category></item><item><title>Primeros dias con la BlackBerry Playbook que nos regaló RIM....</title><description>&lt;img src="http://25.media.tumblr.com/tumblr_m0ou40i4JS1r84ls9o1_500.png"/&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;Primeros dias con la BlackBerry Playbook que nos regaló RIM. Decepcionado con la batería, tras cargarla al 100%, pasadas menos de 48 horas, ya ha bajado un 10%… ¡Sin usarla!&lt;/p&gt;</description><link>http://marcpampols.com/post/19077687697</link><guid>http://marcpampols.com/post/19077687697</guid><pubDate>Sat, 10 Mar 2012 22:24:00 +0100</pubDate></item><item><title>El 'Lorem Ipsum' de las imágenes</title><description>&lt;a href="http://lorempixel.com/"&gt;El 'Lorem Ipsum' de las imágenes&lt;/a&gt;: &lt;p&gt;Ideal para crear rápidamente imágenes de tamaños personalizados para poner a prueba tus proyectos.&lt;/p&gt;</description><link>http://marcpampols.com/post/19053583266</link><guid>http://marcpampols.com/post/19053583266</guid><pubDate>Sat, 10 Mar 2012 13:30:01 +0100</pubDate><category>lorem ipsum</category><category>imagenes</category></item><item><title>10 conceptos de desarrollo web que los diseñadores deben saber.</title><description>&lt;a href="http://www.netmagazine.com/features/10-web-development-concepts-designers-should-know"&gt;10 conceptos de desarrollo web que los diseñadores deben saber.&lt;/a&gt;: &lt;p&gt;Un artículo con un listado de 10 conceptos que deben tener claros todos aquellos que estén involucrados en el desarrollo de un diseño que debe terminar en una web.&lt;/p&gt;
&lt;p&gt;Uno de los principales problemas con los que me encuentro en el desarrollo web cuando tengo que trabajar con empresas externas, es que muchas desconocen la diferencia entre “Diseño gráfico” y “Diseño web”, y cometen el error de encargar diseños web a diseñadores gráficos que no tienen ningún conocimiento de HTML, CSS o JavaScript. &lt;strong&gt;Horrible.&lt;/strong&gt;&lt;/p&gt;</description><link>http://marcpampols.com/post/19022096855</link><guid>http://marcpampols.com/post/19022096855</guid><pubDate>Fri, 09 Mar 2012 23:48:28 +0100</pubDate><category>diseño web</category><category>conceptos</category><category>desarrollo web</category></item><item><title>Protocolo para entrar en una "sala blanca" de Intel</title><description>&lt;a href="http://www.intel.com/espanol/technology/manufacturing/cleanroom.htm"&gt;Protocolo para entrar en una "sala blanca" de Intel&lt;/a&gt;: &lt;p&gt;&lt;ol&gt;&lt;li&gt;Guardar los objetos personales.&lt;/li&gt;
&lt;li&gt;Desechar chicles, caramelos, etc.&lt;/li&gt;
&lt;li&gt;Quitarse el maquillaje con agua y jabón estériles.&lt;/li&gt;
&lt;li&gt;Tomar un sorbo de agua para eliminar las partículas de la boca.&lt;/li&gt;
&lt;li&gt;…..&lt;/li&gt;
&lt;/ol&gt;&lt;ol start="41"&gt;&lt;li&gt;Examinar el equipo en el espejo.&lt;/li&gt;
&lt;li&gt;Ponerse los guantes de látex.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Entrar en la sala blanca.&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;/p&gt;</description><link>http://marcpampols.com/post/17333769787</link><guid>http://marcpampols.com/post/17333769787</guid><pubDate>Thu, 09 Feb 2012 22:32:14 +0100</pubDate></item><item><title>Validador de titulos duplicados para Plone 4.x</title><description>&lt;a href="https://gist.github.com/1724336"&gt;Validador de titulos duplicados para Plone 4.x&lt;/a&gt;: &lt;p&gt;Un validador para Plone 4.x que permite avisar al usuario si ha introducido un elemento con un titulo duplicado. El funcionamiento por defecto del gestor es crear igualmente un elemento modificando el valor del id añadiendo un número, y así podemos tener elementos que comparten el campo &lt;em&gt;Title.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Con este validador, que se puede añadir a cualquier tipo de contenido, podemos avisar al usuario y evitar que entre contenidos duplicados.&lt;/p&gt;</description><link>http://marcpampols.com/post/16931637851</link><guid>http://marcpampols.com/post/16931637851</guid><pubDate>Thu, 02 Feb 2012 21:04:35 +0100</pubDate><category>plone</category><category>validator</category><category>archetypes</category><category>content types</category></item><item><title>Notificaciones Push desde la NAS de Synology</title><description>&lt;p&gt;Hace tiempo que compré una NAS de Synology, y hoy, con la nueva versión 4.0 beta del firmware, activé las notificaciones Push.&lt;/p&gt;
&lt;p&gt;Primero hay que instalar &lt;a href="http://itunes.apple.com/us/app/ds-finder/id429865523?mt=8" title="Synology DS finder" target="_blank"&gt;DS finder&lt;/a&gt; para &amp;#8220;sincronizar&amp;#8221; vuestro terminal con vuestra(s) NAS, y luego activar el envío de notificaciones. Lo que es realmente genial es que aprovecha todas las notificaciones que por defecto incluye el firmware de Synology (aviso por problemas de hardware, reboot remoto, backups finalizados, etc&amp;#8230;), así que puedes estar informado al instante de todo lo que sucede con tu NAS.&lt;/p&gt;
&lt;p&gt;La versión 4.0 beta puede descargarse desde &lt;a href="http://www.synology.com/dsm/dsm4.0_beta.php?lang=enu" title="DSM 4.0 beta" target="_blank"&gt;la página oficial de Synology&lt;/a&gt;, y el proceso de actualización apenas tarda unos 15 minutos y mantiene toda la configuración actual.&lt;/p&gt;
&lt;p&gt;&lt;img src="http://media.tumblr.com/tumblr_lyblyxnxV01r43hac.png"/&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="http://media.tumblr.com/tumblr_lyblztSLKZ1r43hac.png" width="250"/&gt;&lt;/p&gt;
&lt;p&gt;Gracias a &lt;a href="http://www.twitter.com/jordipg" title="Twitter de Jordi Pasqual" target="_blank"&gt;@jordipg&lt;/a&gt; por el aviso!&lt;/p&gt;</description><link>http://marcpampols.com/post/16421898976</link><guid>http://marcpampols.com/post/16421898976</guid><pubDate>Tue, 24 Jan 2012 21:54:27 +0100</pubDate><category>synology</category><category>nas</category><category>iphone</category><category>notificaciones</category><category>4.0 beta</category></item><item><title>Primera ronda de calificación de la Facebook Hacker Cup 2012</title><description>&lt;p&gt;Ayer terminó la primera ronda de calificación de la competición &amp;#8220;Hacker Cup&amp;#8221; de Facebook.&lt;/p&gt;
&lt;p&gt;Por suerte, todos los amigos que participamos pudimos pasar la ronda :)&lt;/p&gt;
&lt;p&gt;De los tres problemas planteados solucionamos uno o dos, el tercero era de una dificultad bastante más elevada y no llegamos a tiempo.&lt;/p&gt;
&lt;p&gt;He publicado en github:gist el código fuente de mis soluciones escritas en Python.&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;Alphabet Soup&lt;br/&gt;&lt;a href="https://gist.github.com/1670780"&gt;&lt;a href="https://gist.github.com/1670780"&gt;https://gist.github.com/1670780&lt;/a&gt;&lt;br/&gt; &lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Billboards&lt;br/&gt;&lt;a href="https://gist.github.com/1670910"&gt;&lt;a href="https://gist.github.com/1670910"&gt;https://gist.github.com/1670910&lt;/a&gt;&lt;/a&gt;  &lt;/li&gt;
&lt;/ul&gt;</description><link>http://marcpampols.com/post/16420074431</link><guid>http://marcpampols.com/post/16420074431</guid><pubDate>Tue, 24 Jan 2012 21:19:09 +0100</pubDate><category>facebook</category><category>hacker cup</category><category>solución</category><category>código</category><category>python</category></item></channel></rss>

