<?xml version="1.0" encoding="UTF-8"?>
<rss 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/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Usuario de Internet</title>
	
	<link>http://www.usuariodeinternet.es</link>
	<description>Experiencias técnicas y lúdicas</description>
	<lastBuildDate>Mon, 01 Feb 2010 00:44:50 +0000</lastBuildDate>
	
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feed.usuariodeinternet.es/usuariodeinternet" /><feedburner:info uri="usuariodeinternet" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>Internacionalización con Smarty</title>
		<link>http://feed.usuariodeinternet.es/~r/usuariodeinternet/~3/EvY05SZACGw/internacionalizacion-con-smarty</link>
		<comments>http://www.usuariodeinternet.es/desarrollo/internacionalizacion-con-smarty#comments</comments>
		<pubDate>Mon, 23 Nov 2009 08:16:06 +0000</pubDate>
		<dc:creator>fer</dc:creator>
				<category><![CDATA[Desarrollo]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[smarty]]></category>

		<guid isPermaLink="false">http://www.usuariodeinternet.es/?p=532</guid>
		<description><![CDATA[
El temita de la internacionalización (i18n para los amigos) en una aplicación web puede dar para largo y tendido, yo voy a hablar aquí concretamente de la forma de guardar y utilizar las cadenas de texto del site en varios idiomas utilizando el framework de templates Smarty.
Hay muchas formas de hacerlo, se pueden encontrar varias [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: center;"><img title="Internacionalización con Smarty" src="/img/post/smarty_i18n.png" border="0" alt="Internacionalización con Smarty" width="640" height="97" /></p>
<p>El temita de la internacionalización (<em>i18n</em> para los amigos) en una aplicación web puede dar para largo y tendido, yo voy a hablar aquí concretamente de la <strong>forma de guardar y utilizar las cadenas de texto</strong> del site en varios idiomas utilizando el framework de templates <a href="http://www.smarty.net" target="_blank">Smarty</a>.</p>
<p>Hay muchas formas de hacerlo, se pueden encontrar varias alternativas en este post de <a href="http://www.smarty.net/forums/viewtopic.php?t=84&#038;postdays=0&#038;postorder=asc&#038;start=0" target="_blank">best way to build a multi-language site with smarty</a>, que empezó en el ¡2003! (el frenético ritmo que lleva la tecnología hace que no me crea nada que no sea de ayer&#8230;). Todas tienen sus ventajas e inconvenientes, y dado que no hay nada en el core de Smarty para ésto ni una solución popularmente aceptada como la <em>estándar</em>, cada uno debe analizar lo que necesita para su proyecto y tener unas preferencias subjetivas, que en mi caso son:</p>
<ul style="margin-left:30px;">
<li><strong>Que no implique PHP</strong>: obviamente hay opciones mucho más sofisticadas, eficientes, etc&#8230; para solucionar el tema del i18n con programación (por ejemplo <a href="http://sourceforge.net/projects/smarty-gettext/" target="_blank">smarty-gettext</a>), pero precisamente el uso de Smarty es para separar la lógica de la aplicación de la de presentación, y dado que considero que ésto es problema de front-end puro, yo quiero resolverlo únicamente con Smarty.</li>
<li><strong>Que sea sencillo y eficiente</strong>: con el tiempo me estoy conviertiendo en un talibán del código, en el sentido bueno (creo) de intentar que las cosas se hagan de la forma más clara posible (<a href="http://es.wikipedia.org/wiki/Principio_KISS" target="_blank">KISS</a> power!) y que note un pinchazo en el corazón con cada ciclo de reloj que se consume en código prescindible.</li>
</ul>
<p><span id="more-532"></span><br />
 Por ejemplo, hay una solución <strong>muy buena</strong> y que he utilizado en otros proyectos, <a href="http://smarty.incutio.com/?page=SmartyMultilanguageSupport" target="_blank">SmartyML</a>, pero es una clase más en PHP (una capa más para procesar) y viendo tanto código pienso que debe haber una forma mejor de hacerlo.</p>
<p>Pero vamos al turrón. Al final encontré en el foro antes mencionado la solución que me parece más sencilla y adecuada para lo que necesito. Se trata de utilizar <a href="http://smarty.net/manual/es/config.files.php" target="_blank"><strong>archivos de configuración</strong></a> (1ª ventaja: es una funcionalidad core de Smarty, con lo que no hay que añadir más complejidad). En estos ficheros se definen variables globales para los templates y se pueden aplicar de varias formas:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// desde el PHP</span>
<span style="color: #000088;">$smarty</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">config_load</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'fichero.conf'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// desde el template</span>
<span style="color: #009900;">&#123;</span>config_load <span style="color: #990000;">file</span><span style="color: #339933;">=</span><span style="color: #0000ff;">'fichero.conf'</span><span style="color: #009900;">&#125;</span></pre></div></div>

<p>Yo prefiero hacerlo desde PHP porque la gestión del idioma de la web es lógica de aplicación y hay que poner cada cosa en su sitio. El directorio donde se almacenan estos ficheros debe ser definido en el código:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$smarty</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Smarty<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$smarty</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">config_dir</span>   <span style="color: #339933;">=</span> <span style="color: #0000ff;">'/path/al/directorio/'</span><span style="color: #339933;">;</span></pre></div></div>

<p>Crearemos un archivo por idioma, en los que tendremos todas las cadenas de texto que vamos a utilizar traducidas, por ejemplo:</p>

<div class="wp_syntax"><div class="code"><pre class="smarty" style="font-family:monospace;"># /path/al/directorio/es.conf (español)
saludo = hola!
enviar = Enviar
cancelar = Cancelar</pre></div></div>


<div class="wp_syntax"><div class="code"><pre class="smarty" style="font-family:monospace;"># /path/al/directorio/en.conf (inglés)
saludo = hi!
enviar = Send
cancelar = Cancel</pre></div></div>

<p>Utilizar estas variables en los templates es tan sencillo como usar la sintaxis <strong>{#variable#}</strong>, por ejemplo:</p>

<div class="wp_syntax"><div class="code"><pre class="html4strict" style="font-family:monospace;"><span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">strong</span>&gt;</span>{#saludo#}<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">strong</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">input</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;button&quot;</span> <span style="color: #000066;">name</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;enviar&quot;</span> <span style="color: #000066;">value</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;{#enviar#}&quot;</span> <span style="color: #66cc66;">/</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">input</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;button&quot;</span> <span style="color: #000066;">name</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;cancelar&quot;</span> <span style="color: #000066;">value</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;{#cancelar#}&quot;</span> <span style="color: #66cc66;">/</span>&gt;</span></pre></div></div>

<p>¡Y ya está! desde el PHP se puede controlar qué archivo de configuración de idioma cargar y de esta manera tener montada nuestra web multilenguaje. Unos últimos apuntes:</p>
<ul style="margin-left:30px;">
<li>Las cadenas también pueden llevar <strong>texto variable</strong>, como por ejemplo un saludo del tipo <em>Hola Fernando, bienvenido!</em> Ésto se puede solucionar de dos formas:

<div class="wp_syntax"><div class="code"><pre class="smarty" style="font-family:monospace;"># forma CUTRE: en el tpl
<span style="color: #009000;">&lt;strong&gt;</span><span style="color: #D36900;">&#123;</span>#saludo1#<span style="color: #D36900;">&#125;</span><span style="color: #D36900;">&#123;</span><span style="color: #00aaff;">$nombre_usuario</span><span style="color: #D36900;">&#125;</span><span style="color: #D36900;">&#123;</span>#saludo2#<span style="color: #D36900;">&#125;</span><span style="color: #009000;">&lt;/strong&gt;</span>
&nbsp;
# en el archivo de configuración de idioma
saludo1 = Hola
saludo2 = bienvenido!</pre></div></div>


<div class="wp_syntax"><div class="code"><pre class="smarty" style="font-family:monospace;"># forma CORRECTA: en el tpl
<span style="color: #009000;">&lt;strong&gt;</span><span style="color: #D36900;">&#123;</span><span style="color: #0600FF;">eval</span> var<span style="color: #D36900;">=</span>#saludo#<span style="color: #D36900;">&#125;</span><span style="color: #009000;">&lt;/strong&gt;</span>
&nbsp;
# en el archivo de configuración de idioma
saludo = Hola <span style="color: #D36900;">&#123;</span><span style="color: #00aaff;">$nombre_usuario</span><span style="color: #D36900;">&#125;</span>, bienvenido!</pre></div></div>

</li>
<li>En lo que entiendo es una <strong>optimizacion</strong> (supongo que a nivel interno se controlará), se pueden utilizar <strong>secciones</strong> (referenciadas así <em>[seccion]</em>) en el archivo de configuración, de manera que si se especifica una en el <em>config_load</em> sólo esas variables se <em>cargarán</em> (la que estén fuera de una sección estarán siempre disponibles). Ésto nos puede servir para organizar las cadenas de texto por página y suponer que Smarty lo manejará mejor que el chorro completo de variables. Quedaría así:

<div class="wp_syntax"><div class="code"><pre class="smarty" style="font-family:monospace;"># cadenas globales
saludo = Hola!
enviar = Enviar
&nbsp;
# página de login
[login]
titulo = Introduce tu usuario y contraseña</pre></div></div>

<p>Y desde el PHP:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$smarty</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">config_load</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'es.conf'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">'login'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$smarty</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">display</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'login.tpl'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

</li>
<li>Una desventaja es que no maneja de manera nativa los <strong>plurales</strong> como otras soluciones, de forma que hay que controlarlo a manubrio, por ejemplo:

<div class="wp_syntax"><div class="code"><pre class="smarty" style="font-family:monospace;"># en el tpl
<span style="color: #D36900;">&#123;</span><span style="color: #0600FF;">eval</span> var<span style="color: #D36900;">=</span>#subida_fotos#<span style="color: #D36900;">&#125;</span><span style="color: #D36900;">&#123;</span><span style="color: #0600FF;">if</span> <span style="color: #00aaff;">$num_fotos</span> <span style="color: #D36900;">&gt;</span> <span style="color: #cc66cc;">1</span><span style="color: #D36900;">&#125;</span>s<span style="color: #D36900;">&#123;</span><span style="color: #D36900;">/</span><span style="color: #0600FF;">if</span><span style="color: #D36900;">&#125;</span>
&nbsp;
# en el archivo de configuración de idioma
subida_fotos = Has subido <span style="color: #D36900;">&#123;</span><span style="color: #00aaff;">$num_fotos</span><span style="color: #D36900;">&#125;</span> foto</pre></div></div>

</li>
</ul>
<p class="akst_link"><a href="http://www.usuariodeinternet.es/?p=532&amp;akst_action=share-this"  title="Comparte el artículo en Internet" id="akst_link_532" class="akst_share_link" rel="nofollow">Compártelo</a>
</p><img src="http://feeds.feedburner.com/~r/usuariodeinternet/~4/EvY05SZACGw" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.usuariodeinternet.es/desarrollo/internacionalizacion-con-smarty/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.usuariodeinternet.es/desarrollo/internacionalizacion-con-smarty</feedburner:origLink></item>
		<item>
		<title>Integrar las APIs de login de Facebook, Yahoo y Windows Live</title>
		<link>http://feed.usuariodeinternet.es/~r/usuariodeinternet/~3/c1Boyio63eg/integrar-las-apis-de-login-de-facebook-yahoo-y-windows-live</link>
		<comments>http://www.usuariodeinternet.es/desarrollo/integrar-las-apis-de-login-de-facebook-yahoo-y-windows-live#comments</comments>
		<pubDate>Fri, 20 Feb 2009 09:37:55 +0000</pubDate>
		<dc:creator>fer</dc:creator>
				<category><![CDATA[Desarrollo]]></category>
		<category><![CDATA[api]]></category>
		<category><![CDATA[facebook]]></category>
		<category><![CDATA[windows live]]></category>
		<category><![CDATA[yahoo]]></category>

		<guid isPermaLink="false">http://www.usuariodeinternet.es/?p=414</guid>
		<description><![CDATA[


La filosofía del single sign-on ha terminado imponiéndose por pura lógica de saturamiento 2.0, con los grandes jugadores vendiendo sus nuevas propuestas (OpenID lo intentó y no lo consiguió&#8230;) y los usuarios cansados de procesos de registro y contraseñas varias. Darles a éstos la oportunidad de usar sus credenciales de alguno de los servicios top [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: center;">
<img height="150" width="640" border="0" alt="El bonito single sign-on" src="/img/post/singlesignon.jpg" title="El bonito single sign-on"/>
</p>
<p>La filosofía del <strong>single sign-on</strong> ha terminado imponiéndose por pura lógica de saturamiento 2.0, con los grandes jugadores vendiendo sus nuevas propuestas (OpenID lo intentó y no lo consiguió&#8230;) y los usuarios cansados de procesos de registro y contraseñas varias. Darles a éstos la oportunidad de usar sus credenciales de alguno de los servicios top para utilizar tu sitio debería ser ya a estas alturas planteado como una funcionalidad primaria de cualquier proyecto web.</p>
<p>Lo que viene a continuación es una guía para implementar en tu web la funcionalidad de &#8220;login externo&#8221; usando las APIs de tres de los grandes: <strong>Facebook</strong>, <strong>Yahoo</strong> y <strong>Windows Live</strong> (Google y OpenID vendrán en otro post). El proceso es similar en todos los casos, y el objetivo es acabar teniendo para utilizar en nuestro código el id único externo (la variable <em>$id_unico</em> en los ejemplos) que nos sirva para identificar y validar al usuario en nuestro sistema local.<br />
<span id="more-414"></span></p>
<h2>Facebook</h2>
<p>La integración más sencilla de todas ¡5 líneas de código!</p>
<p>La <a href="http://developers.facebook.com/">documentación para desarrolladores de Facebook</a> es de las mejores, con muchos ejemplos prácticos y una comunidad muy activa. Vamos a hacer <strong>la implementación más sencilla</strong>, sin meternos en <a href="http://developers.facebook.com/connect.php">Facebook Connect</a>, que será chicha para otro post. Los pasos serían los siguientes:</p>
<ol style="margin-left:30px;">
<li>Logueado en tu cuenta de Facebook debes añadirte la <a href="http://www.facebook.com/developers/">aplicación para desarrolladores</a>.</li>
<li>Creamos una nueva aplicación, y rellenamos lo básico para que funcione (el resto es para configuraciones más avanzadas)
<p style="text-align: center;margin-top:10px;"><img src="/img/post/apilog_facebook_campos.png" alt="Campos mínimos para rellenar en la aplicación de Facebook" title="Campos mínimos para rellenar en la aplicación de Facebook" width="701" height="244" /></p>
</li>
<li>Nos bajamos la <a href="http://svn.facebook.com/svnroot/platform/clients/packages/facebook-platform.tar.gz">librería cliente de PHP</a>.</li>
<li>¡Y a picar!</li>
</ol>
<p>Resumiendo, tenemos una api key, otra key privada, hemos especificado una URL propia de retorno de Facebook, y tenemos su clase de PHP (nos sobraría con los ficheros <em>facebook.php</em> y <em>facebookapi_php5_restlib.php</em>). Pues el script para loguearse con Facebook sería tan sencillo como esto:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// cargamos la clase que nos proporcionan</span>
	<span style="color: #b1b100;">require_once</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'apis_externas/facebook/class_facebook.php'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// datos de la aplicación que se nos facilitan cuando la registramos en Facebook </span>
	<span style="color: #000088;">$appapikey</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'000000000000'</span><span style="color: #339933;">;</span>
	<span style="color: #000088;">$appsecret</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'111111111111'</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// inicializamos el objeto de la clase</span>
	<span style="color: #000088;">$facebook</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Facebook<span style="color: #009900;">&#40;</span><span style="color: #000088;">$appapikey</span><span style="color: #339933;">,</span><span style="color: #000088;">$appsecret</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// si el usuario no está logueado en Facebook le redirigirá allí</span>
	<span style="color: #000088;">$id_unico</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$facebook</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">require_login</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">empty</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$id_unico</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
	<span style="color: #009900;">&#123;</span>
		<span style="color: #666666; font-style: italic;">// si a estas alturas no tenemos el id único algo ha salido mal</span>
		<span style="color: #000088;">$error_api</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></td></tr></table></div>

<p>Hay varias formas de hacer esto en Facebook, y no digo que esta sea la más correcta, pero seguro que la más sencilla. La importante es la línea 14, en la que si el usuario está logueado nos devolverá su id único, y sino le enviará a la página de login de Facebook.</p>
<h2>Yahoo</h2>
<p>Otra API con integración <em>no traumática</em> gracias a la tecnología <a href="https://developer.yahoo.com/auth/">BBAuth de Yahoo</a>. Aquí también se pueden elegir varias implementaciones (OAuth, OpenID), pero de nuevo vamos a optar por la más sencilla y rápida de desarrollar. Los pasos son los siguientes:</p>
<ol style="margin-left:30px;">
<li>Vamos a la página de <a href="https://developer.yahoo.com/dashboard/">alta de aplicaciones</a> (se necesita usuario de Yahoo).</li>
<li>Creamos una nueva <em>Browser-Based Authentication Protected Application</em>
<p style="text-align: center;margin-top:10px;"><img src="/img/post/apilog_yahoo_campos.gif" alt="Campos mínimos para rellenar en la aplicación de Yahoo" title="Campos mínimos para rellenar en la aplicación de Yahoo" width="665" height="586" /></p>
</li>
<li>Nos pedirán confirmar el dominio subiendo un fichero determinado a nuestra web.</li>
<li>Nos bajamos la <a href="https://developer.yahoo.com/auth/quickstart/bbauth_quickstart.zip">librería cliente de PHP</a>.</li>
<li>¡Y a picar!</li>
</ol>
<p>Resumiendo de nuevo, tenemos la aplicación creada, apuntadas las dos keys que necesitamos y la clase para comunicarnos con Yahoo (usaremos el fichero <em>ybrowserauth.class.php4</em> o <em>ybrowserauth.class.php5</em> dependiendo de nuestra versión de PHP). El código final quedará así:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// datos de la aplicación que se nos facilitan cuando la registramos en Yahoo</span>
	<span style="color: #990000;">define</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'APPID'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">'000000000000'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #990000;">define</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'SECRET'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">'111111111111'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>	
&nbsp;
	<span style="color: #666666; font-style: italic;">// cargamos la clase que nos proporcionan (en este caso tenemos PHP 5 en el servidor)</span>
	<span style="color: #b1b100;">require_once</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'apis_externas/yahoo/ybrowserauth.class.php5'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// inicializamos el objeto de la clase</span>
	<span style="color: #000088;">$authObj</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> YBBauthREST<span style="color: #009900;">&#40;</span>APPID<span style="color: #339933;">,</span>SECRET<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">empty</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$_GET</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'token'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> 
	<span style="color: #009900;">&#123;</span>
		<span style="color: #666666; font-style: italic;">// si no tenemos token mandamos a la página de login</span>
		<span style="color: #000088;">$url</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$authObj</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getAuthURL</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">''</span><span style="color: #339933;">,</span><span style="color: #009900; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #990000;">header</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Location: '</span><span style="color: #339933;">.</span><span style="color: #000088;">$url</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #990000;">exit</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$authObj</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">validate_sig</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> 
	<span style="color: #009900;">&#123;</span>
		<span style="color: #666666; font-style: italic;">// si validamos el token ya podemos sacar el id único</span>
		<span style="color: #000088;">$id_unico</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$authObj</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">userhash</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
	<span style="color: #b1b100;">else</span>
	<span style="color: #009900;">&#123;</span>
		<span style="color: #666666; font-style: italic;">// el token recibido no es correcto</span>
		<span style="color: #000088;">$error_api</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></td></tr></table></div>

<p>Es muy importante recordar que esta API es especial en el sentido que el id que se recibe finalmente es un <strong>hash del id único real del usuario en Yahoo y el id de la aplicación</strong>, es decir, si el mismo usuario de loguea con otra aplicación recibiremos un hash distinto, por lo que tenemos que tener en cuenta qué significa exactamente este id <em>único</em> que recibimos de la API.</p>
<h2>Windows Live</h2>
<p>Haciendo honor a su fama, y con mucha diferencia, la API de Windows Live es la más complicada de implementar, tanto por su <a href="http://msdn.microsoft.com/en-us/library/bb676633.aspx">horrenda documentación</a> (lo de msdn es terminal&#8230;) como por el engorro general que supone lidiar con sus múltiples archivos y su extraño flujo de información.</p>
<p>Los pasos iniciales son similares a las anteriores APIs, la diversión viene después&#8230;</p>
<ol style="margin-left:30px;">
<li>Vamos a la página de <a href="https://lx.azure.microsoft.com/">alta de aplicaciones</a> (se necesita usuario de Windows Live).</li>
<li>Creamos un proyecto de <em>Live Services: Existing APIs</em>
<p style="text-align: center;margin-top:10px;"><img src="/img/post/apilog_windowslive_campos.gif" alt="Campos mínimos para rellenar en la aplicación de Windows Live" title="Campos mínimos para rellenar en la aplicación de Windows Live" width="685" height="440" /></p>
<p>Es en este formulario cuando nos enfrentamos al primer problema absurdo, y es que el campo <em>Return URL</em> permite un <strong>máximo de 50 caracteres</strong> wtf?? cualquier ruta que no vaya a la raíz va a tener más de 50 letras! la única solución es tener una herramienta tipo <a href="http://getfirebug.com/">firebug</a> para poder editar online el HTML y cambiar el atributo <em>maxlength</em> del campo para poder enviar una URL en condiciones (lo que confirma lo absurdo de la limitación es que la página no te comprueba si has escrito más de esos 50 caracteres, se envía sin problemas&#8230;)<br />
Y atención también que la <strong>URL de retorno no es la misma que el resto de las APIs</strong>, es a un script que nos bajaremos luego con el SDK.</li>
<li>Nos bajamos el <a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=E565FC92-D5F6-4F5F-8713-4DD1C90DE19F&#038;displaylang=en#filelist">Web Authentication SDK</a> para el lenguaje que vayamos a utilizar.</li>
<li>¡Y a picar!</li>
</ol>
<p>De nuevo tenemos una api key, otra key privada, hemos especificado una URL de retorno nueva, y tenemos su SDK con varios archivos. Lo primero es poner las keys en el fichero <strong><em>Application-Key.xml</em></strong> (debe ser innaccesible desde internet, bien limitándolo con un htaccess o colocándolo fuera del document root):</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
</pre></td><td class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;windowslivelogin<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;appid<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>000000000000<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/appid<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;secret<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>111111111111<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/secret<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;securityalgorithm<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>wsignin1.0<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/securityalgorithm<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/windowslivelogin<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></td></tr></table></div>

<p>Ahora en el directorio <em>sample</em> tenemos una implementación de ejemplo a la que podemos quitarle bastante paja. Lo primero es editar el fichero <strong><em>settings.php</em></strong>:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// por si las cosas no salen y se necesita consultar logs de errores </span>
	<span style="color: #000088;">$DEBUG</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// path completo al XML de configuración de la aplicación</span>
	<span style="color: #000088;">$KEYFILE</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'/home/usuario/Application-Key.xml'</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// nombre de la cookie que almacena el token de usuario que manda la API</span>
	<span style="color: #000088;">$COOKIE</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'webauthtoken'</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// URL a la que tiene que redirigir cuando todo termine</span>
	<span style="color: #000088;">$INDEX</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'/login_externo.php'</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// páginas a las que tiene que llevar cuanto se haga login o logout</span>
	<span style="color: #000088;">$LOGIN</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$INDEX</span><span style="color: #339933;">;</span>
	<span style="color: #000088;">$LOGOUT</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$INDEX</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// la URL de la API ¡no tocar!</span>
	<span style="color: #000088;">$CONTROLURL</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'http://login.live.com/controls/WebAuth.htm'</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></td></tr></table></div>

<p>En el fichero <strong><em>webauth-handler.php</em></strong> (recordar que es éste el que hemos puesto como URL de retorno al crear la aplicación) tenemos que poner la rutas correcta al fichero de configuración y a la librería de la API (el fichero <em>windowslivelogin.php</em> en el directorio <em>lib</em>):</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
&nbsp;
	<span style="color: #b1b100;">require</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'/home/usuario/dominio/windows_live/settings.php'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #b1b100;">require</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'/home/usuario/dominio/windows_live/lib/windowslivelogin.php'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #339933;">....</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></td></tr></table></div>

<p>Y finalmente el código que implementa la autenticación con Windows Live:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// el fichero de configuración de la API</span>
	<span style="color: #b1b100;">require</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'/home/usuario/dominio/windows_live/settings.php'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// la librería del SDK</span>
	<span style="color: #b1b100;">require</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'/home/usuario/dominio/windows_live/lib/windowslivelogin.php'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// inicializamos las variables</span>
	<span style="color: #000088;">$wll</span> <span style="color: #339933;">=</span> WindowsLiveLogin<span style="color: #339933;">::</span><span style="color: #004000;">initFromXml</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$KEYFILE</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #000088;">$wll</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setDebug</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$DEBUG</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #000088;">$APPID</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$wll</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getAppId</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #000088;">$userid</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// comprobamos si el token de usuario está en la cookie</span>
	<span style="color: #000088;">$token</span> <span style="color: #339933;">=</span> <span style="color: #339933;">@</span><span style="color: #000088;">$_COOKIE</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$COOKIE</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #990000;">empty</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$token</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
	<span style="color: #009900;">&#123;</span>
		<span style="color: #000088;">$user</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$wll</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">processToken</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$token</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #666666; font-style: italic;">// tenemos token, intentamos sacar de él el id único del usuario</span>
		<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #990000;">empty</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$user</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
		<span style="color: #009900;">&#123;</span>
			<span style="color: #000088;">$userid</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$user</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getId</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #990000;">empty</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$userid</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
	<span style="color: #009900;">&#123;</span>
		<span style="color: #666666; font-style: italic;">// guardamos el id único</span>
		<span style="color: #000088;">$id_unico</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$userid</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
	<span style="color: #b1b100;">else</span>
	<span style="color: #009900;">&#123;</span>
		<span style="color: #666666; font-style: italic;">// si no tenemos token, redirigimos al usuario a la página de login de Windows Live</span>
		<span style="color: #990000;">header</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Location: http://login.live.com/wlogin.srf?appid=0000000040009631&amp;alg=wsignin1.0'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #990000;">exit</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></td></tr></table></div>

<p>Quedaría, como en el resto de APIs, hacer una gestión eficiente de los errores que se pueden dar, aunque eso ya son detalles de implementación de cada aplicación.</p>
<p>Tampoco comento nada sobre los módulos de PHP que es necesario tener activados en el servidor para hacer funcionar las APIs. En principio los únicos que considero pudieran salirse de una configuración básica son <a href="http://es.php.net/curl"><strong>curl</strong></a> y <a href="http://es.php.net/mhash"><strong>mhash</strong></a>. Curl se utiliza en la librería de Yahoo y es complicado buscarle una alternativa. Mhash se utiliza en la de Windows Live, y en este caso, siendo una extensión mucho menos común, se puede <em>puentear</em> su uso parcheando el fichero <strong>windowslivelogin.php</strong>, en concreto la línea:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1515
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$key</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mhash</span><span style="color: #009900;">&#40;</span>MHASH_SHA256<span style="color: #339933;">,</span> <span style="color: #000088;">$key</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>Cambiándola para utilizar funciones del core de PHP5 que también realizan el hash binario SHA256:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1515
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$key</span> <span style="color: #339933;">=</span> <span style="color: #990000;">pack</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;H*&quot;</span><span style="color: #339933;">,</span> <span style="color: #990000;">hash</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'sha256'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$key</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p class="akst_link"><a href="http://www.usuariodeinternet.es/?p=414&amp;akst_action=share-this"  title="Comparte el artículo en Internet" id="akst_link_414" class="akst_share_link" rel="nofollow">Compártelo</a>
</p><img src="http://feeds.feedburner.com/~r/usuariodeinternet/~4/c1Boyio63eg" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.usuariodeinternet.es/desarrollo/integrar-las-apis-de-login-de-facebook-yahoo-y-windows-live/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		<feedburner:origLink>http://www.usuariodeinternet.es/desarrollo/integrar-las-apis-de-login-de-facebook-yahoo-y-windows-live</feedburner:origLink></item>
		<item>
		<title>Ya tengo nuevo juguete: tumblr</title>
		<link>http://feed.usuariodeinternet.es/~r/usuariodeinternet/~3/loAkTAcByh0/ya-tengo-nuevo-juguete-tumblr</link>
		<comments>http://www.usuariodeinternet.es/navegando/ya-tengo-nuevo-juguete-tumblr#comments</comments>
		<pubDate>Sun, 08 Feb 2009 19:13:20 +0000</pubDate>
		<dc:creator>fer</dc:creator>
				<category><![CDATA[Navegando]]></category>
		<category><![CDATA[comunidad]]></category>
		<category><![CDATA[tumblr]]></category>

		<guid isPermaLink="false">http://www.usuariodeinternet.es/?p=467</guid>
		<description><![CDATA[
 Estoy viciado a tumblr, enganchado a su sencillez, encantado con su filosofía y alucinando con su comunidad.

Es sencillo como pocas cosas compartir lo que quieras en tu tumblr. Tienes un dashboard con enlaces según el tipo de contenido que quieres publicar y poco más. Rellenas un campo (dos si eres pro) y de las [...]]]></description>
			<content:encoded><![CDATA[<div style="float: left; margin-right: 10px;"><img src="/img/post/tumblr.gif" alt="Logo tumblr" title="Logo tumblr" width="200" height="200"  /></div>
<p> Estoy viciado a <a href="http://www.tumblr.com"><strong>tumblr</strong></a>, enganchado a su sencillez, encantado con su filosofía y alucinando con su comunidad.</p>
<ul style="margin-left:30px;">
<li>Es <strong>sencillo</strong> como pocas cosas compartir lo que quieras en tu tumblr. Tienes un dashboard con enlaces según el tipo de contenido que quieres publicar y poco más. Rellenas un campo (dos si eres pro) y de las al botón de <em>Create post</em>. Hay <a href="https://addons.mozilla.org/es-ES/firefox/addon/5867">extensiones de firefox</a> que lo hacen tan trivial como arrastrar el contenido a un icono de tu barra de estado. Y sí, la sencillez crea <strong>adicción</strong> (¿he oído twitter?)
<li style="margin-top:10px;">tumblr es la quintaesencia de la <strong>filosofía</strong> del <a href="http://es.wikipedia.org/wiki/Tumblelog">tumblelog</a>, el término medio entre el blog de toda la vida y el nuevo microblogging, un espacio sin necesidad de temática fija, sin los rigores de un post más trabajado y con ese plus multimedia que a veces se echa en falta en el nanoblogging. No hay comentarios, no hay categorías ni tags&#8230; es una servilleta de papel de un bar en la que apuntas lo que te viene a la cabeza, lo que encuentras, lo que te gusta&#8230; y es <strong>tu</strong> servilleta, porque las posibilidades de personalización son <strong>totales</strong> (<a href="http://tumblrawards.tumblr.com/">ver ejemplos</a>).</li>
<li style="margin-top:10px;">Y sin duda lo que más me ha sorprendido es la <strong>comunidad</strong>. Me recuerda la sensación que tengo cuando navego por <a href="http://www.vimeo.com">Vimeo</a>, todo parece de tanta calidad y veo tan poca morralla que me da que pensar si estas comunidades se forman de manera espontánea o la supuesta navegación por el portal es en realidad una visita guiada a través de un filtro anti-shit. Una muestra en el <a href="http://www.tumblr.com/radar">Radar</a> y el <a href="http://www.tumblr.com/directory">Directorio</a>.
<p>Otro plus es que es una comunidad <strong>activa </strong> (cosa que no me extraña). En tu dashboard puedes ver las actualizaciones de los tumblrs que sigues (otro vicio), y continuando con la sencillez, puedes <em>rebloguear</em> ese contenido o guardártelo como favorito. Todo esto para comentar que he visto como <a href="http://slackr.tumblr.com/">un usuario</a> (que digo yo será bastante popular) ha colgado una foto y al minuto tenía más de 20 reblog/likes. Lástima que en castellano hayan tan pocos (bueno, tampoco me he puesto a buscar, me vale con las joyitas que voy encontrando) tumblrs&#8230;</li>
</ul>
<p>En definitiva, para mi tumblr ha supuesto el complemento perfecto a este blog y <a href="http://twitter.com/olfativo">mi tuiter</a>. La puntilla ha sido cuanto el otro día <a href="http://staff.tumblr.com/post/75941045/twitter">lanzaron la integración oficial con twitter</a>, justo en el clavo, es exactamente uno de los usos que me gusta darle al microblogging, compartir cosas que me voy encontrando en las navegaciones a la deriva&#8230; ahora por fin tengo la perfecta servilleta de papel para apuntarlos y que no se pierdan en la niebla de mi historial!</p>
<p>Para terminar, unos cuantos tumblrs: <a href="http://yimmyayo.tumblr.com/">yimmyayo</a>, <a href="http://hipstertracks.tumblr.com/">hipstertracks</a>, <a href="http://graphiceverywhere.tumblr.com/">graphiceverywhere</a>, <a href="http://kari-shma.tumblr.com/">kari-shma</a>&#8230; y por supuesto el mio!! <a href="http://micro.usuariodeinternet.es/"><strong>micro usuario de internet</strong></a>!!</p>
<p style="text-align: center;">
<a href="http://micro.usuariodeinternet.es/" style="border-bottom:0px;"><img height="143" width="518" border="0" alt="micro usuario de internet, mi tumblr" src="/img/post/tumblr_cabecera_final.jpg" title="micro usuario de internet, mi tumblr"/></a></p>
<p class="akst_link"><a href="http://www.usuariodeinternet.es/?p=467&amp;akst_action=share-this"  title="Comparte el artículo en Internet" id="akst_link_467" class="akst_share_link" rel="nofollow">Compártelo</a>
</p><img src="http://feeds.feedburner.com/~r/usuariodeinternet/~4/loAkTAcByh0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.usuariodeinternet.es/navegando/ya-tengo-nuevo-juguete-tumblr/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://www.usuariodeinternet.es/navegando/ya-tengo-nuevo-juguete-tumblr</feedburner:origLink></item>
		<item>
		<title>Spotify ¿realidad o ficción?</title>
		<link>http://feed.usuariodeinternet.es/~r/usuariodeinternet/~3/HcNnChFs8k4/spotify-realidad-o-ficcion</link>
		<comments>http://www.usuariodeinternet.es/navegando/spotify-realidad-o-ficcion#comments</comments>
		<pubDate>Thu, 15 Jan 2009 20:57:52 +0000</pubDate>
		<dc:creator>fer</dc:creator>
				<category><![CDATA[Navegando]]></category>
		<category><![CDATA[musica]]></category>
		<category><![CDATA[negocio]]></category>

		<guid isPermaLink="false">http://www.usuariodeinternet.es/?p=385</guid>
		<description><![CDATA[
Durante estos días uno no hace más que ver en Internet referencias al nuevo killer service, venerado por la blogosfera y los early adopters (frikis para los profanos), Spotify, o como dar un vuelco al negocio de la música en Internet por la patilla.
Y es que el temita promete. El otro día conseguí una invitación [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: center"><img title="Spotify, la nueva revolución de la música en Internet" src="/img/post/spotify_logo.gif" border="0" alt="Spotify, la nueva revolución de la música en Internet" width="640" height="150" /></p>
<p>Durante estos días uno no hace más que ver en Internet referencias al nuevo killer service, venerado por la blogosfera y los <em>early adopters</em> (frikis para los profanos), <a href="http://www.spotify.com"><strong>Spotify</strong></a>, o como dar un vuelco al negocio de la <strong>música en Internet</strong> por la patilla.</p>
<p>Y es que el temita promete. El otro día conseguí una invitación (ahora mismo está en beta semi-pública) sin saber qué leches iba a probar, y sin ser usuario de servicios tipo last.fm, pandora, etc&#8230; vamos, yo soy de los del género vago, de abrir la radio online a las 9:00 y no cerrarla hasta las 19:00. Pero es que ésto está tan bien hecho, es tan sencillo, tan fluido, que crea adicción, incluso en analfabetos musicales de mi calaña. <strong>Primer logro</strong>.</p>
<p>El servicio va de: <strong>A</strong>. Registrarse <strong>B</strong>. Instalarse su aplicación <strong>C</strong>. ¡Música! (<em>it&#8217;s easy as 1,2,3!</em>). La herramienta es una maravilla, un iTunes fibrado y ligero, diseño minimalista y usabilidad cuidada. Cualquier camino dentro de la aplicación termina siempre en <strong>escuchar música</strong>. Haces click en el nombre de un artista, vas a su ficha, ves toda su discografía, clickeas el track 9 del CD2 de su disco de hace 7 años y lo escuchas. TODA canción que aparezca en la aplicación simplemente haces click y la escuchas. <strong>Música gratis bajo demanda</strong>.</p>
<p style="text-align: center"><img title="La aplicación de escritorio de Spotify" src="/img/post/spotify_app.jpg" border="0" alt="La aplicación de escritorio de Spotify" width="500" height="292" /></p>
<p>No voy a analizar sus pros y contras, para eso ya sabéis que hay <a href="http://www.genbeta.com/2009/01/13-musica-gratis-al-instante-spotify">otras webs temáticas</a>, sólo comentar lo que<strong> me siguen sorprendiendo algunos modelos de negocio en Internet</strong>. En algo como la música, con unos proveedores que odian y desprecian al medio, y unos márgenes pírricos (creo recordar que si en iTunes una canción costaba 0.99 €, las majors se llevaban 0.70 €), no me parece muy sostenible la apuesta de Spotify, con un modelo freebie totalmente funcional (si el modelo premium lo único que me ofrece es que no me salgan ads sonoros, poco van a sacar por ahí), unos ingresos por publicidad tipo radio (¿éso lo sigue contratando alguien?) y un coste asociado al ancho de banda de servir las canciones (<a href="http://torrentfreak.com/spotify-an-alternative-to-music-piracy-090102/">aunque utilicen un modelo híbrido P2P</a>). Tal vez sea lo que se comenta por ahí, que es un torpedo con el que la industria discográfica (¿tal vez hayan aceptado menos trozo de la tarta por el compromiso de los responsables del proyecto de que <em>algo</em> va a cambiar?) quiere atacar a la línea de flotación de la piratería musical: &#8220;<em>Tú, alma triste, si te pongo un programita con el puedes escuchar cualquier canción como si la tuvieras descargada ¿pa que leches quieres seguir dándole al emule?</em>&#8221;</p>
<p>Y bueno, no tendrán la parte social muy desarrollada, pero en Twitter por ejemplo no paran ya de llover los enlaces para escuchar canciones. Comparto un temazo: <a href="http://open.spotify.com/track/40ThmAgDduNcjwkypLe0Dj">http://open.spotify.com/track/40ThmAgDduNcjwkypLe0Dj</a></p>
<p>Por cierto, <strong>tengo unas cuantas invitaciones</strong> para probar Spotify, aunque no se si es una puerta trasera dejada abierta disimuladamente aposta o están en la parra, pero por ahora <a href="https://www.spotify.com/en/get-started/">te puedes registrar sin invitación aquí</a>. <strong>ACTUALIZACIÓN</strong>: parece ser que dicha puerta ha sido cerrada, de todas formas yo sigo teniendo unas cuantas invitaciones, si lo necesitas escribe un comentario.</p>
<p class="video_tit">su vídeo promocional</p>
<div class="video_marco" style="width:500px;"><object width="500" height="281"><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=1900024&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=0&amp;show_portrait=0&amp;color=00adef&amp;fullscreen=1" /><embed src="http://vimeo.com/moogaloop.swf?clip_id=1900024&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=0&amp;show_portrait=0&amp;color=00adef&amp;fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="500" height="281"></embed></object></div>
<p class="akst_link"><a href="http://www.usuariodeinternet.es/?p=385&amp;akst_action=share-this"  title="Comparte el artículo en Internet" id="akst_link_385" class="akst_share_link" rel="nofollow">Compártelo</a>
</p><img src="http://feeds.feedburner.com/~r/usuariodeinternet/~4/HcNnChFs8k4" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.usuariodeinternet.es/navegando/spotify-realidad-o-ficcion/feed</wfw:commentRss>
		<slash:comments>19</slash:comments>
		<feedburner:origLink>http://www.usuariodeinternet.es/navegando/spotify-realidad-o-ficcion</feedburner:origLink></item>
		<item>
		<title>Semana 3 / Pixel Feed</title>
		<link>http://feed.usuariodeinternet.es/~r/usuariodeinternet/~3/Hh_2Ti3BW78/semana-3-pixel-feed</link>
		<comments>http://www.usuariodeinternet.es/lecturas/semana-3-pixel-feed#comments</comments>
		<pubDate>Sun, 04 Jan 2009 21:21:47 +0000</pubDate>
		<dc:creator>fer</dc:creator>
				<category><![CDATA[Lecturas]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[enlaces]]></category>
		<category><![CDATA[musica]]></category>

		<guid isPermaLink="false">http://www.usuariodeinternet.es/?p=262</guid>
		<description><![CDATA[

El tam-tam de los &#8220;nativos digitales&#8221; / elpais.com
Un artículo que me ha parecido muy interesante por dos cosas: primero, plantear cómo va a ser la madurez de esta nueva generación que ha nacido con Internet ¿qué usarán después de Tuenti? ¿por fin comercio electrónico total (comprar el pan por Internet, vamos), la verdadera televisión online? [...]]]></description>
			<content:encoded><![CDATA[<div class="linkfavicon margentopmini"><span></span><img src="/img/favicon/elpais.gif" /></div>
<div class="linktexto margentopmini">
<p><a href="http://www.elpais.com/articulo/sociedad/tam-tam/nativos/digitales/elpeputec/20081221elpepisoc_1/Tes" target="_blank"><strong>El tam-tam de los &#8220;nativos digitales&#8221;</strong></a> <span>/ elpais.com</span></p>
<p>Un artículo que me ha parecido muy interesante por dos cosas: primero, plantear cómo va a ser la madurez de esta nueva generación que ha nacido con Internet ¿qué usarán después de Tuenti? ¿por fin comercio electrónico total (comprar el pan por Internet, vamos), la verdadera televisión online? En España se va a poner el medio muy interesante! y segundo, el artículo habla sobre los nuevos retos que plantea esto mismo en la educación. A mi eso de que &#8220;<em>Su atención se divide mejor, su cerebro tiene un procesador más complejo</em>&#8221; me parece una tontería, no son mas listos ni multitarea, pero para esto mejor leer los comentarios del artículo, hay opiniones de primera mano, los profesores</p>
</div>
<div style="clear:both;"></div>
<div class="linkfavicon"><span></span><img src="/img/favicon/generico.gif" /></div>
<div class="linktexto">
<p><a href="http://gallir.wordpress.com/2008/11/28/pequena-historia-del-fracaso-de-un-proyecto-personal-derrotado-por-friendfeed-por-goleada-y-sin-siquiera-salir-al-campo/" target="_blank"><strong>Pequeña historia del fracaso de un proyecto personal</strong></a> <span>/ gallir.wordpress.com</span></p>
<p>Me ha encantado este post, esa sensación de tener la idea, llegar incluso a plasmarla en un boceto, adelantar a paso de tortuga, y todo para terminar viendo pasar a toda ostia a otro que tuvo la misma antes o después, pero consiguió los recursos para llevarla a cabo. Lo que se suele decir &#8220;<em>Primera regla del éxito: Empezar</em>&#8220;</p>
</div>
<div style="clear:both;"></div>
<div class="linkfavicon"><span></span><img src="/img/favicon/sethgodin.gif" /></div>
<div class="linktexto">
<p><a href="http://sethgodin.typepad.com/seths_blog/2008/11/three-new-jobs.html" target="_blank"><strong>Three new jobs you might want to consider</strong></a> <span>/ sethgodin.typepad.com</span></p>
<p>La web social lo ha cambiado todo, y entre otras cosas no puedo estar más deacuerdo en que ha generado la necesidad para las empresas de Internet de contar con nuevos perfiles profesionales para manejarse en estos mares. Yo considero básica ya a estas alturas la figura del <strong>responsable de comunidad</strong>, que no viene a ser más que el relaciones públicas 2.0, ese cuyas principales armas son Facebook, Twitter&#8230;.</p>
</div>
<div style="clear:both;"></div>
<div class="linkfavicon"><span></span><img src="/img/favicon/sixrevisions.gif" /></div>
<div class="linktexto">
<p><a href="http://sixrevisions.com/ajax/20-excellent-websites-for-learning-ajax/" target="_blank"><strong>20 Excellent Websites for Learning Ajax</strong></a> <span>/ sixrevisions.com</span></p>
<p>Aprender los básicos de Ajax es realmente sencillo, es un método que para usos normales no suele salirse de un ABC fijo. Pero aquí han recopilado una serie de sitios que permiten meterse de cabeza en esta tecnología con todos sus detalles y complejidad</p>
</div>
<div style="clear:both;"></div>
<div class="linkfavicon"><span></span><img src="/img/favicon/smashingmagazine.gif" /></div>
<div class="linktexto">
<p><a href="http://www.smashingmagazine.com/2008/11/16/60-beautiful-music-videos/" target="_blank"><strong>60 Beautiful Music Videos</strong></a> <span>/ smashingmagazine.com</span></p>
<p>Si es que me encantan los videoclips, y más los originales, en los que me acaba gustando más el vídeo que la música. En este post recopilan auténticas joyitas, y cuidado, es NSFW, un auténtico mata-productividad</p>
</div>
<div style="clear:both;"></div>
<p style="margin-top:20px;text-align:center;font-size:12px;">adoremos al pixel</p>
<div style="border: 1px solid #dcdcdc; margin: 15px auto; padding: 7px; background: #ffffff url(/wp-content/themes/Fontella/images/imagesbg.png) repeat-x scroll center bottom; width: 425px;"><object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/MXIzyquw-kc&#038;showsearch=0&#038;rel=0"></param><param name="wmode" value="transparent"></param><embed src="http://www.youtube.com/v/MXIzyquw-kc&#038;showsearch=0&#038;rel=0" type="application/x-shockwave-flash" wmode="transparent" width="425" height="344"></embed></object></div>
<p class="akst_link"><a href="http://www.usuariodeinternet.es/?p=262&amp;akst_action=share-this"  title="Comparte el artículo en Internet" id="akst_link_262" class="akst_share_link" rel="nofollow">Compártelo</a>
</p><img src="http://feeds.feedburner.com/~r/usuariodeinternet/~4/Hh_2Ti3BW78" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.usuariodeinternet.es/lecturas/semana-3-pixel-feed/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.usuariodeinternet.es/lecturas/semana-3-pixel-feed</feedburner:origLink></item>
		<item>
		<title>¡Feliz Navidad!</title>
		<link>http://feed.usuariodeinternet.es/~r/usuariodeinternet/~3/U4HGj-pROLM/feliz-navidad</link>
		<comments>http://www.usuariodeinternet.es/personal/feliz-navidad#comments</comments>
		<pubDate>Mon, 22 Dec 2008 12:01:40 +0000</pubDate>
		<dc:creator>fer</dc:creator>
				<category><![CDATA[Personal]]></category>
		<category><![CDATA[chunda chunda]]></category>
		<category><![CDATA[musica]]></category>
		<category><![CDATA[navidad]]></category>

		<guid isPermaLink="false">http://www.usuariodeinternet.es/?p=289</guid>
		<description><![CDATA[
Compártelo
]]></description>
			<content:encoded><![CDATA[<div style="border: 1px solid #dcdcdc; margin: 15px auto; padding: 7px; background: #ffffff url(http://www.fernandogarciatorres.es/wp-content/themes/Fontella/images/imagesbg.png) repeat-x scroll center bottom; width: 640px;"><object width="640" height="360"><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=2515299&amp;server=vimeo.com&amp;show_title=0&amp;show_byline=0&amp;show_portrait=0&amp;color=00adef&amp;fullscreen=1" /><embed src="http://vimeo.com/moogaloop.swf?clip_id=2515299&amp;server=vimeo.com&amp;show_title=0&amp;show_byline=0&amp;show_portrait=0&amp;color=00adef&amp;fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="640" height="360"></embed></object></div>
<p class="akst_link"><a href="http://www.usuariodeinternet.es/?p=289&amp;akst_action=share-this"  title="Comparte el artículo en Internet" id="akst_link_289" class="akst_share_link" rel="nofollow">Compártelo</a>
</p><img src="http://feeds.feedburner.com/~r/usuariodeinternet/~4/U4HGj-pROLM" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.usuariodeinternet.es/personal/feliz-navidad/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.usuariodeinternet.es/personal/feliz-navidad</feedburner:origLink></item>
		<item>
		<title>Lanzamiento de Gente QUÉ</title>
		<link>http://feed.usuariodeinternet.es/~r/usuariodeinternet/~3/Rv_sFHpeSKg/lanzamiento-de-gente-que</link>
		<comments>http://www.usuariodeinternet.es/profesional/lanzamiento-de-gente-que#comments</comments>
		<pubDate>Sun, 21 Dec 2008 17:07:29 +0000</pubDate>
		<dc:creator>fer</dc:creator>
				<category><![CDATA[Profesional]]></category>
		<category><![CDATA[advernet]]></category>
		<category><![CDATA[comunidad]]></category>
		<category><![CDATA[que]]></category>

		<guid isPermaLink="false">http://www.usuariodeinternet.es/?p=256</guid>
		<description><![CDATA[ Tras un par de meses de desarrollo intenso, y otro par de semanas de rush final demencial (sin los lanzamientos ésto no sería tan divertido), ve la luz, por un lado, el rediseño de la web del Diario QUÉ, y por la parte que nos toca, su estrenada y flamante plataforma de comunidad, Gente [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.usuariodeinternet.es/wp-content/uploads/2008/12/genteque.gif" alt="Gente QUÉ" title="Gente QUÉ" width="200" height="150" style="float: left; margin-right: 10px;" /> Tras un par de meses de desarrollo intenso, y otro par de semanas de rush final demencial (sin los lanzamientos ésto no sería tan divertido), ve la luz, por un lado, el <a title="Web del Diario QUÉ" href="http://www.que.es/" target="_blank">rediseño de la web del Diario QUÉ</a>, y por la parte que nos toca, su estrenada y flamante plataforma de comunidad, <a alt="La comunidad del QUÉ" title="La comunidad del QUÉ" href="http://gente.que.es" target="_blank"><strong>Gente QUÉ</strong></a>.</p>
<p>En un mercado con muchos medios tradicionales aferrándose a un papel que cada vez huele más a muerto, el QUÉ se lanza en bomba a la piscina con una estrategia innovadora y apostando con fuerza por el <strong>usuario</strong>.</p>
<p>En líneas generales, la primera fase, el core del proyecto, es una <strong>plataforma de single sign-on</strong> que permite al usuario tener su perfil en Gente QUÉ y utilizar dichas credenciales para acceder a cualquiera de los servicios que se integren con la plataforma, de manera que cuando te logueas en uno, la sesión se mantiene durante toda la navegación por el &#8220;ecosistema&#8221; que se está montando alrededor del QUÉ.</p>
<p>Dejando de lado el análisis pseudo-gurú, desde el punto de vista del desarrollo yo destacaría las siguientes funcionalidades:</p>
<ul style="padding-left: 30px;">
<li><strong>ID ÚNICO</strong>. Con la facilidad de uso para el usuario en mente se ha integrado el <a href="http://gente.que.es/login.php">logueo a través de sistemas externos</a>, en concreto, con <strong>Facebook, Windows Live, Yahoo y OpenID</strong>, de manera que una vez autenticado en uno de ellos se puede registrar una cuenta en Gente que quedará ligada a dicho ID, pudiendo a partir de entonces utilizar todos los servicios del QUÉ accediendo a través de tu usuario de Facebook, por ejemplo ¡no más contraseñas desperdigadas por Internet!
<p style="margin-top:10px;">Una de las mayores complicaciones de esta parte era implementarlo de forma que el usuario lo entendiera, que no se mareara cuando de repente se le redirige a una página externa, y que pudiera darse cuenta de los beneficios que tiene esta funcionalidad. Considero que lo hemos conseguido simplificando el proceso al máximo, aunque es verdad que debemos pulirlo en las fases que vendrán.</p>
<p>Lidiar con las APIs de cada servicio ha sido una de cal y otra de arena. Para variar, hacer algo con Windows Live es un picor constante en busca de documentación decente e intentando resolver comportamientos demenciales. El resto chapó. También las hemos utilizado para obtener los contactos de las cuentas e <a href="http://gente.que.es/invitar_contactos.php?men=ok">invitar a nuevos amigos</a>. En breve haré un post explicando con detalle cómo integrar cada uno de ellos.</p>
<div style="text-align: center;margin:10px;"><img width="552" height="81" src="/img/post/gente_contactos.gif" alt="La funcionalidad de importar contactos desde servicios externos" title="La funcionalidad de importar contactos desde servicios externos" /></div>
</li>
<li><strong>LIFESTREAMING</strong>. Tal vez la característica más diferenciadora respecto a iniciativas de otros medios sea ésta de registrar la actividad que generan los usuarios en los servicios integrados en la plataforma. Cuando se llega al punto en que hasta los de <a href="http://robdolin.spaces.live.com/blog/cns!3C8CA60F8F925FEC!3140.entry">Windows Live salen del caparazón</a>, era un paso lógico para el QUÉ, ya que tenían centralizado el login, hacer lo mismo para la <a href="http://gente.que.es/pulso.php">actividad del usuario</a>.
<p style="margin-top:10px;">En gran parte relacionada con esta funcionalidad está la de <strong>comunidad</strong>, con la posibilidad de seguir a usuarios y por lo tanto, su actividad. En esta primera fase las relaciones quedan limitadas a ésto, pero habrá muchas novedades en este sentido en breve.</p>
<div style="text-align: center;margin:10px;"><img width="552" height="81" src="/img/post/gente_actividad.gif" alt="La actividad del usuario en Gente QUÉ" title="La actividad del usuario en Gente QUÉ" /></div>
</li>
<li><strong>BARRA DE USUARIO</strong>. Los servicios que se integran con Gente QUÉ debían tener alguna <em>marca</em> que así los identificara, y también con la necesidad de ofrecer un acceso rápido a las funcionalidades de la plataforma, se desarrolló esta barra <em>inspirada</em> en la de Facebook. Ahora mismo ofrece simplemente eso, accesos directos, pero es una de las partes del proyecto que más añadidos y atención va a recibir en los próximos meses, estoy seguro. Podéis verla por ejemplo desde la misma <a href="http://www.que.es">portada del QUÉ</a>.
<p style="margin-top:10px;">Para nosotros el mayor reto fue implementar todo el tinglado con <strong>javascript</strong>, con pequeñas pijaditas como los tooltip informativos y grandes brownies como controlar si hay una sesión iniciada en Gente QUÉ desde servicios externos o idear una forma de sincronizar dicha sesión con la local, pero vamos, esto es material para otro post.</p>
<div style="text-align: center;margin:10px;"><img width="552" height="81" src="/img/post/gente_barra.png" alt="La barra de usuario de Gente QUÉ" title="La barra de usuario de Gente QUÉ" /></div>
</li>
<li><strong>APIs</strong>. Desde el principio teníamos claro que estábamos haciendo una plataforma de servicio, así que todas las funcionalidades son accesibles a través de APIs propias, de manera que cualquier servicio externo se puede integrar de forma prácticamente transparente con la plataforma de forma sencilla y rápida. Un total de <strong>más de 15 APIs</strong> y 30 páginas de documentación dan fe de lo grande que es este proyecto y la casi total flexibilidad que ofrece para futuras integraciones y cambios.
<div style="text-align: center;margin:10px;"><img height="81" width="552" alt="Diagramas de flujo de las APIs" src="/img/post/gente_apimini.gif" title="Diagramas de flujo de las APIs" /></div>
</li>
</ul>
<p>Para nosotros ha sido un proyecto complicado, pero con el que sobre todo <strong>hemos aprendido mucho</strong>. Cuando te metes en desarrollos de este tipo, tan dinámicos y con programadores de todos los niveles, se descubren enseguida las carencias en la metodología de trabajo que puedas tener. Ahora es cuando nos vamos a plantear implantar cosas de esas que usan los profesionales con carrera (framework, subversion, gestión avanzada de bugs&#8230;), hasta ahora hemos podido pasar sin ellas, pero la cosa se pone seria!</p>
<p class="akst_link"><a href="http://www.usuariodeinternet.es/?p=256&amp;akst_action=share-this"  title="Comparte el artículo en Internet" id="akst_link_256" class="akst_share_link" rel="nofollow">Compártelo</a>
</p><img src="http://feeds.feedburner.com/~r/usuariodeinternet/~4/Rv_sFHpeSKg" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.usuariodeinternet.es/profesional/lanzamiento-de-gente-que/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://www.usuariodeinternet.es/profesional/lanzamiento-de-gente-que</feedburner:origLink></item>
		<item>
		<title>Chunda² / SplurgenShitter</title>
		<link>http://feed.usuariodeinternet.es/~r/usuariodeinternet/~3/_jTGx1iCXmA/chunda-splurgenshitter</link>
		<comments>http://www.usuariodeinternet.es/esparcimiento/chunda-splurgenshitter#comments</comments>
		<pubDate>Thu, 11 Dec 2008 23:12:45 +0000</pubDate>
		<dc:creator>fer</dc:creator>
				<category><![CDATA[Esparcimiento]]></category>
		<category><![CDATA[chunda chunda]]></category>
		<category><![CDATA[musica]]></category>

		<guid isPermaLink="false">http://www.usuariodeinternet.es/?p=202</guid>
		<description><![CDATA[
Compártelo
]]></description>
			<content:encoded><![CDATA[<div style="border: 1px solid #dcdcdc; margin: 15px auto; padding: 7px; background: #ffffff url(/wp-content/themes/Fontella/images/imagesbg.png) repeat-x scroll center bottom; width: 600px;"><object width="600" height="485"><param name="movie" value="http://www.youtube.com/v/X2-gHbSh2AY&#038;ap=%2526fmt%3D18&#038;showsearch=0&#038;rel=0"></param><param name="wmode" value="transparent"></param><embed src="http://www.youtube.com/v/X2-gHbSh2AY&#038;ap=%2526fmt%3D18&#038;showsearch=0&#038;rel=0" type="application/x-shockwave-flash" wmode="transparent" width="600" height="485"></embed></object></div>
<p class="akst_link"><a href="http://www.usuariodeinternet.es/?p=202&amp;akst_action=share-this"  title="Comparte el artículo en Internet" id="akst_link_202" class="akst_share_link" rel="nofollow">Compártelo</a>
</p><img src="http://feeds.feedburner.com/~r/usuariodeinternet/~4/_jTGx1iCXmA" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.usuariodeinternet.es/esparcimiento/chunda-splurgenshitter/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.usuariodeinternet.es/esparcimiento/chunda-splurgenshitter</feedburner:origLink></item>
		<item>
		<title>Error en la codificación con AJAX</title>
		<link>http://feed.usuariodeinternet.es/~r/usuariodeinternet/~3/7Gu12c0tL98/error-en-la-codificacion-con-ajax</link>
		<comments>http://www.usuariodeinternet.es/desarrollo/error-en-la-codificacion-con-ajax#comments</comments>
		<pubDate>Tue, 09 Dec 2008 02:43:05 +0000</pubDate>
		<dc:creator>fer</dc:creator>
				<category><![CDATA[Desarrollo]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://www.usuariodeinternet.es/?p=20</guid>
		<description><![CDATA[
Pelearse con la codificación de los caracteres en una aplicación web es pan nuestro de cada día. En un desarrollo sencillo uno puede olvidarse de ese detalle y dejar el trabajo de cloacas al navegador y el PHP. Pero en el momento en que entran en juego javascript y fuentes externas de datos, es entonces [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: center"><img title="¿Matrix utiliza UTF-8?" src="/img/post/matrix_code.jpg" border="0" alt="¿Matrix utiliza UTF-8?" width="640" height="150" /></p>
<p>Pelearse con la codificación de los caracteres en una aplicación web es pan nuestro de cada día. En un desarrollo sencillo uno puede olvidarse de ese detalle y dejar el trabajo de cloacas al navegador y el PHP. Pero en el momento en que entran en juego <strong>javascript y fuentes externas de datos</strong>, es entonces cuando la posibilidades de <strong>cagarla</strong> se multiplican.</p>
<p>Una de las formas más sencillas de prevenir problemas con la codificación es utilizar siempre <strong>UTF-8</strong> para el desarrollo completo de la aplicación. Ésto incluye la base de datos, una línea al principio de todo script:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #990000;">header</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Content-type: text/html; charset=utf-8'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>También en los HTML:</p>

<div class="wp_syntax"><div class="code"><pre class="html4strict" style="font-family:monospace;"><span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">meta</span> <span style="color: #000066;">http-equiv</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;Content-Type&quot;</span> <span style="color: #000066;">content</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text/html; charset=UTF-8&quot;</span> <span style="color: #66cc66;">/</span>&gt;</span></pre></div></div>

<p>Y por supuesto, que el fichero esté <strong>físicamente</strong> codificado en UTF-8, cosa que cada uno deberá hacer con el editor de código correspondiente (mi experiencia con <a href="http://www.ultraedit.com/">Ultraedit</a> en este sentido es inmejorable).</p>
<p>El horror comienza cuando no has hecho los deberes, y a una aplicación sencilla se le quiere empezar a meter AJAX y datos de diversas fuentes. Por defecto tu tinglado estará utilizando seguramente <strong>ISO 8859-1</strong>, la codificación del alfabeto latino, y éso es lo que va a estar esperando el navegador a no ser que le indiques lo contrario&#8230;</p>
<p style="text-align: center"><img title="Mala codificación de los caracteres" src="/img/post/char_raros.gif" border="0" alt="Mala codificación de los caracteres" width="374" height="169" /></p>
<p>Estos problemas de codificación se pueden deber a múltiples razones, sería imposible cubrirlas todas en un post, así que me centraré en las dos con las que he tenido que lidiar estos días:</p>
<ul style="padding-left:30px;">
<li><strong>API EXTERNA</strong>. Aquí no queda otra, Si la API no ofrece un parámetro para especificar la codificación, va a venir en UTF-8 prácticamente seguro y tocará hacer en el código, por ejemplo en PHP, un <a href="http://es.php.net/utf8-decode" target="_blank">utf8_decode</a> de lo que devuelva.</li>
<li style="margin-top:15px;"><strong>AJAX</strong>. La diversión con la codificación de caracteres cuando entra en juego el javascript puede no llegar a tener límite. Si, para más inri, utilizamos AJAX para comunicar con un script pongamos de PHP, entonces tenemos todos los ingredientes para la empanada de caracteres raros.
<p style="margin-top:10px;">Obviando detalles de bajo nivel como que el objeto XMLHttpRequest que se encarga de esta comunicación utiliza siempre UTF-8, o que dependiendo de si utilizas GET o POST e Internet Explorer o Firefox se usará una codificación u otra, vemos que las combinaciones pueden marear hasta la náusea, así que hay que buscar una solución que funcione independientemente de la codificación origen-destino, el navegador o el protocolo utilizado.</p>
<p>Tras varios intentos, dí con una combinación que parece comerse cualquier barbaridad que se pueda poner en un formulario (una caja de texto que acepte código de programación, textos chinos o búlgaros&#8230; es un reto). El flujo sería el siguiente:</p>
<ol>
<li>Desde el javascript mandamos los datos codificados con la función <a href="http://xkr.us/articles/javascript/encode-compare/"><strong>encodeURIComponent</strong></a> (utilizar otra nos dará problemas con los caracteres <em>&#038;</em> y <em>+</em>), por ejemplo:

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">ajax.<span style="color: #000066;">open</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'get'</span><span style="color: #339933;">,</span><span style="color: #3366CC;">'url_script.php?datos='</span><span style="color: #339933;">+</span>encodeURIComponent<span style="color: #009900;">&#40;</span>datos<span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span><span style="color: #003366; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

</li>
<li>Dependiendo del lenguaje de programación que se utilice en el script que recibe los datos habrá que hacer una decodificación o no de los mismos. PHP automáticamente lo realiza para lo que recibe por GET, como en este ejemplo.</li>
<li>Para devolver la respuesta, con PHP utilizamos <a href="http://es.php.net/manual/es/function.rawurlencode.php"><strong>rawurlencode</strong></a> para codificarla (esta función lo realiza de forma más estricta que <a href="http://es.php.net/manual/es/function.urlencode.php">urlencode</a>). Por ejemplo:

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #b1b100;">echo</span> <span style="color: #990000;">rawurlencode</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$respuesta</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

</li>
<li>Finalmente, de vuelta a javascript, decodificamos la respuesta con <a href="http://www.w3schools.com/jsref/jsref_decodeURIComponent.asp"><strong>decodeURIComponent</strong></a>, y ya tenemos una bonita cadena de caracteres lista para utilizar sin problemas de codificación. Por ejemplo:

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> respuesta <span style="color: #339933;">=</span> ajax.<span style="color: #660066;">responseText</span><span style="color: #339933;">;</span>
div.<span style="color: #660066;">innerHTML</span> <span style="color: #339933;">=</span> decodeURIComponent<span style="color: #009900;">&#40;</span>respuesta<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

</li>
</ol>
</li>
</ul>
<p>En definitiva, <strong>hay que utilizar UTF-8</strong>, hay que dejarle al navegador muy claro que lo estamos haciendo, y tenemos que usar una serie de métodos para que en el trasiego de la información entre distintos lenguajes y scripts no se pierda la codificación.</p>
<p class="akst_link"><a href="http://www.usuariodeinternet.es/?p=20&amp;akst_action=share-this"  title="Comparte el artículo en Internet" id="akst_link_20" class="akst_share_link" rel="nofollow">Compártelo</a>
</p><img src="http://feeds.feedburner.com/~r/usuariodeinternet/~4/7Gu12c0tL98" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.usuariodeinternet.es/desarrollo/error-en-la-codificacion-con-ajax/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://www.usuariodeinternet.es/desarrollo/error-en-la-codificacion-con-ajax</feedburner:origLink></item>
		<item>
		<title>Advernet Somos Todos</title>
		<link>http://feed.usuariodeinternet.es/~r/usuariodeinternet/~3/zcGyxLuUHAU/advernet-somos-todos</link>
		<comments>http://www.usuariodeinternet.es/profesional/advernet-somos-todos#comments</comments>
		<pubDate>Wed, 05 Nov 2008 19:35:55 +0000</pubDate>
		<dc:creator>fer</dc:creator>
				<category><![CDATA[Profesional]]></category>
		<category><![CDATA[advernet]]></category>
		<category><![CDATA[oficina]]></category>

		<guid isPermaLink="false">http://www.usuariodeinternet.es/?p=192</guid>
		<description><![CDATA[Una pequeña muestra de contenido propio grabado en nuestras oficinas :D

Compártelo
]]></description>
			<content:encoded><![CDATA[<p style="text-align:center;font-size:12px;">Una pequeña muestra de contenido propio grabado en nuestras oficinas :D</p>
<div style="border: 1px solid #dcdcdc; margin: 15px auto; padding: 7px; background: #ffffff url(/wp-content/themes/Fontella/images/imagesbg.png) repeat-x scroll center bottom; width: 600px;"><object width="600" height="452"><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=1824535&amp;server=vimeo.com&amp;show_title=0&amp;show_byline=0&amp;show_portrait=0&amp;color=00adef&amp;fullscreen=1" /><embed src="http://vimeo.com/moogaloop.swf?clip_id=1824535&amp;server=vimeo.com&amp;show_title=0&amp;show_byline=0&amp;show_portrait=0&amp;color=00adef&amp;fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="600" height="452"></embed></object></div>
<p class="akst_link"><a href="http://www.usuariodeinternet.es/?p=192&amp;akst_action=share-this"  title="Comparte el artículo en Internet" id="akst_link_192" class="akst_share_link" rel="nofollow">Compártelo</a>
</p><img src="http://feeds.feedburner.com/~r/usuariodeinternet/~4/zcGyxLuUHAU" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.usuariodeinternet.es/profesional/advernet-somos-todos/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://www.usuariodeinternet.es/profesional/advernet-somos-todos</feedburner:origLink></item>
	</channel>
</rss>
