<?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>Berriart &#187; Tutoriales</title>
	<atom:link href="http://www.berriart.com/category/tutoriales/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.berriart.com</link>
	<description>Un programador hablando de diseño............</description>
	<lastBuildDate>Fri, 27 Jan 2012 08:53:46 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Instalar Pootle en Ubuntu</title>
		<link>http://www.berriart.com/2011/07/08/instalar-pootle-en-ubuntu/</link>
		<comments>http://www.berriart.com/2011/07/08/instalar-pootle-en-ubuntu/#comments</comments>
		<pubDate>Thu, 07 Jul 2011 23:04:47 +0000</pubDate>
		<dc:creator>artberri</dc:creator>
				<category><![CDATA[Aplicaciones web]]></category>
		<category><![CDATA[Desarrollo web]]></category>
		<category><![CDATA[Recursos]]></category>
		<category><![CDATA[Tutoriales]]></category>
		<category><![CDATA[gettext]]></category>
		<category><![CDATA[po]]></category>
		<category><![CDATA[pootle]]></category>
		<category><![CDATA[software libre]]></category>
		<category><![CDATA[traducciones]]></category>
		<category><![CDATA[Ubuntu]]></category>

		<guid isPermaLink="false">http://www.berriart.com/?p=810</guid>
		<description><![CDATA[El otro día un tuit de @hello_google me volvió a recordar que, como él, yo también tenía que buscar una herramienta online que nos permita editar ficheros .PO de forma colaborativa. Como la mayoría ya sabréis son ficheros de traducciones que se usan en muchos proyectos de software, y a veces traen de cabeza a [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.berriart.com/wp-content/uploads/2011/07/74359.jpg"><img src="http://www.berriart.com/wp-content/uploads/2011/07/74359-150x150.jpg" alt="" title="International Flags" width="150" height="150" class="alignleft size-thumbnail wp-image-813" /></a>El otro día un <a href="http://twitter.com/#!/hello_google/status/83496250917404672">tuit de @hello_google</a> me volvió a recordar que, como él, yo también tenía que buscar una herramienta online que nos permita editar <a href="http://es.wikipedia.org/wiki/Gettext">ficheros .PO</a> de forma colaborativa. Como la mayoría ya sabréis son ficheros de traducciones que se usan en muchos proyectos de software, y a veces traen de cabeza a desarrolladores y traductores. </p>
<p>La verdad es que una herramienta que nos permita manejar estos ficheros de forma colaborativa y utilizando una interfaz web medianamente intuitiva y fácil de usar era algo que llevaba tiempo necesitando pero que <em>entre pitos y flautas</em> no tenía tiempo de buscar. Conocía la existencia de <a href="https://launchpad.net/">Launchpad</a>, pero yo pensaba que era sólo para proyectos de software libre por lo que para proyectos cerrados no me valía (ahora me he dado cuenta de que también tiene servicio de pago, aún así siempre prefiero una alternativa open source y que pueda instalar en mis propios servidores). La cuestión, es que sin quererlo, he encontrado la solución cuando hacía otra consulta en <a href="http://codex.wordpress.org/Translating_WordPress">la página sobre traducciones de WordPress</a>.</p>
<p>Como habréis podido adivinar por el título de este post la solución que he encontrado se llama <a href="http://translate.sourceforge.net/wiki/pootle/">Pootle</a> (<strong>PO</strong>-based <strong>O</strong>nline <strong>T</strong>ranslation / <strong>L</strong>ocalization <strong>E</strong>ngine) y también es válido para otros tipos de archivo de traducción como pueden ser los XLIFF. Podéis ver <a href="http://pootle.locamotion.org/">en este enlace</a> un versión live de esta aplicación si queréis ver un poco mejor de que se trata, pero si queréis <em>cacharrear</em> un poco más podéis instalarlo directamente en Ubuntu que es bastante sencillito (en otras distribuciones o SO os buscáis la vida :p ). Como casi siempre, hay paquete:</p>
<p><code>sudo apt-get install pootle</code></p>
<p>Yo lo he configurado para que use <em>mysql</em> en vez de <em>sqlite3</em> editando el fichero <em>localsettings.py</em>. Si tú también lo vas a hacer, deberás instalar primero el paquete <em>python-mysqldb</em>,  crear una BD para ello, y modificar estos datos en el fichero de configuración (hay otros datos que también puedes modificar ahí, como por ejemplo configurarlo para usar memcached):</p>
<p><code>sudo apt-get install python-mysqldb<br />
gedit /etc/pootle/localsettings.py</code></p>
<p>Una vez que tengas todo listo y configurado solo tienes que hacer correr el servidor de Pootle:</p>
<p><code>sudo PootleServer</code></p>
<p>Esto lo hará correr por el puerto 8080, si ya tienes algo ahí o prefieres usar otro puerto solo tienes que indicárselo:</p>
<p><code>sudo PootleServer --port=XXXX</code></p>
<p>Finalmente, si todo ha ido bien tendrás tu servidor montado. Sino has hecho alguna otra configuración, puedes acceder a él accediendo a la URL: <code>http://127.0.0.1:8080/</code>. Si has seguido estos mismos pasos puedes loguearte con el usuario <em>admin</em> password <em>admin</em> y empezar a toquetear y cambiar configuraciones (cambia también el pass ). Ya os contaré algunas impresiones si finalmente lo implantamos para algún proyecto.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.berriart.com/2011/07/08/instalar-pootle-en-ubuntu/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Integrar Zend Framework en Symfony</title>
		<link>http://www.berriart.com/2011/04/12/integrar-zend-framework-symfony/</link>
		<comments>http://www.berriart.com/2011/04/12/integrar-zend-framework-symfony/#comments</comments>
		<pubDate>Tue, 12 Apr 2011 08:26:53 +0000</pubDate>
		<dc:creator>artberri</dc:creator>
				<category><![CDATA[Desarrollo web]]></category>
		<category><![CDATA[Programación]]></category>
		<category><![CDATA[Symfony]]></category>
		<category><![CDATA[Tutoriales]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[integración]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[Zend]]></category>

		<guid isPermaLink="false">http://www.berriart.com/?p=703</guid>
		<description><![CDATA[No, no me he vuelto loco, y os aseguro que no es nada tan raro. Es algo que Fabien Potencier creador de Symfony o Matthew Weier O’Phinney y Stefan Koopmanschap responsables del Framework Zend han sugerido en varias ocasiones. Los que usamos Symfony no tenemos porque volvernos locos para usar Lucene, la API de Google [...]]]></description>
			<content:encoded><![CDATA[<p>No, no me he vuelto loco, y os aseguro que no es nada tan raro. Es algo que <a href="http://fabien.potencier.org/">Fabien Potencier</a> creador de Symfony o <a href="http://weierophinney.net/matthew/">Matthew Weier O’Phinney</a> y <a href="http://www.stefankoopmanschap.com">Stefan Koopmanschap</a> responsables del Framework Zend han sugerido en varias ocasiones.</p>
<p>Los que usamos Symfony no tenemos porque volvernos locos para usar Lucene, la API de Google GData, manejar PDFs, recoger feeds o tantas otras funcionalidades que cubre tan bien el Framework Zend. No, porque integrar Zend en Symfony viene a ser bastante sencillo:</p>
<h3>Añadir la librería Zend a nuestro código</h3>
<p>Debemos descargar el <a href="http://framework.zend.com/download/current/">Framework Zend</a> y copiarlo en <em>lib/vendor</em>, que es el directorio donde guardamos habitualmente las librerías externas. Ahí lo meteremos todo dentro de una carpeta nueva que llamaremos Zend.</p>
<h3>Sistema para cargar Zend cuando lo necesitemos</h3>
<p>Para esto lo que vamos a hacer es crear un método nuevo en la clase <em>config/ProjectConfiguration.class.php</em> que nos permita cargar Zend fácilemente desde cualquier parte:</p>
<pre name="code" class="php">
class ProjectConfiguration extends sfApplicationConfiguration

  static protected $zendAutoloader = false;

  /** ............ **/

  /**
   * Agrega el framework Zend a nuestra App
   */
  static public function registerZend()
  {
    if(!self::$zendAutoloader)
    {
      set_include_path(implode(
        PATH_SEPARATOR,
        array(sfConfig::get('sf_lib_dir') . '/vendor', get_include_path())
      ));
      require_once 'Zend/Loader/Autoloader.php';
      self::$zendAutoloader = Zend_Loader_Autoloader::getInstance();
    }

    return self::$zendAutoloader;
  }
}
</pre>
<h3>Empezamos a usarlo</h3>
<p>Una vez hecho todo esto podríamos tranquilamente en un <em>action</em> o en algún <em>task</em> hacer uso del framework Zend. Por ejemplo&#8230;</p>
<pre name="code" class="php">
// Cargamos el framework Zend
ProjectConfiguration::registerZend();

// Utilizamos Zend....
try {
  $feed = Zend_Feed_Reader::import($parameters['feed']);
} catch (Zend_Feed_Exception $e) {
  /** ........ **/
}
</pre>
<p>Como podéis ver eso es todo <img src='http://www.berriart.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' />  A continuación os pongo las diapos que pasó la gente de Symfony y Zend en las conferencias explicando la utilidad de integrarlos y donde explican como hacerlo que es de donde he sacado yo la info:</p>
<ul>
<li><a href="http://fabien.potencier.org/talk/27/symfony-and-zend-framework-together-2009">Using Zend Framework and Symfony Together (Zend PHP Conference 2009)</a></li>
<li><a href="http://www.slideshare.net/weierophinney/using-zend-framework-with-symfony">Using Zend Framework with Symfony (sfLive 2010)</a></li>
<li><a href="http://www.slideshare.net/skoop/integrating-symfony-and">Integrating symfony and Zend Framework (IPC 2010)</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.berriart.com/2011/04/12/integrar-zend-framework-symfony/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Configurar Postfix para el reenvio de emails</title>
		<link>http://www.berriart.com/2011/03/30/configurar-postfix-para-el-reenvio-de-emails/</link>
		<comments>http://www.berriart.com/2011/03/30/configurar-postfix-para-el-reenvio-de-emails/#comments</comments>
		<pubDate>Wed, 30 Mar 2011 12:25:53 +0000</pubDate>
		<dc:creator>artberri</dc:creator>
				<category><![CDATA[Desarrollo web]]></category>
		<category><![CDATA[Tutoriales]]></category>
		<category><![CDATA[email]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[mail]]></category>
		<category><![CDATA[postfix]]></category>
		<category><![CDATA[reenvio]]></category>
		<category><![CDATA[Ubuntu]]></category>

		<guid isPermaLink="false">http://www.berriart.com/?p=682</guid>
		<description><![CDATA[Antes de nada comentar que &#8216;los sistemas&#8217; han sido siempre una de mis asignaturas pendientes, como se suele decir, en esta vida no se puede saber de todo. Esto lo comento para avisaros de que puede que lo que os cuento no sea 100% correcto, pero también sirve para que si algun SysAdmin comprensivo lee [...]]]></description>
			<content:encoded><![CDATA[<p>Antes de nada comentar que &#8216;los sistemas&#8217; han sido siempre una de mis asignaturas pendientes, como se suele decir, en esta vida no se puede saber de todo. Esto lo comento para avisaros de que puede que lo que os cuento no sea 100% correcto, pero también sirve para que si algun SysAdmin comprensivo lee esto y está mal me lo diga. Lo que sí puedo decir es que a mi me ha funcionado.</p>
<p>Por lo general, cuando estoy con un proyecto que necesita un servicio de email suelo recomendar e instalar <a href="http://www.google.com/apps/intl/en/business/index.html">Google Apps for Business</a>. Me parece que dan un buen servicio y se puede dar de alta facilmente simplemente teniendo el control de los DNS del dominio. Pero a veces, como en este caso, <strong>lo que busco es</strong> simplemente <strong>que el email <em>loquesea@midominio.com</em> sea reenviado a <em>example@gmail.com</em></strong>.</p>
<p>En este ejemplo hablamos de configurarlo en un servidor con Ubuntu y con postfix instalado. Si tienes otra distribución me temo que tendrás que ver por ti mismo como hacerlo de manera equivalente y si tienes Ubuntu pero no tienes postfix instalado lo puedes instalar haciendo simplemente:<br />
<code>sudo apt-get install postfix</code></p>
<p>Antes de nada haz una copia del fichero de configuración que vamos a modificar por si acaso:<br />
<code>sudo cp /etc/postfix/main.cf /etc/postfix/main.cf.bkp</code></p>
<p>Luego edita ese fichero y agrega las siguientes líneas (o modificalas si ya tienes esas variables definidas):<br />
<code>virtual_alias_domains = midominio.com</code><br />
<code>virtual_alias_maps = hash:/etc/postfix/virtual</code><br />
<em>(Asegurate de que el dominio que agregas como alias no se encuentre en ese mismo fichero en la variable <em>mydestination</em></em>)</p>
<p>La variable <em>virtual_alias_domains</em> indica en este caso los dominios de los que aceptamos recibir emails para luego reenviarlos, por eso añadimos el dominio del email que queremos reenviar. Por otro las <em>virtual_alias_maps</em> indica el fichero que contiene los alias que vamos a crear para poder reenviar los emails. El fichero está en <em>/etc/postfix/virtual</em> y en nuestro ejemplo debería contener:<br />
<code>loquesea@midominio.com        example@gmail.com</code><br />
<code>fulano@midominio.com            otherexample@gmail.com</code><br />
<code># Uncomment entry below to implement a catch-all address</code><br />
<code># @midominio.com                 example@gmail.com</code></p>
<p>Como se puede apreciar primero se debe escribir el alias y después el email al que quieres reenviar; una línea por cada reenvio que queramos configurar. Como se puede apreciar también se puede configurar para tener un <em>catch-all</em>.</p>
<p>Finalmente y para que los cambios que hemos hecho surjan efecto debemos recargar los aliases y reiniciar o recargar el servidor de postfix:<br />
<code>postmap /etc/postfix/virtual</code><br />
<code>postfix reload</code></p>
<p>Creo que eso es todo, si véis que falta algo decídmelo en los comentarios.</p>
<p>Hay más información en el propio <a href="http://www.postfix.org/VIRTUAL_README.html">README de Postfix</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.berriart.com/2011/03/30/configurar-postfix-para-el-reenvio-de-emails/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Cómo usar los Namespaces en PHP 5.3</title>
		<link>http://www.berriart.com/2011/02/15/como-usar-los-namespaces-en-php-5-3/</link>
		<comments>http://www.berriart.com/2011/02/15/como-usar-los-namespaces-en-php-5-3/#comments</comments>
		<pubDate>Tue, 15 Feb 2011 09:44:30 +0000</pubDate>
		<dc:creator>artberri</dc:creator>
				<category><![CDATA[Desarrollo web]]></category>
		<category><![CDATA[Programación]]></category>
		<category><![CDATA[Tutoriales]]></category>
		<category><![CDATA[how to]]></category>
		<category><![CDATA[namespace]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[php 5.3]]></category>

		<guid isPermaLink="false">http://www.berriart.com/?p=596</guid>
		<description><![CDATA[Una de las nuevas incorporaciones y de los cambios más significativos de PHP 5.3 son los Namespaces, nada nuevo para todos aquellos que hayan programado C# o Java, pero un cambio que mejorará la estructura de nuestros programas y que empezaremos a ver sobre todo en todos los grandes Frameworks (las nuevas versiones de Zend [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.berriart.com/wp-content/uploads/2011/02/php531-150x150.jpg" alt="php 5.3" title="php 5.3" width="150" height="150" class="alignleft size-thumbnail wp-image-646" />Una de las nuevas incorporaciones y de los cambios más significativos de PHP 5.3 son los Namespaces, nada nuevo para todos aquellos que hayan programado C# o Java, pero un cambio que mejorará la estructura de nuestros programas y que empezaremos a ver sobre todo en todos los grandes Frameworks (las nuevas versiones de Zend Framework, CakePHP, Doctrine y Symfony entre otros requerirán PHP 5.3).</p>
<h3>¿Porqué necesitamos los Namespaces?</h3>
<p>Según va aumentando el número de librerías escritas en PHP se hace mayor el riesgo de colisión de nombres de clases y funciones entre librerías. En un principio sería totalmente comprensible que diferentes programas implementen por ejemplo una clase llamada <em>Photo</em> que maneje las imágenes en el proyecto, pero eso hasta la llegada de PHP 5.3 estaba mal visto porque había que intentar evitar tener problemas de compatibilidad con otros proyectos. Por eso mismo era más probable que esa clase se llamara por ejemplo  <em>Mi_Proyecto_Photo</em>. </p>
<p>Ejemplos de este tipo se pueden ver por ejemplo en WordPress dónde todas las clases empiezan por <em>WP_</em> o en el framework Zend, donde la política de nombres (muy descriptiva) hace que se le asignen nombres a veces demasiado largos a las funciones: Z<em>end_Search_Lucene_Analysis_Analyzer_Common_Text_CaseInsensitive</em>.</p>
<p>Los Namespaces resuelven este problema porque las constantes, clases y funciones pueden quedar definidas dentro de su Namespace, sin entrar en conflicto con otros homónimos que estén dentro de otros namespaces.</p>
<h3>¿Cómo se definen los Namespaces?</h3>
<p>Por defecto, y si no se indica lo contrario, todas las funciones, clases y constantes quedarán definidas en el entorno global, como ha sido siempre en PHP. Será lo que pase con todas las librerías que carguemos y que no estén realizadas específicamente para PHP 5.3 o superior, y que por lo tanto no tendrán definido su namespace.</p>
<p>Pero si vamos a correr nuestro programa sobre PHP 5.3 o superior debemos empezar a definir los namespaces en nuestros programas y para ello simplemente hay que hacerlo utilizando la palabra clave <em>namespace</em> seguido del nombre al inicio de nuestro script; siempre debe ser la primera instrucción del fichero sin tener ningún otro código delante, ni espacios, ni HTML (excepto <em>declare</em>):</p>
<pre name="code" class="php">// Definición del namespace para el código de este script
namespace MiProyecto;
// A partir de aquí escribe tu código y domina el mundo </pre>
<p>Lo lógico y lo recomendado es que utilices un fichero por cada namespace que definas, pero si por alguna extraña razón quisieras hacerlo varias veces en el mismo podrías de la siguiente manera:</p>
<pre name="code" class="php">// Definición del namespace para el proyecto 1
namespace MiProyecto1;
// Código del Proyecto1
// Definición del namespace para el proyecto 2
namespace MiProyecto2;
// Código del Proyecto2
// Definición del namespace para el proyecto 3 con la sintaxis alternativa
namespace MiProyecto3 {
    // Código del Proyecto3
}</pre>
<h4>Sub-namespaces:</h4>
<p>También podemos definir sub-namespaces para tener mejor estructurado nuestro código, o lo que es lo mismo, organizar jerarquicamente nuestras librerías o programas. Como separador a la hora de definir los namespaces y sus sub-namespaces utilizaremos la barra invertida: \. Ejemplos:</p>
<ul>
<li>MiProyecto\DB\MySQL</li>
<li>MiProyecto\DB\Mongo</li>
<li>MiProyecto\Contenido\Articulos</li>
<li>OtraCompania\MiProyecto\Plugin\Comentarios</li>
</ul>
<h3>¿Cómo llamar a elementos que se encuentren dentro de un namespace?</h3>
<p>Vamos a tomar como ejemplo la siguiente librería definida bajo el namespace Berriart\Sample y que guardaremos como berriart.sample.php:</p>
<pre name="code" class="php">&lt;?php
// Código de la sección  Sample del proyecto Berriart
namespace Berriart\Sample;
const MYCONST = 'Berriart\Sample\MYCONST';
function MyFunction() {
    return __FUNCTION__;
}
class MyClass {
    static function WhoAmI() {
        return __METHOD__;
    }
}  
</pre>
<p>Ahora podríamos incluir este código desde otro script y ejecutarlo de la siguiente manera:</p>
<pre name="code" class="php">&lt;?php
header('Content-type: text/plain');
require_once('berriart.sample.php');
echo \Berriart\Sample\MYCONST . PHP_EOL;
echo \Berriart\Sample\MyFunction() . PHP_EOL;
echo \Berriart\Sample\MyClass::WhoAmI() . PHP_EOL;
</pre>
<p>En este pequeño script hacemos uso de la función, la clase y la constante definidas en anterior fichero. Como éste no tiene namespace definido se está ejecutando en el entorno global, y por lo tanto para poder hacer uso de los elementos definidos en un namespace determinado los llamamos en este caso haciendo uso de la &#8216;ruta absoluta&#8217; del namespace. El anterior código nos devolbería lo siguiente:</p>
<pre>Berriart\Sample\MYCONST
Berriart\Sample\MyFunction
Berriart\Sample\MyClass::WhoAmI
</pre>
<p>Como os podéis imaginar, utilizar el nombre del namespace completo cada vez que llamamos a una función, clase o constante no nos aporta muchos más beneficios que los largos nombres descriptivos, pero no os preocupéis porque no es la única manera de llamarlos, y a continuación podemos ver todas las maneras de hacerlo. Las diferentes nomenclaturas son similares a las de los sistemas de ficheros:</p>
<h4>Nombre completamente cualificado (Fully-qualified name) (~ruta absoluta)</h4>
<p>Es la manera que hemos visto en el anterior ejemplo y consiste en utilizar el nombre completo del namespace. Para indicar que se trata de un nombre absoluto debemos empezar la llamada con una barra, ej:</p>
<pre name="code" class="php">$variable = \Berriart\Sample\MyClass::WhoAmI();
</pre>
<p>De esta manera no hay lugar a ambigüedades. Da igual si este código se encuentra dentro de algún namespace o en el espacio glogal, al estar escrita &#8216;la ruta completa&#8217; siempre se hará la misma llamada. Pero como se puede apreciar generalmente no sería muy práctico.</p>
<h4>Nombre cualificado (Qualified name) (~ruta relativa)</h4>
<p>Un identificador con al menos un separador de namespace:</p>
<pre name="code" class="php">$variable = Sample\MyClass::WhoAmI();
</pre>
<p>Si el namespace actual fuera <em>Berriart</em>, esto se resolvería con Berriart\Sample\MyClass::WhoAmI(): </p>
<pre name="code" class="php">&lt;?php
namespace Berriart;
header('Content-type: text/plain');
require_once('berriart.sample.php');
echo Sample\MyClass::WhoAmI() . PHP_EOL;

// Devolvería:
// Berriart\Sample\MyClass::WhoAmI
</pre>
<p>Pero si el código es global, esto se resuelve con Sample\MyClass::WhoAmI() que en el caso del ejemplo al no existir devolvería error:</p>
<pre name="code" class="php">&lt;?php
header('Content-type: text/plain');
require_once('berriart.sample.php');
echo Sample\MyClass::WhoAmI() . PHP_EOL;

// Devolvería error:
// Fatal error: Class 'Sample\MyClass' not found in...
</pre>
<h4>Nombre no cualificado (Unqualified name) (~fichero relativo)</h4>
<p>Nombre de clase, constante o función sin hacer referencia a ningún namespace:</p>
<pre name="code" class="php">$variable = MyClass::WhoAmI();
</pre>
<p>Si el código en el que esto se ejecuta es global, no se encuentra en un <em>namespace</em>, esto se resuelve con la clase MyClass que también debería estar definida en el espacio global y no dentro de un namespace. En cambio si la llamásemos dentro de un namespace primero buscaría dentro de ese namespace y luego en el espacio global.</p>
<h3>Importando namespaces</h3>
<p>Los namespaces se pueden importar mediante el comando <em>use</em>. La utilización del comando <em>use</em> no cambia el espacio en el que trabajamos, si estamos en el espacio global seguiremos en él, y si estamos dentro de un namespace porque estamos usando la palabra clave &#8216;namespace&#8217; dentro de nuestro script, también seguiremos en él; pero nos permitirá hacer uso de cosas de otros namespaces haciendo uso del nombre cualificado.</p>
<pre name="code" class="php">&lt;?php
header('Content-type: text/plain');
require_once('berriart.sample.php');

use Berriart\Sample;
echo Sample\MyClass::WhoAmI() . PHP_EOL;

// Devolvería:
// Berriart\Sample\MyClass::WhoAmI
</pre>
<p>Se pueden importar tantos namespaces como se quieran haciendo uso del comando <em>use</em> en repetidas ocasiones o separandolos con comas en la misma instrucción.</p>
<p>Es importante remarcar que en este ejemplo que hemos puesto seguimos en el espacio global por lo que no se podría llamar directamente a MyClass::WhoAmI() (de manera no cualificada) porque buscaría esa clase también en el espacio global.</p>
<h3>Creando <em>Alias</em> para los namespaces</h3>
<p>Los alias son un recurso muy útil para poder acortar los nombres de los namespaces a la hora de hacer nuestras llamadas. Se crean utilizando la palabra clave <em>as</em> junto al comando <em>use</em>:</p>
<pre name="code" class="php">&lt;?php
header('Content-type: text/plain');
require_once('berriart.sample.php');

use Berriart\Sample as BS;
echo BS\MyClass::WhoAmI() . PHP_EOL;

// Devolvería:
// Berriart\Sample\MyClass::WhoAmI
</pre>
<p>Hay que destacar que también se pueden crear alias directamente para las clases (no en cambio para constantes y funciones):</p>
<pre name="code" class="php">&lt;?php
header('Content-type: text/plain');
require_once('berriart.sample.php');

use Berriart\Sample\MyClass as Obj;
echo Obj::WhoAmI() . PHP_EOL;

// Devolvería:
// Berriart\Sample\MyClass::WhoAmI
</pre>
<h3>Reglas de resolución de nombres</h3>
<p>Las llamadas desde la incorporación de los namespaces se resuelven siguiendo estas reglas:</p>
<ol>
<li>Las llamadas a clases, funciones o constantes completamente cualificadas se resuleven en tiempo de compilación. Por ejemplo <em>new \A\B</em> se resuelve con la clase <em>A\B</em>.</li>
<li>Todos los nombres no cualificados y cualificados (no los completamente cualificados) se traducen durante la compilación según las reglas de importación actuales. Por ejemplo, si el espacio de nombres <em>A\B\C</em> se importa como <em>C</em>, una llamada a <em>C\D\e() </em>se traduce a <em>A\B\C\D\e()</em>.</li>
<li>Dentro de un espacio de nombres, todos los nombres cualificados no traducidos según la reglas de importación tienen añadido al inicio el namespace actual. Por ejemplo, si una llamada a <em>C\D\e()</em> se lleva a cabo dentro del namespace <em>A\B</em>, se traduce a <em>A\B\C\D\e()</em>.</li>
<li>Los nombres de clases no cualificados se traducen durante la compilación según las reglas de importación actuales (el nombre completo sustituido por el nombre abreviado importado). Por ejemplo, si el espacio de nombres <em>A\B\C</em> se importa como <em>C</em>, <em>new C()</em> se traduce a new <em>A\B\C()</em>.</li>
<li>Dentro de un espacio de nombres (digamos <em>A\B</em>), las llamdas a funciones no cualificadas se resuelven en tiempo de ejecución. Aquí se muestra cómo se resuelve una llamada a la función <em>foo()</em>:
<ol>
<li>Se busca una función desde el espacio de nombres actual: <em>A\B\foo()</em>.</li>
<li>Se intenta encontrar y llamar a la función global <em>foo()</em>.</li>
</ol>
</li>
<li>Dentro de un namespace (digamos <em>A\B</em>), las llamadas a nombres de clases no cualificados o cualificados (no los completamente cualificados) se resuelven en tiempo de ejecución. Aquí se muestra cómo se resuelve una llamada a <em>new C()</em> o a <em>new D\E()</em>.
<p>Para new <em>C()</em>:</p>
<ol>
<li>Se busca una clase desde el espacio de nombres actual: A\B\C.</li>
<li>Se intenta autocargar A\B\C.</li>
</ol>
<p>      Para new <em>D\E()</em>:</p>
<ol>
<li>Se busca una clase añadiendo al inicio el espacio de nombres actual: A\B\D\E.</li>
<li>Se intenta autocargar A\B\D\E.</li>
</ol>
<p>      Para referenciar cualquier clase global en el espacio de nombres global, se debe usar su nombre completamente cualificado<em> new \C()</em>.
</li>
</ol>
<h3>La constante __NAMESPACE__ y la palabra clave <em>namespace</em></h3>
<p>La constante especial __NAMESPACE__ siempre nos devolverá el namespace actual, en el que nos econtramos. En el caso de estar en el espacio global devolverá una cadena vacia.</p>
<pre name="code" class="php">&lt;?php
namespace Berriart\Sample;
echo __NAMESPACE__; // devuelve: Berriart\Sample
</pre>
<p>Esto tiene una clara aplicación para el debugging, pero también nos sirve para hacer llamadas utilizando el nombre totalmente cualificado:</p>
<pre name="code" class="php">&lt;?php
namespace Berriart\Sample;
class MyClass {
	public function WhoAmI() {
		return __METHOD__;
	}
}
$c = __NAMESPACE__ . '\\MyClass';
$m = new $c;
echo $m->WhoAmI(); // devuelve: Berriart\Sample\MyClass::WhoAmI
</pre>
<p>En el caso de este ejemplo como la clase a la que queremos llamar se encuentra en el mismo namespace en el que nos encontramos también podríamos referirnos a la clase utilizando la palabra clave <em>namespace</em>, que utilizada así sería el equivalente a la palabra clave <em>self</em> dentro de las clases:</p>
<pre name="code" class="php">&lt;?php
namespace Berriart\Sample;
class MyClass {
	public function WhoAmI() {
		return __METHOD__;
	}
}
$m = new namespace\MyClass();
echo $m->WhoAmI(); // devuelve: Berriart\Sample\MyClass::WhoAmI
</pre>
<h3>Autoloading de clases usando Namespaces</h3>
<p>Una de las más importantes funcionalidades de PHP 5 a la hora de ahorrar tiempo es la carga automática. Antes, en un programa que solo hiciera uso del espacio global una posible definición de la función especial __autoload sería: </p>
<pre name="code" class="php">&lt;?php
$obj1 = new MyClass1(); // classes/MyClass1.php is auto-loaded
$obj2 = new MyClass2(); // classes/MyClass2.php is auto-loaded
// autoload function
function __autoload($class_name) {
	require_once("classes/$class_name.php");
}
</pre>
<p>En PHP 5.3, utilizando namespaces, a la función autoload se le pasaría el namespace completo más el nombre de la clase. Por ejemplo, el valor de <em>$class_name</em> podría ser &#8220;Berriart\Sample\MyClass&#8221;. Por lo tanto, aunque podrías seguir metiendo todas las clases en la misma carpeta y crear una regla de nomenclatura, lo lógico sería que la estructura de ficheros de la librería sea relativa a la estructura de los namespaces y que la función __autoload fuera algo así:</p>
<pre name="code" class="php">&lt;?php
function __autoload($class_name) {
	// convert namespace to full file path
	$class_path = 'classes/' . str_replace('\\', '/', $class_name) . '.php';
	require_once($class_path);
}
</pre>
<h3>Webgrafía y créditos</h3>
<p>Para redacactar este artículo practicamente se ha traducido <a href="http://blogs.sitepoint.com/2009/07/13/php-53-namespaces-basics/">este tutorial</a> del inglés, y se ha contrastado y completado con<a href="http://php.net/manual/es/language.namespaces.php"> el manual de PHP sobre namespaces</a>.</p>
<p>Espero que leer esto os haya ayudado a entender mejor los <em>namespaces</em>, con lo que sea ya sabéis, dejad un comentario.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.berriart.com/2011/02/15/como-usar-los-namespaces-en-php-5-3/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Instalar Trac en Ubuntu</title>
		<link>http://www.berriart.com/2010/07/24/instalar-trac-ubuntu/</link>
		<comments>http://www.berriart.com/2010/07/24/instalar-trac-ubuntu/#comments</comments>
		<pubDate>Sat, 24 Jul 2010 12:15:50 +0000</pubDate>
		<dc:creator>artberri</dc:creator>
				<category><![CDATA[Desarrollo web]]></category>
		<category><![CDATA[Recursos]]></category>
		<category><![CDATA[Tutoriales]]></category>
		<category><![CDATA[subversion]]></category>
		<category><![CDATA[svn]]></category>
		<category><![CDATA[trac]]></category>
		<category><![CDATA[Ubuntu]]></category>

		<guid isPermaLink="false">http://www.berriart.com/?p=582</guid>
		<description><![CDATA[Trac es un wiki mejorado y un sistema de &#8216;tickets&#8217; para la gestión de proyectos de software basado en web. Creo que es una de las mejores maneras de mantener un proyecto de software libre, aunque es perfectamente útil para un proyecto &#8216;privado&#8217;. Se integra perfectamente con el sistema de control de versiones Subversion, y [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://trac.edgewall.org/">Trac</a> es un wiki mejorado y un sistema de &#8216;tickets&#8217; para la gestión de proyectos de software basado en web. Creo que es una de las mejores maneras de mantener un proyecto de software libre, aunque es perfectamente útil para un proyecto &#8216;privado&#8217;. Se integra perfectamente con el sistema de control de versiones <a href="http://subversion.tigris.org/">Subversion</a>, y es una manera de tener centralizada toda la documentación de un proyecto teniendo incluso la posibilidad de poder relacionar incidencias con sus respectivos arreglos en el código. Si no lo conoces y quieres ver un ejemplo, puedes acceder al <a href="http://trac.symfony-project.org/">Trac de Symfony</a>, ya que los desarrolladores de este Framework utilizan esta herramienta.</p>
<p>Si tienes un servidor Ubuntu con Apache y quieres instalarlo a continuación te describo los pasos que he seguido yo para hacerlo (recuerda que si no estás como usuario &#8216;root&#8217; tendrás que hacer <em>sudo</em>):</p>
<p>Instalar suvbersion:<br />
<code>apt-get install subversion libapache2-svn</code></p>
<p>Instalar Trac y el módulo de Python para Apache:<br />
<code>apt-get install libapache2-mod-python libapache2-mod-python-doc trac </code></p>
<p>Crear la carpeta que hará de &#8216;Document Root&#8217; para poder acceder al trac via web, por ejemplo:<br />
<code>mkdir /var/www/trac</code></p>
<p>Si lo quieres proteger, como es mi caso, crea un fichero .htpasswd:<br />
<code>htpasswd -c /var/www/trac/.htpasswd admin</code></p>
<p>Preparar el Virtual Host:<br />
<code>vi /etc/apache2/sites-available/trac</code></p>
<p>Y escribir:</p>
<pre>&lt;VirtualHost *&gt;
ServerAdmin mymail@domain.com
ServerName trac.domain.com

&lt;Location /projects&gt; #set up Trac handling
SetHandler mod_python
PythonHandler trac.web.modpython_frontend
PythonOption TracEnvParentDir /var/www/trac
PythonOption TracUriRoot /projects

#authentication scheme
AuthType Basic
AuthName "My Tracker"
AuthUserFile /var/www/trac/.htpasswd
Require valid-user

&lt;/Location&gt;

ErrorLog /var/log/apache2/trac_error.log

# Possible values include: debug, info, notice, warn, error, crit,
# alert, emerg.
LogLevel warn

CustomLog /var/log/apache2/trac_access.log combined

&lt;/VirtualHost&gt;</pre>
<p>Vamos a crear un repositorio SVN para el código:<br />
<code>mkdir /var/lib/svn<br />
mkdir /var/lib/svn/myproject<br />
svnadmin create /var/lib/svn/myproject</code></p>
<p>Yo lo he preparado para poder tener diferentes <em>tracs</em>, así que estos pasos se pueden repetir:<br />
<code>mkdir /var/www/trac/myproject<br />
trac-admin /var/www/trac/myproject initenv<br />
sudo chown -R www-data:www-data /var/www/trac/myproject</code></p>
<p>Finalmente reiniciamos Apache:<br />
<code>/etc/init.d/apache2 restart</code></p>
<p>Y ya podríamos acceder a nuestro trac en este ejemplo en: http://trac.domain.com/projects</p>
<p>Espero que os sirva de ayuda.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.berriart.com/2010/07/24/instalar-trac-ubuntu/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>&#8216;Tunear&#8217; Gedit y convertirlo en un IDE</title>
		<link>http://www.berriart.com/2009/08/28/tunear-gedit-y-convertirlo-en-un-ide/</link>
		<comments>http://www.berriart.com/2009/08/28/tunear-gedit-y-convertirlo-en-un-ide/#comments</comments>
		<pubDate>Fri, 28 Aug 2009 15:02:48 +0000</pubDate>
		<dc:creator>artberri</dc:creator>
				<category><![CDATA[Desarrollo web]]></category>
		<category><![CDATA[Recursos]]></category>
		<category><![CDATA[Tutoriales]]></category>
		<category><![CDATA[editor]]></category>
		<category><![CDATA[gedit]]></category>
		<category><![CDATA[ide]]></category>
		<category><![CDATA[programar]]></category>

		<guid isPermaLink="false">http://www.berriart.com/?p=503</guid>
		<description><![CDATA[No sé si os lo he comentado alguna vez, pero Gedit es mi editor preferido y la herramienta que más utilizo para programar. He probado, e incluso alguna vez utilizo, algun IDE auténtico (según para que) Eclipse, Aptana o NetBeans; pero por lo general mi IDE es Gedit. Algunos dirán que lo que digo es [...]]]></description>
			<content:encoded><![CDATA[<p>No sé si os lo he comentado alguna vez, pero <a href="http://projects.gnome.org/gedit/">Gedit</a> es mi editor preferido y la herramienta que más utilizo para programar. He probado, e incluso alguna vez utilizo, algun IDE <em>auténtico</em> (según para que) Eclipse, Aptana o NetBeans; pero por lo general mi IDE es Gedit.</p>
<p>Algunos dirán que lo que digo es una barbaridad, pero me parece una de las mejores herramientas y sobre todo la más ligera. Porque aunque en un principio parezca que es muy <em>light</em>, si sabemos cómo, podemos personalizarla y convertirla en una gran herramienta. Hace tiempo <a href="http://www.viciao2k3.net/blog/linux/haciendo-gedit-mas-sociable-para-el-programador/">Miquel ya nos dió unos consejitos</a>, pero como se nos ha pasado a Mac, ahora me tengo que buscar la vida :p</p>
<p><strong>Os explico mi configuración y ya me diréis que opináis:</strong></p>
<p>Lo primero es ir a las preferencias <em>(Editar->Preferencias)</em>, y adecuaremos unas cuantas cositas:</p>
<p><u>- Pestaña &#8216;Ver&#8217;:</u></p>
<ul>
<li>Mostrar números de línea</li>
<li>Resaltar línea actual</li>
<li>Resaltar pareja del corchete</li>
</ul>
<p><img src="http://www.berriart.com/wp-content/uploads/2009/08/gedit-preferences-1.png" alt="gedit preferences" title="gedit preferences cap" width="450" height="444" class="aligncenter size-full wp-image-505" /></p>
<p><u>- Pestaña &#8216;Editor&#8217;:</u></p>
<ul>
<li>Insertar 4 espacios en lugar de tabulaciones</li>
<li>Activar sangría automática</li>
<li>Desactivar copia de seguridad, ya que crea archivos con el mismo nombre con el caracter &#8216;~&#8217; al final, que hace que linux los trate como ocultos y que si los subimos al servidor nos traeran graves problemas de seguridad</li>
</ul>
<p><img src="http://www.berriart.com/wp-content/uploads/2009/08/gedit-preferences-2.png" alt="gedit preferences " title="gedit preferences " width="450" height="444" class="aligncenter size-full wp-image-506" /></p>
<p><strong>Los colores</strong> que vienen por defecto para resaltar el código, no me gustan. Yo prefiero el fondo negro, ahorro energia y descanso la vista :p Así que nos vamos a la siguiente pestaña &#8216;Tipografías y colores&#8217;. De los esquemas existentes, tampoco me convencen ninguno, así que lo que hice fue descargarme otro. <a href="http://120linux.com/6-estilos-de-colores-para-gedit/">Aquí podéis descargar colores para Gedit</a>, a mi el esquema que más me gusta y el que uso es el Darkwin. Para instalarlo, descargalo y luego en la pestaña pulsa en el botón &#8216;Añadir&#8217; y agregalo.</p>
<p>Ahora llega el turno de instalar <strong>plugins o complementos</strong> para el Gedit. Por defecto trae algunos preinstalados que solo necesitamos activar desde la cuarta pestaña del panel de preferencias. Activaremos los siguientes:</p>
<ul>
<li>Herramientas externas &#8211; Permite ejecutar comandos o programas externos a Gedit para facilitarnos el trabajo. Más adelante explicaré como configurarlo.</li>
<li>Panel de examinador de Archivos &#8211; Pone a nuestra disposición un panel lateral para examinar y acceder a los archivos de nuestro proyecto (Tecla rápida F9).</li>
<li>Recortes &#8211; Permite insertar &#8216;recortes&#8217; de código, o estructuras muy utilizadas (loops, ifs,&#8230;). Escribe la palabra clave y luego pulsa tabulador, el resto se escribirá solo.</li>
<li>Sangrar líneas &#8211; Permite el sangrado de líneas de manera rápida mediante Ctrl+T.</li>
</ul>
<p>Además de estos, creo que es una buena opción instalar otro plugin más, pero este no viene por defecto, se llama <a href="http://sourceforge.net/projects/symbol-browser/">Symbol Browser</a>. Se trata de un panel lateral que permite la exploración de objetos, funciones, <em>defines</em>,&#8230; </p>
<p><img src="http://www.berriart.com/wp-content/uploads/2009/08/screenshot.jpg" alt="Symbol Browser" title="Symbol Browser" width="400" height="419" class="aligncenter size-full wp-image-512" /></p>
<p>Yo os explico como le he instalado en Ubuntu 9.04, pero si necesitáis más información <a href="http://www.micahcarrick.com/11-14-2007/gedit-symbol-browser-plugin.html">podéis ver este artículo</a> que fue como lo descubrí. Lo primero que hay que hacer es instalar Exuberant Ctags, que es la herramienta ne la que se basa este plugin, luego descargamos el plugin y lo instalamos. No olvides después de instalarlo activarlo en la pestaña &#8216;Complementos&#8217; como hemos hecho con los anteriores.</p>
<pre>sudo apt-get install ctags
cd ~/.gnome2/gedit/
wget http://sourceforge.net/projects/symbol-browser/files/symbol-browser-bin/gedit-symbol-browser-plugin-bin-ubuntu-i386-0.1/gedit-symbol-browser-plugin-bin-ubuntu-i386-0.1.tar.gz/download #La URL puede cambiar al cambiar de versión
tar -xzf gedit-symbol-browser-plugin-bin-ubuntu-i386-0.1.tar.gz
</pre>
<p>Eso sería todo. Bueno, más bien casi todo. Por último habría que configurar el plugin &#8216;Herramientas externas&#8217; para poder realizar diferentes tareas, como comprobar la syntaxis de nuestro código, consultar la documentación de PHP, &#8216;standarizar&#8217; nuestro código con el programa PHP-Beautifer,&#8230; Para ver como hacerlo creo que lo mejor es que os paséis por la web de la que he recogido la mayor parte de la info que he puesto en este post, ya que mejor que él seguro que no lo explico: <a href="http://www.micahcarrick.com/09-29-2007/gedit-html-editor.html">Micah Carrick</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.berriart.com/2009/08/28/tunear-gedit-y-convertirlo-en-un-ide/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Hook al activar o desacivar un plugin de WordPress</title>
		<link>http://www.berriart.com/2009/05/06/hook-activar-desactivar-plugin/</link>
		<comments>http://www.berriart.com/2009/05/06/hook-activar-desactivar-plugin/#comments</comments>
		<pubDate>Tue, 05 May 2009 22:49:47 +0000</pubDate>
		<dc:creator>artberri</dc:creator>
				<category><![CDATA[Desarrollo web]]></category>
		<category><![CDATA[Plugins]]></category>
		<category><![CDATA[Tutoriales]]></category>
		<category><![CDATA[Web 2.0]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[activar]]></category>
		<category><![CDATA[funciones]]></category>
		<category><![CDATA[plugins de wordpress]]></category>

		<guid isPermaLink="false">http://www.berriart.com/?p=473</guid>
		<description><![CDATA[Si eres desarrollador de plugins de WordPress, te habrá pasado alguna vez que has querido que se ejecute alguna acción cuando un usuario instala uno de tus plugins o cuando lo desinstala. Un ejemplo claro es que tu plugin necesite una tabla de base de datos adicional, y necesite que ésta se cree al activar [...]]]></description>
			<content:encoded><![CDATA[<p>Si eres desarrollador de plugins de WordPress, te habrá pasado alguna vez que has querido que se ejecute alguna acción cuando un usuario instala uno de tus plugins o cuando lo desinstala. Un ejemplo claro es que tu plugin necesite una tabla de base de datos adicional, y necesite que ésta se cree al activar el plugin. Al igual que al desinstalar el plugin podría ser que esa tabla ya no sirva y quieras que se borre.</p>
<p>Para ello WordPress nos ofrece dos funciones que nos permitirán que se ejecute algo al activar o desactivar un plugin, estas funciones son <em>register_activation_hook</em> y <em>register_deactivation_hook</em>. Se puede ver su modo de empleo en las siguientes líneas de código que simulan la situación que he expuesto antes:</p>
<pre name="code" class="php">&lt;?php

register_activation_hook( __FILE__, 'plugin_name_activate' );
register_deactivation_hook( __FILE__, 'plugin_name_deactivate' );

function plugin_name_activate() {
	global $wpdb;
	$sql = 'CREATE TABLE `' . $wpdb->prefix . 'plugin_name`
		( `id` INT( 11 ) NOT NULL AUTO_INCREMENT PRIMARY KEY ,
		`date` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ,
		`otro` VARCHAR( 255 ) NOT NULL )
	';
	$wpdb->query($sql);

}

function plugin_name_deactivate() {
	global $wpdb;
	$sql = 'DROP TABLE `' . $wpdb->prefix . 'plugin_name`';
	$wpdb->query($sql);

}

?&gt;</pre>
<p>A mi me han sido de utilidad en más de una ocasión, ya me contaréis.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.berriart.com/2009/05/06/hook-activar-desactivar-plugin/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Mejorar con GIMP las fotos tomadas desde un avión</title>
		<link>http://www.berriart.com/2009/04/24/mejorar-con-gimp-las-fotos-tomadas-desde-un-avion/</link>
		<comments>http://www.berriart.com/2009/04/24/mejorar-con-gimp-las-fotos-tomadas-desde-un-avion/#comments</comments>
		<pubDate>Thu, 23 Apr 2009 23:09:29 +0000</pubDate>
		<dc:creator>artberri</dc:creator>
				<category><![CDATA[Gimp]]></category>
		<category><![CDATA[Tutoriales]]></category>
		<category><![CDATA[avión]]></category>
		<category><![CDATA[fotos]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://www.berriart.com/?p=456</guid>
		<description><![CDATA[Una de las cosas que más molan de ir en el asiento con ventanilla de un avión es poder sacar fotos aéreas, aunque te pase como a mi, que siempre que se puede sacar algo chulo estoy mirando para otro lado, sin pilas o con la cámara muy a desmano (en la maleta facturada por [...]]]></description>
			<content:encoded><![CDATA[<p>Una de las cosas que más <em>molan</em> de ir en el asiento con ventanilla de un avión es poder sacar fotos aéreas, aunque te pase como a mi, que siempre que se puede sacar algo chulo estoy mirando para otro lado, sin pilas o con la cámara muy a desmano (en la maleta facturada por ejemplo). Pero existe un problema a la hora de sacar esas fotos y es que, gracias a la ventanilla y algún que otro factor, salen muy descoloridas o como si tuvieran una cortinilla gris delante.</p>
<p>Pero como bien dice Helen Bradley en este <a href="http://www.projectwoman.com/2009/02/photoshop-fixing-photos-shot-from.html">tutorial para photoshop</a> en el que me he inspirado totalmente (ahora se dice así), hay pocas cosas que el Photoshop no pueda arreglar, o en este caso, el GIMP. Así que a continuación os explico como podéis arreglar una foto de ventanilla de avión con GIMP. Ésto sería un ejemplo:</p>
<p><a href="http://www.berriart.com/wp-content/uploads/2009/04/tutorial-gimp.jpg"><img src="http://www.berriart.com/wp-content/uploads/2009/04/tutorial-gimp-600x838.jpg" alt="tutorial-gimp" title="tutorial-gimp" width="600" height="838" class="size-medium wp-image-457" /></a></p>
<p>Coger alguna de las fotos de avión de vuestros viajes y abrirla con el GIMP que empezamos.</p>
<p><strong>Paso 1</strong><br />
Empezamos haciendo un duplicado de la capa de fondo para trabajar sobre él, y dejamos debajo el original por si luego lo necesitamos. Para ello, podemos pulsar en el botón de duplicar capa, hacerlo desde el menú <em>Capa</em> o pulsar <em>Shift+Ctrl+D</em>.</p>
<p><a href="http://www.berriart.com/wp-content/uploads/2009/04/duplicar.png"><img src="http://www.berriart.com/wp-content/uploads/2009/04/duplicar-600x375.png" alt="duplicar capa" title="duplicar capa" width="600" height="375" class="size-medium wp-image-458" /></a></p>
<p><strong>Paso 2</strong><br />
Seleccionamos la capa superior (sobre la que vamos a trabajar) y vamos al menú <em>Colores->Niveles</em>. El histograma de niveles te dice mucho sobre el estado de la imagen. En la mayoría de estos casos faltara blanco y negro, y la curva se verá concentrada en el centro. Así que para arreglarlo vamos a arrastrar los &#8216;sliders&#8217; laterales -negro y blanco- hasta donde comienza la curva por cada uno de los lados. Al hacerlo se debería ver perfectamente un aumento en el contraste y un poco en el color también. Aceptamos y seguimos.</p>
<p><a href="http://www.berriart.com/wp-content/uploads/2009/04/niveles.png"><img src="http://www.berriart.com/wp-content/uploads/2009/04/niveles-600x375.png" alt="niveles" title="niveles" width="600" height="375" class="alignnone size-medium wp-image-460" /></a></p>
<p><strong>Paso 3</strong><br />
Arreglar problemas con el color. Con frecuencia, la imagen tendrá demasiado azul (u otro problema de tonalidad) y se puede arreglar mediante un ajuste de curvas, así que vamos al menú  <em>Colores->Curvas</em>. Del desplegable de canales, vamos seleccionando el rojo, verde y azul, y probamos a mover la curva hacia arriba o hacia abajo dependiendo de si le queremos dar  o quitar ese color. Se pueden hacer pruebas con la vista previa activada hasta que quede a tu gusto y aceptamos.</p>
<p><strong>Paso 4</strong><br />
Al hacer la foto desde tan alto, suele tener mejor tonalidad en la zona de abajo, la más cercana al fotografo. Para compensar esto vamos a añadir una capa nueva y a hacer lo siguiente sobre ella. Con el negro seleccionado de color frontal y el blanco de fondo, elegimos la herramienta de degradado y hacemos uno de arriba a abajo (la zona superior debe ser negra y la de abajo blanca). Cuando lo tengamos listo, cambiaremos el &#8216;modo&#8217; de la capa de &#8216;normal&#8217; a &#8216;solapar&#8217; (en un desplegable que hay sobre el listado de capas) y manejando la transparencia de esta capa lo dejamos al gusto.</p>
<p><strong>Paso 5</strong><br />
Ahora le podemos dar los últimos retoques a la capa de la imágen tratada utilizando las herramientas del menú de <em>Colores</em>, saturación, contraste, brillo,&#8230; hasta que por fin se parezca más a lo que queremos.</p>
<p><strong>Paso 6</strong><br />
Finalmente intentaremos darle un poco de nitided a la imagen, pero antes uniremos todas las capas en una pulsando en el menú <em>Imagen->Aplanar Imagen</em>. Ahora, para darle nitided vamos a intentar enfocar la imágen con un filtro de GIMP. Prueba a ir al menú <em>Filtros->Realzar->Sharpen</em> (si no lo tienes tendrás que instalar <a href="http://comunidad.fotolibre.net/index.php?topic=2361.0">algún plugin para enfoque</a>). Cuando lo tengas modifica el umbral del filtro hasta que te parezca que está bien y acepta. Hemos terminado.</p>
<p><a href="http://www.berriart.com/wp-content/uploads/2009/04/final.png"><img src="http://www.berriart.com/wp-content/uploads/2009/04/final-600x375.png" alt="final" title="final" width="600" height="375" class="alignnone size-medium wp-image-459" /></a></p>
<p>Espero que os haya gustado, y ya sabéis, si lo probáis dejadme un enlace en los comentarios a vuestra imagen para ver el resultado.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.berriart.com/2009/04/24/mejorar-con-gimp-las-fotos-tomadas-desde-un-avion/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Tutorial GIMP, fotos que parecen maquetas (fake model o tilt/shift)</title>
		<link>http://www.berriart.com/2009/02/22/tutorial-gimp-fotos-que-parecen-maquetas-fake-model-o-tiltshift/</link>
		<comments>http://www.berriart.com/2009/02/22/tutorial-gimp-fotos-que-parecen-maquetas-fake-model-o-tiltshift/#comments</comments>
		<pubDate>Sun, 22 Feb 2009 20:20:53 +0000</pubDate>
		<dc:creator>artberri</dc:creator>
				<category><![CDATA[Gimp]]></category>
		<category><![CDATA[Tutoriales]]></category>
		<category><![CDATA[efectos]]></category>
		<category><![CDATA[fotos]]></category>
		<category><![CDATA[maquetas]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://www.berriart.com/?p=419</guid>
		<description><![CDATA[No sé si habéis visto alguna vez fotos reales que parecen maquetas a pequeña escala del lugar. Es un efecto que se llama fake model o tilt/shift, que es bastante sencillito de hacer, y que hace que algunas fotos queden muy curiosas. En Flickr, tenéis una larga lista de fotos de este tipo y aquí [...]]]></description>
			<content:encoded><![CDATA[<p>No sé si habéis visto alguna vez fotos reales que parecen maquetas a pequeña escala del lugar. Es un efecto que se llama <em>fake model</em> o <em>tilt/shift</em>, que es bastante sencillito de hacer, y que hace que algunas fotos queden muy curiosas. En Flickr, <a href="http://www.flickr.com/search/?q=fake%20model&#038;w=all">tenéis una larga lista de fotos de este tipo</a> y <a href="http://www.flickr.com/search/?q=Tilt%2FShift&#038;w=all">aquí otra</a>. Yo he hecho algunas de ejemplo:</p>
<div style="float:left;margin:0 10px 10px 0;"><a href="http://www.berriart.com/wp-content/uploads/2009/02/arousa-fakemodel.jpg"><img src="http://www.berriart.com/wp-content/uploads/2009/02/arousa-fakemodel-400x187.jpg" alt="arousa fakemodel" title="arousa fakemodel" width="400" height="187" style="padding:3px;border:1px #ccc solid;" /></a><br />
<br />
<a href="http://www.berriart.com/wp-content/uploads/2009/02/airport-fakemodel.jpg"><img src="http://www.berriart.com/wp-content/uploads/2009/02/airport-fakemodel-150x150.jpg" alt="airport fakemodel" title="airport fakemodel" width="150" height="150" style="float:left;padding:3px;border:1px #ccc solid;" /></a><a href="http://www.berriart.com/wp-content/uploads/2009/02/intersection-modelfake.jpg"><img src="http://www.berriart.com/wp-content/uploads/2009/02/intersection-modelfake-150x150.jpg" alt="intersection modelfake" title="intersection modelfake" width="150" height="150" style="float:right;padding:3px;border:1px #ccc solid;" /></a></div>
<p>El efecto no está hecho sobre fotos propias, así que podéis ver los originales de las fotos anteriores en los albumes de sus respectivos autores en flickr, <a href="http://www.flickr.com/photos/reservasdecoches/">reservasdecoches</a>, <a href="http://www.flickr.com/photos/docsearls/2055951787/sizes/l/">dsearls</a>. Para que podáis recrear el mismo efecto en vuestras fotos escribo este pequeño tutorial para <a href="http://www.berriart.com/category/gimp/">GIMP</a>.</p>
<p>Así que elegís la foto a la que queréis aplicarle el efecto y empezamos, las fotos buenas para este tipo de efectos suelen ser fotos aereas, sobre todo de edificios modernos que se encuentran en zonas antiguas. Una vez tengamos la foto abierta con el GIMP vamos a duplicar la capa actual, para ello vamos al menú <em>Capa->Duplicar Capa</em>, o más facilmente pulsamos Ctrl+Shift+D. Como luego vamos a borrar parte de esta capa, necesitamos añadirle el <em>canal alfa</em> -o transparencia-, así que seleccionamos la capa recién creada y vamos al menú <em>Capa->Transparencia->Añadir canal alfa</em>.</p>
<p>Ahora hay que agregar el efecto de desenfoque a esta capa superior. Para ello vamos al menú <em>Filtros->Desenfoque (Blur)->Desenfoque Gaussiano</em>. Depende de la foto deberemos desenfocar en mayor o menos medida, eso depende de vosotros.</p>
<p><a href="http://www.berriart.com/wp-content/uploads/2009/02/pantallazo.png"><img src="http://www.berriart.com/wp-content/uploads/2009/02/pantallazo-400x250.png" alt="tutorial fakemodel" title="tutorial fakemodel" width="400" height="250" style="margin:auto;padding:3px;border:1px #ccc solid;display:block;" /></a></p>
<p>Y para terminar,escogemos la herramienta borrador (Shift+E), y vamos borrando la capa desenfocada en las partes de la foto que queremos que parezcan una maqueta. Para borrar es mejor escoger un pincel difuminado, pero en algunos puntos puede que tengas que usar uno más solido.</p>
<p><a href="http://www.berriart.com/wp-content/uploads/2009/02/pantallazo-1.png"><img src="http://www.berriart.com/wp-content/uploads/2009/02/pantallazo-1-400x250.png" alt="tutorial gimp fakemodel" title="tutorial gimp fakemodel" width="400" height="250"  style="margin:auto;padding:3px;border:1px #ccc solid;display:block;" /></a></p>
<p>Como veréis al ir borrrando la capa difuminada va quedando a la vista la capa original, mucho más marcada, dando la impresión en algunos casos de que la parte enfocada no es real y es una maqueta a escala. Espero que os haya gustado y como siempre que escribo un <a href="http://www.berriart.com/category/tutoriales/">tutorial</a>, me encantaría ver en los comentarios vuestras creaciones.</p>
<p><a href="http://www.berriart.com/wp-content/uploads/2009/02/arousa-fakemodel.jpg"><img src="http://www.berriart.com/wp-content/uploads/2009/02/arousa-fakemodel-400x187.jpg" alt="arousa fakemodel" title="arousa fakemodel" width="400" height="187" style="margin:auto;padding:3px;border:1px #ccc solid;display:block;" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.berriart.com/2009/02/22/tutorial-gimp-fotos-que-parecen-maquetas-fake-model-o-tiltshift/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Crear una aplicación para Facebook</title>
		<link>http://www.berriart.com/2008/12/01/crear-una-aplicacion-para-facebook/</link>
		<comments>http://www.berriart.com/2008/12/01/crear-una-aplicacion-para-facebook/#comments</comments>
		<pubDate>Sun, 30 Nov 2008 23:53:26 +0000</pubDate>
		<dc:creator>artberri</dc:creator>
				<category><![CDATA[Aplicaciones web]]></category>
		<category><![CDATA[Programación]]></category>
		<category><![CDATA[Recursos]]></category>
		<category><![CDATA[Tutoriales]]></category>
		<category><![CDATA[aplicación]]></category>
		<category><![CDATA[Facebook]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://www.berriart.com/?p=316</guid>
		<description><![CDATA[Ya que voy a hacer una aplicación para Facebook de Efemerides 2.0, voy a aprovechar para explicar lo sencillo que es crear un pequeña aplicación, lo que sería un hello world para Facebook. Lo primero que hay que hacer si se quieren desarrollar aplicaciones de Facebook, es tener una cuenta y agregarse la aplicación de [...]]]></description>
			<content:encoded><![CDATA[<p>Ya que voy a hacer una aplicación para Facebook de <a href="http://efemerides20.com/">Efemerides 2.0</a>, voy a aprovechar para explicar lo sencillo que es crear un pequeña aplicación, lo que sería un <em>hello world</em> para Facebook. </p>
<p>Lo primero que hay que hacer si se quieren desarrollar aplicaciones de <a href="http://www.facebook.com/">Facebook</a>, es tener una cuenta y <a href="http://www.facebook.com/developers/">agregarse la aplicación de desarrolladores</a>. Cuando ya la tengamos agregada hay que pinchar en <a href="http://www.facebook.com/developers/editapp.php?new">crear nueva aplicación</a>, ponerle un nombre y enviar.</p>
<p>Lo que vamos a desarrollar es una aplicación web para Facebook, así que vamos a necesitar un sitio dónde alojarla, además vamos a escribirla en PHP y si queréis guardar datos necesitaremos una base de datos MySQL.</p>
<p>Cuando ya sepamos donde la vamos a alojar, nos vamos a nuestra aplicación en Facebook y vamos a editar sus datos. En la siguiente imagen se explican los parámetros de configuración que debemos rellenar en un inicio:</p>
<p><img src="http://www.berriart.com/wp-content/uploads/2008/12/miaplicacion.png" alt="" width="450" height="2162" style="display:block;margin:auto;" /></p>
<p>Ya tenemos todo configurado en la parte de Facebook, ahora solo nos queda crear nuestra aplicación y subirla a nuestro servidor. Como ya hemos dicho la escribiremos en PHP, pero primero debemos <a href="http://developers.facebook.com/clientlibs/facebook-platform.tar.gz">bajarnos la librería PHP de Facebook</a>. La descomprimimos y la metemos en la carpeta dónde vayamos a alojar la aplicación.</p>
<p>Finalmente este es el <em>hello world</em> en PHP que debemos subir y guardar como index.php:</p>
<pre><code>&lt;?php

require_once 'facebook-platform/client/facebook.php';

$appapikey = 'XXXXXXXXXXXXXXXXXXXXXXX';
$appsecret = 'XXXXXXXXXXXXXXXXXXXXXXX';
$facebook = new Facebook($appapikey, $appsecret);
$user_id = $facebook-&gt;require_login();

echo "&lt;p&gt;Hola, &lt;fb:name uid=\"$user_id\" useyou=\"false\" /&gt;&lt;/p&gt;";

// Sacar por pantalla los cumpleaños de 20 de nuestros amigos
echo "&lt;p&gt;Cumpleaños de mis amigos:";
$friends = $facebook-&gt;api_client-&gt;friends_get();
$friends = array_slice($friends, 0, 25);
foreach ($friends as $friend) {
	$birthdate = $facebook-&gt;api_client-&gt;users_getinfo($friend, 'birthday');
	echo "&lt;br&gt;Id de usuario: " . $friend . " - Fecha de nacimiento: " . $birthdate[0]['birthday'] . "\n";
}
echo "&lt;/p&gt;";
?&gt;</code></pre>
<p>Como veis en este script, primero incluimos la librería PHP de Facebook:</p>
<p><span style="color:#880000;">require_once &#8216;facebook-platform/client/facebook.php&#8217;;</span></p>
<p>Luego hay que escribir las API keys de nuestra aplicación que encontraremos en el panel de nuestra aplicación en Facebook.</p>
<p><span style="color:#880000;">$appapikey = &#8216;XXXXXXXXXXXXXXXXXXXXXXX&#8217;;<br />
$appsecret = &#8216;XXXXXXXXXXXXXXXXXXXXXXX&#8217;;</span></p>
<p>Después creamos el objeto Facebook, y obtenemos el ID de usuario de la persona que accede a nuestra aplicación:</p>
<p><span style="color:#880000;">$facebook = new Facebook($appapikey, $appsecret);<br />
$user_id = $facebook-&gt;require_login();</span></p>
<p>Printeamos un saludo utilizando el user ID y <a href="http://wiki.developers.facebook.com/index.php/FBML">FBML</a>, que es un lenguage tipo HTML especial para Facebook:</p>
<p><span style="color:#880000;">echo &#8220;&lt;p&gt;Hola, &lt;fb:name uid=\&#8221;$user_id\&#8221; useyou=\&#8221;false\&#8221; /&gt;&lt;/p&gt;&#8221;;</span></p>
<p>Y finalmente sacamos los IDs de 25 de nuestros amigos y su fecha de nacimiento si es que la han puesto:</p>
<p><span style="color:#880000;">// Sacar por pantalla los cumpleaños de 20 de nuestros amigos<br />
echo &#8220;&lt;p&gt;Cumpleaños de mis amigos:&#8221;;<br />
$friends = $facebook-&gt;api_client-&gt;friends_get();<br />
$friends = array_slice($friends, 0, 25);<br />
foreach ($friends as $friend) {<br />
	$birthdate = $facebook-&gt;api_client-&gt;users_getinfo($friend, &#8216;birthday&#8217;);<br />
	echo &#8220;&lt;br&gt;Id de usuario: &#8221; . $friend . &#8221; &#8211; Fecha de nacimiento: &#8221; . $birthdate[0]['birthday'] . &#8220;\n&#8221;;<br />
}<br />
echo &#8220;&lt;/p&gt;&#8221;;</span></p>
<p>Ésto ha sido todo, y como se puede ver al menos hacer un ejemplo no es muy dificil. A partir de aquí lo que os de la imaginación, estáis en vuestro servidor y podéis hacer casi lo que queráis. Para ver vuestra creación debeís acceder a <em>http://apps.facebook.com/miaplicacion/</em>, es decir, la página que habéis elegido como <em>Canvas URL</em> en la configuración.</p>
<p>Experimentad y ya me contaréis.</p>
<p><strong>Editado: </strong> Ya he corregido el problema del que hablaban en los comentarios.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.berriart.com/2008/12/01/crear-una-aplicacion-para-facebook/feed/</wfw:commentRss>
		<slash:comments>81</slash:comments>
		</item>
	</channel>
</rss>

