<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>FORCÉN</title>
	<atom:link href="http://www.forcen.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.forcen.com</link>
	<description>a.k.a. el turista accidental</description>
	<lastBuildDate>Fri, 21 Oct 2011 10:20:43 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Solo en España</title>
		<link>http://www.forcen.com/2011/10/solo-en-espana/</link>
		<comments>http://www.forcen.com/2011/10/solo-en-espana/#comments</comments>
		<pubDate>Fri, 21 Oct 2011 10:20:43 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.forcen.com/?p=186</guid>
		<description><![CDATA[Conversación mantenida hace 10 minutos con alguien que acaba de reunirse con un cliente. El proyecto, a grandes rasgos, consiste en que desde el cliente, y una vez detalladas las necesidades de un proyecto (tantos folletos, tantos filostros, tantos poyaques), se soliciten presupuestos a una serie de proveedores. Estos proveedores, a través de Internet, acceden [...]]]></description>
			<content:encoded><![CDATA[<p>Conversación mantenida hace 10 minutos con alguien que acaba de reunirse con un cliente. El proyecto, a grandes rasgos, consiste en que desde el cliente, y una vez detalladas las necesidades de un proyecto (tantos folletos, tantos filostros, tantos poyaques), se soliciten presupuestos a una serie de proveedores.</p>
<p>Estos proveedores, a través de Internet, acceden al detalle del proyecto y rellenan los precios para cada uno de los elementos del mismo: 2.000 poyaques a 15 lerus/unidad, 1.500 filostros a 200 lerus/cuartoymitá, etc.</p>
<p>El gerente del cliente ha decidido que no. Que eso es complicarle la vida a los proveedores y que mejor seguir con el tradicional sistema de coger el teléfono y llamar a los susodichos. Como única mejora, admite que se puedan mandar emails pidiendo los presupuestos.</p>
<p>Este es el tipo de &#8220;mejoras&#8221; que sólo se toman en España.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.forcen.com/2011/10/solo-en-espana/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Trabajo de campo con iOS</title>
		<link>http://www.forcen.com/2011/08/trabajo-de-campo-con-ios/</link>
		<comments>http://www.forcen.com/2011/08/trabajo-de-campo-con-ios/#comments</comments>
		<pubDate>Thu, 04 Aug 2011 23:55:05 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[iPhone]]></category>

		<guid isPermaLink="false">http://www.forcen.com/?p=178</guid>
		<description><![CDATA[Cómo ser tecnológicamente correctos en medio de la nada. Publicado en faq-mac.com.]]></description>
			<content:encoded><![CDATA[<p>Cómo ser tecnológicamente correctos en medio de la nada.</p>
<p>Publicado en<a href="http://www.faq-mac.com/43826/realizar-trabajos-campo-dispositivos-usan-ios-faustino-forcen"> faq-mac.com</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.forcen.com/2011/08/trabajo-de-campo-con-ios/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Linkify tweets with Unicode characters.</title>
		<link>http://www.forcen.com/2011/07/linkify_tweets_with_unicode_characters/</link>
		<comments>http://www.forcen.com/2011/07/linkify_tweets_with_unicode_characters/#comments</comments>
		<pubDate>Mon, 25 Jul 2011 12:16:18 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Twitter]]></category>

		<guid isPermaLink="false">http://www.forcen.com/?p=163</guid>
		<description><![CDATA[A short entry describing a tested function for linkifying twits. If you&#8217;re following non-us twetters you&#8217;ll sometimes find that they write hashtags &#8220;properly&#8221;, using diacritical characters. Twitter handle those hashtags properly, so #telefónica will be understood as #telefonica. But if you&#8217;re writing your own application you&#8217;ll need to handle those characters by yourself. Twitter send [...]]]></description>
			<content:encoded><![CDATA[<p>A short entry describing a tested function for linkifying twits. If you&#8217;re following non-us twetters you&#8217;ll sometimes find that they write hashtags &#8220;properly&#8221;, using diacritical characters. Twitter handle those hashtags properly, so #telefónica will be understood as #telefonica.</p>
<p>But if you&#8217;re writing your own application you&#8217;ll need to handle those characters by yourself. Twitter send them encoded as Unicode, so it&#8217;s easy to process them using PCRE&#8230; if your installation of PCRE is compiled with full Unicode support.</p>
<p><span id="more-163"></span></p>
<p>So, the first step is to check your configuration. This snippet will tell you if PCRE supports Unicode.</p>
<blockquote>
<pre class="brush: php; gutter: true">if (@preg_match('/\pL/u', 'a') == 1) {
    echo "PCRE unicode support is turned on.";
} else {
    echo "PCRE unicode support is turned off.";
}</pre>
</blockquote>
<p>The solution varies from distro to distro. <a href="http://chrisjean.com/2009/01/31/unicode-support-on-centos-52-with-php-and-pcre/">Here you&#8217;ll find the way to get Unicode support on Centos</a>.</p>
<p>And now for a simple function to linkify the tweets.</p>
<blockquote>
<pre class="brush: php; gutter: true">/**

    * Linkify function with support for utf-8 characters.
    *
    * @param $text is the raw text of the tweet
    * @return the same tweet with links, users and hashtags linkified
    *
    */

function procesaTwit($text) {
    return preg_replace(array(
            '@(https?://([-\w\.]+)+(/([\w/_\.\-]*(\?\S+)?(#\S+)?)?)?)@',
            '/@(\w+)/',
            '/#([\d\w\pL]+)/',
        ),

        array( '&lt;a href="$1" target="_blank"&gt;$1&lt;/a&gt;',
                '&lt;a href="http://twitter.com/$1"&gt;@$1&lt;/a&gt;'
                '&lt;a href="http://twitter.com/#!/search?q=%23$1"&gt;#$1&lt;/a&gt;'
        ),

        $text);
}</pre>
</blockquote>
<p>That&#8217;s all you need to properly linkify tweets with Unicode characters.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.forcen.com/2011/07/linkify_tweets_with_unicode_characters/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>El tamaño (en Twitter) si importa</title>
		<link>http://www.forcen.com/2011/07/el-tamano-en-twitter-si-importa/</link>
		<comments>http://www.forcen.com/2011/07/el-tamano-en-twitter-si-importa/#comments</comments>
		<pubDate>Tue, 19 Jul 2011 12:26:50 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Cancamusa]]></category>
		<category><![CDATA[Twitter]]></category>

		<guid isPermaLink="false">http://www.forcen.com/?p=159</guid>
		<description><![CDATA[Los que saben del tema (y cobran por decir que saben) insisten en que, en tema followers, lo que importa es la calidad y no la cantidad. Realmente piensan que si conisuges que un famoso te siga va a leer lo que escribes, no digamos ya reemitir tu mensaje. El problema es que, generalmente, esta [...]]]></description>
			<content:encoded><![CDATA[<p>Los que saben del tema (y cobran por decir que saben) insisten en que, en tema followers, lo que importa es la calidad y no la cantidad. Realmente piensan que si conisuges que un famoso te siga va a leer lo que escribes, no digamos ya reemitir tu mensaje.</p>
<p>El problema es que, generalmente, esta gente no sabe de lo que habla o sólo sabe lo que ha escuchado de otros que cobran por decir que saben. El mundo de la cancamusa tiende a retroalimentarse. Es una Sociedad de Elogios Mutuos donde nadie va a confesar que no tiene ninguna solución (aunque las venda).</p>
<p><span id="more-159"></span>Mi amigo <a href="http://twitter.com/#!/juan_diaz_diaz">Juán Díaz Díaz</a> (que no cobra por decir que sabe, <a href="http://tweet.grader.com/juan_diaz_diaz">si no que sabe</a>) lleva meses en su particular #twitterquest, cubriendo eventos, añadiendo followers y examinando métricas y resultados de los distintos experimentos que va realizando con herramientas tanto públicas como home-made. Actualmente tiene 42k followers. Los que cobran por decir que saben niegan que eso sea útil.</p>
<p>Aunque las coberturas que realiza de cada evento, comentando o simplemente retransmitiendo lo que dicen los ponentes, lleguen a más de un millón de impresiones (p. ej., 2.4M con 70 twits sobre el CongresoSMM). O que esté en el puesto número 7 de la <a href="http://tweet.grader.com/index.php?Action=TwitterUsersByLocation&amp;City=BARCELONA&amp;State=56&amp;Country=ES">élite twittera en Catalunya</a> o el <a href="http://tweet.grader.com/index.php?Action=TwitterUsersByLocation&amp;Country=ES">23 a nivel nacional</a>. Resultados que esos mismos que cobran por decir que saben ni siquiera sueñan con tener, ni para sus clientes ni, mucho menos, para ellos mismos.</p>
<p>El problema es que no entienden que las reglas han cambiado. No se trata de que alguien vea a un famoso recomendando un producto o un servicio. Como dice Juan,<em> la audiencia es importante porque tu NO sabes quien es un prospecto. y si lo sabes ya vas a por el.</em></p>
<p>Y claro que parte de esos 42k followers, o de los millones que puede llegar a leer los mensajes reenviados por esos usuarios, incluyen ruido y bots, pero <em>si no contactas con la masa no tienes factor de amplificacion</em>. Nunca sabes cuándo una parte de la masa se va a interesar por tu mensaje <em>y para tener efecto amplificado tienes que tener mucho donde ir cebando</em>.</p>
<p>Mientras tanto los que cobran por decir que saben siguen diciendo que el tamaño no importa.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.forcen.com/2011/07/el-tamano-en-twitter-si-importa/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Índices colaborativos</title>
		<link>http://www.forcen.com/2011/05/indices-colaborativos/</link>
		<comments>http://www.forcen.com/2011/05/indices-colaborativos/#comments</comments>
		<pubDate>Sun, 15 May 2011 16:51:31 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[ebooks]]></category>

		<guid isPermaLink="false">http://www.forcen.com/?p=156</guid>
		<description><![CDATA[¿Tiene sentido un índice en un ebook? Acotando el tema a los libros técnicos o de referencia puede tenerlo. Veamos por qué. Cuando buscamos algo en un libro de referencia físico vamos al índice donde encontramos las palabras o conceptos que el autor piensa que son importantes en el ámbito de aplicación del libro, agrupándolas [...]]]></description>
			<content:encoded><![CDATA[<p>¿Tiene sentido un índice en un ebook? Acotando el tema a los libros técnicos o de referencia puede tenerlo. Veamos por qué.</p>
<p>Cuando buscamos algo en un libro de referencia físico vamos al índice donde encontramos las palabras o conceptos que el autor piensa que son importantes en el ámbito de aplicación del libro, agrupándolas en ocasiones. Por ejemplo, en un libro de JavaScript:</p>
<blockquote><p>object constants, 109, 110<br />
Object constructor<br />
creating objects, 41<br />
factory pattern and, 148<br />
toString() method, 48<br />
usage considerations, 41, 42</p></blockquote>
<p>Es decir, el autor o el editor han recogido los términos que consideran más relevantes. Un trabajo complicado y espeso.</p>
<p><span id="more-156"></span></p>
<p>Se supone que en un ebook no es preciso utilizar esos índices, porque tenemos un buscador. Pero&#8230; esa herramienta busca por palabras, no por conceptos. En la página 41 del libro citado más arriba no aparace &#8220;usage considerations&#8221;, pero cuando revisamos el índice para saber más sobre el constructor de un objeto nos viene bien saber que en esas dos páginas se hacen algunas consideraciones sobre el uso del mismo. En resumen, ese índice que nos parece innecesario porque tenemos buscador si que tiene utilidad.</p>
<p>Pero nuevamente, crear ese índice es un proceso largo y tedioso. Que tiene otra desventaja. Refleja lo que el autor, que es el que sabe del tema, considera importante sobre la materia tratada en el libro. Lo suficiente como para merecer una entrada en el índice. Pero un lector puede encontrar que en ese mismo libro hay un dato interesante que no aparece reflejado en el índice por la razón que sea.</p>
<p>Si el lector acude a menudo al libro en cuestión (como hacemos muchos con muchos libros) le viene bien poder acceder rápidamente al punto o puntos en cuestión. En los ebooks actuales se recurre a marcar dichos puntos y anotar. Imagino que, incluso permitirán buscar por las anotaciones de los puntos de lectura insertados (estoy hablando ahora sólo en plan teórico, no pienso levantarme a coger el Kindle).</p>
<p>Pero&#8230; ¿no sería más útil que el lector pudiese ir creando o ampliando el índice del libro utilizando las búsquedas que ha realizado como base? Por supuesto que no todas las búsquedas que se hacen en un libro electrónico son válidas o relevantes. Como tampoco lo son todas las búsquedas que hacemos en el índice de un libro en papel. Se puede añadir un botón al listado de resultado de una búsqueda donde &#8220;nombrar&#8221; dicha búsqueda y añadirla a nuestro índice.</p>
<p>Y, poniendonos 2.0, ¿qué nos impide añadir otro botón que envíe nuestra entrada del índice a un repositorio donde otros lectores del libro puedan aprovecharse de nuestra búsqueda?</p>
<p>&nbsp;</p>
<blockquote><p>&nbsp;</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://www.forcen.com/2011/05/indices-colaborativos/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>El abogado del diablo</title>
		<link>http://www.forcen.com/2011/05/el-abogado-del-diablo/</link>
		<comments>http://www.forcen.com/2011/05/el-abogado-del-diablo/#comments</comments>
		<pubDate>Fri, 13 May 2011 07:05:06 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.forcen.com/?p=153</guid>
		<description><![CDATA[Hay dos formas de verlo: o eres muy negativo o eres el que piensa en todos los posibles problemas de cualquier situación/feature/email. Y se aplica a todos los ámbitos, técnicos o no. El problema viene cuando te toca lidiar con dos tipos de personajes: el que piensa que lo que está empeñado en hacer/implementar/arreglar es [...]]]></description>
			<content:encoded><![CDATA[<p>Hay dos formas de verlo: o eres muy negativo o eres el que piensa en todos los posibles problemas de cualquier situación/feature/email.</p>
<p>Y se aplica a todos los ámbitos, técnicos o no. El problema viene cuando te toca lidiar con dos tipos de personajes: el que piensa que lo que está empeñado en hacer/implementar/arreglar es una buena idea y el buenrollista profesional, también conocido como &#8220;a quién se le va ocurrir lanzar un ataque contra nuestra web, si somos guenos&#8221;?</p>
<p>En otros universos paralelos es costumbre escuchar a alguien con una cierta experiencia y entender que no dice las cosas por aburrimiento. En apaña lo normal es que los que acaban de salir de un curso rápido de naderías hagan lo contrario de lo que se les ordena o se salten todos los mecanismos/protocolos/devolucionesdefunción de seguridad &#8220;porque es aburrido y así es más rápido&#8221;. O directamente pregunten &#8220;por qué hay que comprobar que el cliente está conectado a la base de datos si ya he llamado a la función de conexión?&#8221;.</p>
<p>Así que con el tiempo eres el borde negativo que no se alegra cuando alguien envía un email a una startup diciendo &#8220;estupendo lo que habeis creado. me gusta mucho. ¿cuándo puede mi técnico hablar con el vuestro para que lo cambieis para que haga lo que a mí me interesa?&#8221;.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.forcen.com/2011/05/el-abogado-del-diablo/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Desfiltrando el router</title>
		<link>http://www.forcen.com/2011/03/desfiltrando-el-router/</link>
		<comments>http://www.forcen.com/2011/03/desfiltrando-el-router/#comments</comments>
		<pubDate>Wed, 23 Mar 2011 11:14:10 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.forcen.com/?p=139</guid>
		<description><![CDATA[Un rápido aviso para los que sufren un router Zyxel 660 de Telefónica. Hace unos días, después de que se muriese el anterior, me colocaron uno del mismo modelo. Proceso habitual: ocultar la red, añadir las MACs de los ordenadores y abrir los puertos necesarios. Hasta ahí todo bien. Pero el servidor web no se [...]]]></description>
			<content:encoded><![CDATA[<p>Un rápido aviso para los que sufren un router Zyxel 660 de Telefónica. Hace unos días, después de que se muriese el anterior, me colocaron uno del mismo modelo. Proceso habitual: ocultar la red, añadir las MACs de los ordenadores y abrir los puertos necesarios. Hasta ahí todo bien. Pero el servidor web no se veía desde fuera de la red. Recomprobación de puertos, reiniciado de router, reiniciado de servidor, reiniciado de camiseta, invocación a los Antiguos&#8230; Ni una pista.</p>
<p>El problema son los filtros que se han añadido al router. Que se desactivan fácilmente, cuando se sabe que existe.</p>
<p><span id="more-139"></span></p>
<p>Sólo hay que acceder a la dirección del router (típicamente 192.168.1.1) pot telnet.</p>
<p>&nbsp;</p>
<div id="attachment_143" class="wp-caption aligncenter" style="width: 519px"><a href="http://www.forcen.com/wp-content/uploads/Captura-de-pantalla-2011-03-23-a-las-12.02.18.png"><img class="size-full wp-image-143" title="Pantalla principal del router" src="http://www.forcen.com/wp-content/uploads/Captura-de-pantalla-2011-03-23-a-las-12.02.18.png" alt="" width="509" height="313" /></a><p class="wp-caption-text">La opción de los filtros es la 21</p></div>
<p>&nbsp;</p>
<div id="attachment_141" class="wp-caption aligncenter" style="width: 520px"><a href="http://www.forcen.com/wp-content/uploads/Captura-de-pantalla-2011-03-23-a-las-12.03.39.png"><img class="size-full wp-image-141" title="Filtros" src="http://www.forcen.com/wp-content/uploads/Captura-de-pantalla-2011-03-23-a-las-12.03.39.png" alt="" width="510" height="344" /></a><p class="wp-caption-text">Los filtros pueden variar en tu configuración. En el router anterior no existian ni el 11 ni el 12</p></div>
<p>&nbsp;</p>
<div id="attachment_142" class="wp-caption aligncenter" style="width: 519px"><a href="http://www.forcen.com/wp-content/uploads/Captura-de-pantalla-2011-03-23-a-las-12.03.20.png"><img class="size-full wp-image-142" title="webset2" src="http://www.forcen.com/wp-content/uploads/Captura-de-pantalla-2011-03-23-a-las-12.03.20.png" alt="" width="509" height="342" /></a><p class="wp-caption-text">El filtro WebSet2 es el &quot;culpable&quot;.</p></div>
<p>&nbsp;</p>
<p>&nbsp;</p>
<div id="attachment_140" class="wp-caption aligncenter" style="width: 520px"><a href="http://www.forcen.com/wp-content/uploads/Captura-de-pantalla-2011-03-23-a-las-12.04.42.png"><img class="size-full wp-image-140" title="Filtro" src="http://www.forcen.com/wp-content/uploads/Captura-de-pantalla-2011-03-23-a-las-12.04.42.png" alt="" width="510" height="343" /></a><p class="wp-caption-text">En Active cambia el valor a No.</p></div>
<p>&nbsp;</p>
<p>Un par de horas de dolor de cabeza resueltas en un minuto. Cuando se sabe dónde buscar.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.forcen.com/2011/03/desfiltrando-el-router/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Los que han de decidir</title>
		<link>http://www.forcen.com/2011/03/los-que-han-de-decidir/</link>
		<comments>http://www.forcen.com/2011/03/los-que-han-de-decidir/#comments</comments>
		<pubDate>Wed, 23 Mar 2011 10:57:52 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Cancamusa]]></category>

		<guid isPermaLink="false">http://www.forcen.com/?p=61</guid>
		<description><![CDATA[Hace poco leí, en uno de esos momentos de relajada investigación (traducción: leyendo blogs al tuntún) una frase de un diseñador: &#8220;el problema es que los que tienen que decidir sobre el diseño de un producto no tienen ni idea del tema&#8221;. Realmente es una queja muy frecuente entre el gremio. Por ejemplo, esto mismo [...]]]></description>
			<content:encoded><![CDATA[<p>Hace poco leí, en uno de esos momentos de relajada investigación (traducción: leyendo blogs al tuntún) una frase de un diseñador: &#8220;el problema es que los que tienen que decidir sobre el diseño de un producto no tienen ni idea del tema&#8221;. Realmente es una queja muy frecuente entre el gremio. Por ejemplo, esto mismo lo dijo alguien que sufre a diario las <em>decisiones</em> de un departamento de <em>producto</em>. Donde <em>decisiones</em> tiende a <em>incoherencias</em> los días pares e <em>indecisiones</em> los pares.</p>
<p>Hace unos meses sufrí, indirectamente, a ese mismo departamento de <em>producto</em> en cierto ministerio de cuyo nombre prefiero no acordarme. Pongamos, para simplificar, que se llama <strong>Mordor</strong>: un edificio poblado por tribus de orcoficinistas cordialmente enfrentados (del <em>buenrollismo de funcionario</em> hablaremos otro día).</p>
<p><span id="more-61"></span>Hallábame, a la sazón, en el susodicho <strong>Mordor</strong> redimiendo condena y alicatando el baño de ejecutivos. El problema estaba en que los que debían decidir el tipo, tamaño y color de los azulejos no sólo no ocultaban su desconocimiento sobre lo más básico: si poner los azulejos pareados o al tresbolillo, porque no es buena idea alicatar con pladur&#8230; sino que no tenían muy claro quien era el experto-barra-responsable (en un ministerio siempre ha de haber un jefe o jefa de negociado que alivie el penoso trabajo de responsabilizarse de una decisión) que había de determinar la forma, color y sabor de los susodichos azulejos.</p>
<p>Así se dieron casos surrealistas como el de la, en principio, sencilla pregunta sobre si los azulejos debían ser rojo chillón o amarillo fosforito que devino en ameno conciliábulo al que se fueron añadiendo el encargado de la masa, luego el aparejador, el constructor (que es de <em>producto</em>, pero parece que menos)&#8230; para determinar que eso sólo lo podía decidir otra individua del anteriormente citado negociado de <em>producto</em>. Momento memorable cuando el constructor dijo &#8220;eso está en el <em>briefing</em>, seguro&#8221;; después de descifrar el citado <em>briefing</em> (alias PowerPoint) el discurso cambió a &#8220;está en el <em>briefing</em> de los que están pintando los trasteros, seguro&#8221;. ¡Ah, la seguridad de los <em>expertos</em>!</p>
<p>Hubo, en ese mismo proyecto, otros momentos memorables, como el apasionado <em>speech</em> de esa persona a quien podemos únicamente identificar como <em>la grávida,</em> echando balones fuera (&#8220;pero al final esto lo tiene que decidir la jefa de negociado&#8221;) ante el sufriente diseñador del primer párrafo, alardeando de sus múltiples desconocimientos mientras ofendía a todos aquellos que tenían que sacar adelante sus indecisiones&#8230; O simplemente tirar adelante con un trabajo del que no había ni documentación ni definición ni perrito que le ladre.</p>
<p>Qué sería de las empresas sin estos divertidos departamentos que deciden sin saber, que encargan (y pagan sospechosamente bien) diseños que nunca se implementarán y que están, en definitiva, por encima de esos pequeños detalles como decidir de qué color tienen que encenderse los azulejos cuando el que entra en el baño de ejecutivos es el jefe de la Horda o el mismo Sauron.</p>
<p>Finalmente la condena fue redimida, el baño fue alicatado y hubo gran regocijo (por mi parte). Posteriormente corrieron rumores de que iban a levantar los azulejos para poner las cañerías. Que estaban en el briefing, seguro. Y se sigue sin saber si los azulejos deben ir en filas o al tresbolillo.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.forcen.com/2011/03/los-que-han-de-decidir/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Be kind, be multilingual</title>
		<link>http://www.forcen.com/2011/01/be-kind-be-multilingual/</link>
		<comments>http://www.forcen.com/2011/01/be-kind-be-multilingual/#comments</comments>
		<pubDate>Tue, 18 Jan 2011 12:22:44 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.forcen.com/?p=125</guid>
		<description><![CDATA[The problem: we want to have a page in several languages. Without having to create one html file for each page for each language. The solution can be divided in three parts: 1. how to know in which language we must show the page, 2. how to render the &#8220;structure&#8221; of the pages and 3. [...]]]></description>
			<content:encoded><![CDATA[<p>The problem: we want to have a page in several languages. Without having to create one html file for each page for each language.</p>
<p>The solution can be divided in three parts:</p>
<p>1. how to know in which language we must show the page,</p>
<p>2. how to render the &#8220;structure&#8221; of the pages and</p>
<p>3. how to get the content of the pages.</p>
<p>In this entry I&#8217;ll show how to code, in PHP, the fist part of the solution.</p>
<p><span id="more-125"></span>The code is simple. We want to change the language of the page at user&#8217;s request AND store the language settings in the client, so the next time our page is loaded it will automagically show the language selected by the user in his/her last visit.</p>
<pre escaped="true" lang="php" line="1">// tipically you define the root of your globals in a confif file
// it's define here for completeness...
define('VAR_ROOT', 'MY_PAGE_');

// the language by default
$strDefLanguage = 'es';

// an array of allowed values for strLan
// HINT: whenever possible check any user input with a list
// 		of 'legal' values.
$arrLanguages = array('en', 'es', 'fr', 'de', 'ca');

/**
  * this function returns the language for our application.
  *
  * @param an string that, optionally, contains the language to switch to.
  * @returns the language in use right now for our app
*/
function getLanguage($strLan = '') {

    if($strLan != '' &amp;&amp; in_array($strLan, $arrLanguages)) {
        $_SESSION[VAR_ROOT . 'LANG'] = $strLan;
        setcookie(VAR_ROOT . 'LANG', $strLan, time() + 60 * 60 * 24 * 30);
    }
    return (isset($_SESSION[VAR_ROOT . 'LANG']) ? $_SESSION[VAR_ROOT . 'LANG'] :
           (isset($_COOKIE[VAR_ROOT . 'LANG']) ? $_COOKIE[VAR_ROOT . 'LANG'] :
           $strDefLanguage));
}
</pre>
<p>Note that this function goes against the principle of simple responsability. Sometimes we sacrifice this kind of things for speed and functionality. It&#8217;s not bad. Neither good.</p>
<p>Anyway, you&#8217;ll call this function on each of your pages, before starting to render the structure or to read the data from the database.</p>
<pre escaped="true" lang="php" line="1">&lt;?php
// you MUST start a session for this to work.
session_start();

// your includes go here
require_once('someconfig.php');    // like this one...

// now you read the language
// we're setting the language to the lan parameter
// only if it exists.
// otherwise we just get the current language.
$strLang = getLanguage(isset($_GET['lan']) ? $_GET['lan'] : '');

// you can now read your literals file
// remember that strLang has a known, filtered, value
// so this is safe
require_once('lan' . $strLang . '.php');

// or instanciate your database class
$objNotes = new notesClass($strLang);
</pre>
<p>In next entries I&#8217;ll describe in more detail the other two parts.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.forcen.com/2011/01/be-kind-be-multilingual/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to mimic Twitter slides on Safari Mobile</title>
		<link>http://www.forcen.com/2011/01/how-to-mimick-twitter-slides-on-safari-mobile/</link>
		<comments>http://www.forcen.com/2011/01/how-to-mimick-twitter-slides-on-safari-mobile/#comments</comments>
		<pubDate>Thu, 13 Jan 2011 20:20:46 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Desarrollo]]></category>
		<category><![CDATA[iPhone]]></category>

		<guid isPermaLink="false">http://www.forcen.com/?p=69</guid>
		<description><![CDATA[Last night, during our local NSCoders meeting, one of my fellow coders asked me how to replicate some functionality using CSS. It turned out that the functionality required more JavaScript than CSS. In Twitter the user can slide a twit to show some controls that relate to that twit.  Jorge wanted to imitate this behaviour. [...]]]></description>
			<content:encoded><![CDATA[<p>Last night, during our local NSCoders meeting, one of my fellow coders asked me how to replicate some functionality using CSS. It turned out that the functionality required more JavaScript than CSS.</p>
<p>In Twitter the user can slide a twit to show some controls that relate to that twit.  Jorge wanted to imitate this behaviour. After a fast search I explained him how to &#8220;bind&#8221; some JavaScript to the <em>touchmove</em> and <em>touchend</em> events. This morning, remembering the <a href='http://092.me'>question</a> I tried to code some fast example implementing a similar functionality.</p>
<p><a href="http://www.forcen.com/wp-content/uploads/slider.png"><img class="aligncenter size-full wp-image-116" title="slider" src="http://www.forcen.com/wp-content/uploads/slider.png" alt="" width="500" height="185" /></a></p>
<p>Basically the user initiates an slide on an element of the list. When the element has been slided past a point it opens completely, revealing the controls beneath.</p>
<p><span id="more-69"></span></p>
<p>Thankfully I found <a href="http://css-tricks.com/slide-to-unlock/" target="_blank">here</a> an example on how to mimic the sliding using both touch events and CSS transforms. This sample, in turn, referred to <a href="http://www.evanblack.com/blog/touch-slide-to-unlock/" target="_blank">this other</a>. Based on their code I managed to get mine working in a couple of hours. You can point your iPhone to <a href="http://www.forcen.com/tests/slide/"><strong>http://www.forcen.com/tests/slide/</strong></a> to see it in action. For simplicity all of the css, javascript and html are on the same page. The only external dependency is jQuery.</p>
<h2>The markup</h2>
<p>The HTML for this example is simple:</p>
<p>Each item is contained into a div, that will be the element that is slided.</p>
<pre escaped="true" lang="html">&lt;ul id="items"&gt;
    &lt;li&gt;
        &lt;div id="2323232"&gt;
            &lt;strong&gt;first entry&lt;/strong&gt;&lt;br /&gt;An example
        &lt;/div&gt;
    &lt;/li&gt;
    &lt;li&gt;
        &lt;div id="2454532"&gt;
            &lt;strong&gt;second entry&lt;/strong&gt;&lt;br /&gt;of how to imitate
        &lt;/div&gt;
    &lt;/li&gt;
&lt;/ul&gt;</pre>
<p>I only have a control bar that will be moved into place when the user starts a move over an entry. The holder is for keeping the  control bar hidden:</p>
<pre escaped="true" lang="html">
<div id="controlsHolder">
<ul id="controls">
<li><img id="boton1" src="_imgs/b1.png" alt="" /></li>
<li><img id="boton2" src="_imgs/b2.png" alt="" /></li>
<li><img id="boton3" src="_imgs/b3.png" alt="" /></li>
</ul>
</div>
</pre>
<h2>The Event Handlers</h2>
<p>Now the JavaScript: At load time I bind the touch events to the code that will handle the movement of the item.</p>
<p>The <em>touchstart</em> event is generated when the user touchs on an item. Using jQuery bind it to all div elements with class &#8220;content&#8221;. The called function will not only initiate the controls bar but it&#8217;ll also close any open element whenever the user touchs on any element of the list.</p>
<pre escaped="true" lang="javascript" line="1">$('div.content').bind(
    'touchstart',

    // whenever the user starts a touch event
    // on this kind of element...
    function(event) {

        // I close any open slider...
        hideControls();

        // and move the controls behind
        // the element touched by the user.
        setControls(event.target);

        // right now, the element is "closed"
        isOpen = false;
);</pre>
<p>While the user is moving the element Safari will call this code:</p>
<pre escaped="true" lang="javascript" line="1">$('div.content').bind(
    'touchmove',
    function(event) {
            // jQuery will send me the element
            // affected by the event
        var el = event.target,
            // this is a jQuery event object, so in order
            // to get the touch parameters I need to
            // access the originalEvent param.
            touch = event.originalEvent.touches[0],
            curX = touch.pageX - this.offsetLeft - 25;

        // we don't want the Safari's standard
        // behaviour for this kind of event.
        event.preventDefault();

        // we're near the left, do nothing.
        if(curX &lt;= 0) { return; }

        // user's moved the element past a point,
        // so I make it slide completely to the left
        if(curX &gt; 150) {
            showControls(el);

            // now the element is open.
            // the touchend handler needs to know it.
            isOpen = true;
            return;
        }
        // otherwise I move the element
        // to follow the user's gesture
         el.style.webkitTransform = 'translateX(' + curX + 'px)';
    }
);</pre>
<p>Finally, the <em>touchend</em> event will be send when the user lift ups the finger. This event will be sent regardless of the point where&#8217;s the user&#8217;s stopped the gesture. And regardless of our code moving the element out of the viewport. So we need to know if the element is &#8220;open&#8221; or not.</p>
<pre escaped="true" lang="javascript" line="1">$('div.content').bind(
    'touchend',
     function() {
        // only if our code hasn't been called...
        if(!isOpen) {
            // we move the element back to left.
            doSlide(this, 0);
         }
   }
);</pre>
<p>This is just an example function that will be called when the user touchs the <em>mail</em> icon on the tools bar.</p>
<pre escaped="true" lang="javascript" line="1">$('#boton3').click(doMail)</pre>
<h2>The Slider Code</h2>
<p>The functions that show or hide the controls are, finally, fairly simple. They only need to move the controls bar behind another object and apply a simple CSS transition.</p>
<p>Why a transition instead of a jQuery animation?. In iPhone the CSS transitions are handled bu the GPU, so they are more swift and &#8220;natural&#8221;. Note the this transitions will not be as smooth on Android&#8217;s version of WebKit. Even, in some versions of Android there&#8217;ll be no animations at all.</p>
<pre escaped="true" lang="javascript" line="1">// this function perfoms the sliding of the element
// using CSS3 transforms.
function doSlide(el, numPos) {
    el.style.webkitTransition = '-webkit-transform 0.3s ease-in';
    el.style.webkitTransform = 'translateX(' + numPos + 'px)';
}

// this function is called on touchstart.
// it "moves" the controls bar into the &lt;li&gt;
// that contains the &lt;div&gt; touched by the user.
function setControls(elDIV) {
    $(elDIV).closest('li').append($('#controls'));
}

// this just slides the element away to the right
function showControls(elDIV) {
    // I'm gonna need the refnum of the entry for
    // the functions called from the controls bar.
    numCurItem = elDIV.id;
    // slide the div way out to the right...
    doSlide(elDIV, ($(elDIV).outerWidth(true) + 50));
    // and store the currently open div in a var.
    elContent = elDIV;
}

// here we slide the "open" element back to the left
function hideControls() {
    if(elContent != null) {
        doSlide(elContent, 0);
        elContent = null;
    }
}</pre>
<h2>Conclusion</h2>
<p>So, this is what happens when you mix coders and beer and laughs. You learn some interesting things and get cred points in the process. You can use a similar effect in a desktop web app, by implementing a draggable object like in the <a href="http://css-tricks.com/slide-to-unlock/" target="_blank">css-tricks.com sample</a>.</p>
<p>BTW, the icons are from <a href="http://icondock.com/free/20-free-marker-style-icons" target="_blank">IconDock</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.forcen.com/2011/01/how-to-mimick-twitter-slides-on-safari-mobile/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Minified using disk
Page Caching using disk (enhanced)
Database Caching using disk
Object Caching 809/915 objects using disk

Served from: www.forcen.com @ 2012-05-21 07:59:54 -->
