<?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>Usuario de Internet &#187; php</title>
	<atom:link href="http://www.usuariodeinternet.es/tag/php/feed" rel="self" type="application/rss+xml" />
	<link>http://www.usuariodeinternet.es</link>
	<description>Experiencias técnicas y lúdicas</description>
	<lastBuildDate>Sun, 02 Oct 2011 02:09:16 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Script Caza Unfollowers de Twitter</title>
		<link>http://www.usuariodeinternet.es/desarrollo/twitter-unfollowers</link>
		<comments>http://www.usuariodeinternet.es/desarrollo/twitter-unfollowers#comments</comments>
		<pubDate>Wed, 16 Mar 2011 09:00:30 +0000</pubDate>
		<dc:creator>fer</dc:creator>
				<category><![CDATA[Desarrollo]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[twitter]]></category>

		<guid isPermaLink="false">http://www.usuariodeinternet.es/?p=831</guid>
		<description><![CDATA[Las reacciones ante un unfollow en Twitter suelen ser diversas, desde la acción recíproca inmediata (cosa que no logro entender ¿has dejado de ver el telediario porque el presentador no se dirija a ti en persona? pues eso&#8230;) hasta la más absoluta indeferencia. A mi más bien me mueve la curiosidad, saber si ha sido [...]]]></description>
			<content:encoded><![CDATA[<p>Las reacciones ante un unfollow en Twitter suelen ser diversas, desde la acción recíproca inmediata (cosa que no logro entender ¿has dejado de ver el telediario porque el presentador no se dirija a ti en persona? pues eso&#8230;) hasta la más absoluta indeferencia. A mi más bien me mueve la curiosidad, saber si ha sido la posible reacción ante un tuit concreto, el perfil de la persona que deja de seguirme, etc&#8230;</p>
<p>Aquí os traigo un pequeño script que he hecho para enterarme de esto. Sé que hay por ahi muchos servicios que hacen lo mismo, los he probado y todos me han parecido una chusta, publicidad, desfase en la notificación y en general nada que cumpla bien algo tan simple como esto. Por eso he acabado tirando unas líneas de código para tenerlo en mi propio servidor y hacer exáctamente lo que espero, que es muy sencillo: <strong>recibir un email cada vez que alguien deje de seguirme en Twitter</strong>. A continuación explico algunos detalles de esta mini aplicación que podéis descargar desde <a href="https://github.com/ferjgar/twitter-unfollowers">github</a>.</p>
<p style="text-align: center;"><img src="http://www.usuariodeinternet.es/img/post/twitter-unfollowers.jpg" alt="Esos que te hacen unfollow en Twitter..." /></p>
<p><span id="more-831"></span><br />
Lo primero aclarar que obviamente no es una aplicación de uso general, por las siguientes peculiaridades:</p>
<ul style="margin-left: 30px;">
<li>Aunque fácilmente modificable, hace únicamente lo que yo necesito, explicado al principio</li>
<li>Está limitada a 5000 followers (por defecto el límite de la API de Twitter si no se utiliza paginación), cuando sobrepase esa cifra ya lo modificaré ;)</li>
<li>Utiliza un fichero para almacenar los followers y arrays para comparar, lo cual con un número elevado de ellos no sé cómo rendirá</li>
</ul>
<p>Al turronaco. El único requerimiento es la extensión <strong>curl</strong> de PHP, que se utiliza para llamar a las APIs de Twitter. La gestión de errores es como un martillo, si no hay curl o alguna API devuelve un error el script termina, no necesito nada más sofisticado.</p>
<p>La única personalización necesaria está en el fichero <span class="codigo">twitter_unfollowers.php</span>, para los campos del email que recibiremos:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>11
12
13
14
15
16
17
18
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// fichero donde se guardan los followers para posteriormente compararlos con los actuales</span>
<span style="color: #990000;">define</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'FIC_GUARDADO'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'twitter_followers_{USUARIO}.db'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">// poner a 0 si no quieres recibir un email con la lista de unfollowers</span>
<span style="color: #990000;">define</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'ENVIAR_EMAIL'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'1'</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;">'EMAIL_DIRECCION'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'xxxx@yyyy.com'</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;">'EMAIL_ASUNTO'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'[TWITTER] Te ha(n) desfollogüeado {NUM} usuario(s)'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">// dirección válida en el servidor donde se ejecuta el script para que el email no se vaya al spam</span>
<span style="color: #990000;">define</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'EMAIL_REMITENTE'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'iiii@jjjj.com'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>Podemos utilizar esta clase en un simple script que se pondría en el <a href="http://es.wikipedia.org/wiki/Cron_%28Unix%29">cron</a>, como por ejemplo:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
</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;">'twitter_unfollowers.php'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #000088;">$tuiter</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Twitter_unfollowers<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'&lt;id_usuario_twitter&gt;'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #000088;">$tuiter</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">check_unfollow</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">'fin'</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></td></tr></table></div>

<div class="descarga">
<a href="https://github.com/ferjgar/twitter-unfollowers">descargar en <strong>github</strong></a></p>
<p>Twitter Unfollowers [v1.2]</p>
</div>
<p class="relacionados">Changelog</p>
<blockquote><p>v1.0 &#8211; Desarrollo inicial<br />
v1.1 &#8211; Eliminada la necesidad de autenticarse con OAuth para utilizar las APIs<br />
v1.2 &#8211; Arreglados problemas de codificación y control de errores de la API</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://www.usuariodeinternet.es/desarrollo/twitter-unfollowers/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Internacionalización con Smarty</title>
		<link>http://www.usuariodeinternet.es/desarrollo/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 [...]
Entradas relacionadas:<ol>
<li><a href='http://www.usuariodeinternet.es/desarrollo/error-en-la-codificacion-con-ajax' rel='bookmark' title='Error en la codificación con AJAX'>Error en la codificación con AJAX</a></li>
<li><a href='http://www.usuariodeinternet.es/desarrollo/scroll-infinito-con-jquery' rel='bookmark' title='Scroll infinito con jQuery'>Scroll infinito con jQuery</a></li>
</ol>]]></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>Entradas relacionadas:<ol>
<li><a href='http://www.usuariodeinternet.es/desarrollo/error-en-la-codificacion-con-ajax' rel='bookmark' title='Error en la codificación con AJAX'>Error en la codificación con AJAX</a></li>
<li><a href='http://www.usuariodeinternet.es/desarrollo/scroll-infinito-con-jquery' rel='bookmark' title='Scroll infinito con jQuery'>Scroll infinito con jQuery</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.usuariodeinternet.es/desarrollo/internacionalizacion-con-smarty/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

