<?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/"
	xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd"
	xmlns:media="http://search.yahoo.com/mrss/"
>

<channel>
	<title>GaRaGeD Style &#187; perl</title>
	<atom:link href="http://thegaraged.org/garaged/perl/feed" rel="self" type="application/rss+xml" />
	<link>http://thegaraged.org</link>
	<description>linux, SL y yo</description>
	<lastBuildDate>Thu, 22 Jul 2010 19:13:02 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=abc</generator>
	<!-- podcast_generator="podPress/8.8" - maintenance_release="8.8.4" -->
		<copyright> </copyright>
		<managingEditor> ()</managingEditor>
		<webMaster> ()</webMaster>
		<category></category>
		<itunes:keywords></itunes:keywords>
		<itunes:subtitle></itunes:subtitle>
		<itunes:summary></itunes:summary>
		<itunes:author></itunes:author>
		<itunes:category text="Society &amp; Culture"/>
		<itunes:owner>
			<itunes:name></itunes:name>
			<itunes:email></itunes:email>
		</itunes:owner>
		<itunes:block>No</itunes:block>
		<itunes:explicit></itunes:explicit>
		<itunes:image href="http://thegaraged.org/wp-content/plugins/podpress/images/powered_by_podpress_large.jpg" />
		<image>
			<url></url>
			<title>GaRaGeD Style</title>
			<link>http://thegaraged.org</link>
			<width>144</width>
			<height>144</height>
		</image>
		<item>
		<title>archivo de word-&gt;txt-&gt;perlazo-&gt;html</title>
		<link>http://thegaraged.org/2009/07/15/archivo-de-word-txt-perlazo-html</link>
		<comments>http://thegaraged.org/2009/07/15/archivo-de-word-txt-perlazo-html#comments</comments>
		<pubDate>Wed, 15 Jul 2009 19:20:37 +0000</pubDate>
		<dc:creator>garaged</dc:creator>
				<category><![CDATA[perl]]></category>
		<category><![CDATA[la huesped]]></category>
		<category><![CDATA[stephenie meyer]]></category>
		<category><![CDATA[the host]]></category>

		<guid isPermaLink="false">http://thegaraged.org/?p=537</guid>
		<description><![CDATA[]]></description>
			<content:encoded><![CDATA[<p>Este es un post sobre el fino arte de piratearse un ebook, aunque no voy a decir que me incrimine, excepto que se trata de una autora contemporanea, de la que hace poco comenté aquí mismo que leí cierta saga de 4 libros sobre vampiritos amables.</p>
<p>Bueno, la historia está así, tengo un archivo de word (.doc), entonces, lo primero que hice fue convertirlo a txt en el word (duh!), luego con el script que está abajo que además usa el programa &#8220;txt2html&#8221; se divide el texto en capítulos y se convierte a HTML para ser subido a mi iphone y pueda ser leído con el BookReader.</p>
<p>Si tuve que hacerle algunos cambios al &#8220;txt&#8221;, porque el script no es muy inteligente (como su dueño) (no es mío !!), pero nada que tome más de 1 minuto, al final tengo en mi iphone listo para leerse la más reciente novela de la susodicha misteriosa.</p>
<div id="wpshdo_1" class="wp-synhighlighter-outer"><div id="wpshdt_1" class="wp-synhighlighter-expanded"><table border="0" width="100%"><tr><td align="left" width="80%"><a name="#codesyntax_1"></a><a id="wpshat_1" class="wp-synhighlighter-title" href="#codesyntax_1"  onClick="javascript:wpsh_toggleBlock(1)" title="Click to show/hide code block">Code block</a></td><td align="right"><a href="#codesyntax_1" onClick="javascript:wpsh_code(1)" title="Show code only"><img border="0" style="border: 0 none" src="http://thegaraged.org/wp-content/plugins/wp-synhighlight/themes/default/images/code.png" /></a>&nbsp;<a href="#codesyntax_1" onClick="javascript:wpsh_print(1)" title="Print code"><img border="0" style="border: 0 none" src="http://thegaraged.org/wp-content/plugins/wp-synhighlight/themes/default/images/printer.png" /></a>&nbsp;<a href="http://thegaraged.org/wp-content/plugins/wp-synhighlight/About.html" target="_blank" title="Show plugin information"><img border="0" style="border: 0 none" src="http://thegaraged.org/wp-content/plugins/wp-synhighlight/themes/default/images/info.gif" /></a>&nbsp;</td></tr></table></div><div id="wpshdi_1" class="wp-synhighlighter-inner" style="display: block;"><pre class="perl" style="font-family:monospace;"><span class="co1">#!/opt/local/bin/perl -w</span>
<span class="kw2">use</span> strict<span class="sy0">;</span>
<span class="kw2">use</span> warnings<span class="sy0">;</span>
<span class="kw1">my</span> <span class="re0">$file</span> <span class="sy0">=</span> <span class="re0">$ARGV</span><span class="br0">&#91;</span>0<span class="br0">&#93;</span><span class="sy0">;</span>
<a href="http://perldoc.perl.org/functions/open.html"><span class="kw3">open</span></a> FILE<span class="sy0">,</span> <span class="st0">&quot;&lt; $file&quot;</span><span class="sy0">;</span>
<span class="kw1">my</span> <span class="re0">$oldname</span> <span class="sy0">=</span> <span class="st0">&quot;CHAPTER 0&quot;</span><span class="sy0">;</span>
<a href="http://perldoc.perl.org/functions/open.html"><span class="kw3">open</span></a> FILE_OUT<span class="sy0">,</span> <span class="st0">&quot;&gt;$oldname.txt&quot;</span><span class="sy0">;</span>
<span class="kw1">while</span> <span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
	<a href="http://perldoc.perl.org/functions/chop.html"><span class="kw3">chop</span></a><span class="sy0">;</span>
	<span class="kw1">my</span> <span class="re0">$linea</span> <span class="sy0">=</span> <span class="co5">$_</span><span class="sy0">;</span>
	<span class="kw1">if</span> <span class="br0">&#40;</span> <span class="co5">$_</span> <span class="sy0">=~</span> <span class="co2">m/^CHAPTER [\d]+$/</span> <span class="br0">&#41;</span> <span class="br0">&#123;</span>
		<a href="http://perldoc.perl.org/functions/print.html"><span class="kw3">print</span></a> <span class="st0">&quot;$_ - &quot;</span><span class="sy0">;</span>
		<span class="kw1">my</span> <span class="re0">$chap</span> <span class="sy0">=</span> <span class="co5">$_</span><span class="sy0">;</span>
		<span class="kw1">my</span> <span class="re0">$name</span> <span class="sy0">=</span> <span class="sy0">;</span>
		<a href="http://perldoc.perl.org/functions/chop.html"><span class="kw3">chop</span></a> <span class="re0">$name</span><span class="sy0">;</span>
		<a href="http://perldoc.perl.org/functions/print.html"><span class="kw3">print</span></a> <span class="st0">&quot;$name<span class="es0">\n</span>&quot;</span><span class="sy0">;</span>
		<a href="http://perldoc.perl.org/functions/close.html"><span class="kw3">close</span></a> FILE_OUT<span class="sy0">;</span>
		<a href="http://perldoc.perl.org/functions/open.html"><span class="kw3">open</span></a> FILE_OUT<span class="sy0">,</span> <span class="st0">&quot;&gt;$chap-$name.txt&quot;</span><span class="sy0">;</span>
		<span class="st0">`txt2html &quot;$oldname.txt&quot; &gt; &quot;$oldname.html&quot;`</span><span class="sy0">;</span>
		<span class="re0">$oldname</span> <span class="sy0">=</span> <span class="st0">&quot;$chap-$name&quot;</span><span class="sy0">;</span>
		<span class="re0">$linea</span> <span class="sy0">=</span> <span class="st0">&quot;$chap - $name&quot;</span><span class="sy0">;</span>
	<span class="br0">&#125;</span> <span class="kw1">elsif</span> <span class="br0">&#40;</span> <span class="co5">$_</span> <span class="sy0">=~</span> <span class="co2">m/^Page [\d]+$/</span> <span class="br0">&#41;</span> <span class="br0">&#123;</span>
		<span class="re0">$linea</span> <span class="sy0">=</span> <span class="sy0">;</span>
		<span class="re0">$linea</span> <span class="sy0">=</span>  <span class="kw1">or</span> <span class="re0">$linea</span> <span class="sy0">=</span> <span class="st0">&quot;&quot;</span><span class="sy0">;</span>
	<span class="br0">&#125;</span>
	<a href="http://perldoc.perl.org/functions/print.html"><span class="kw3">print</span></a> FILE_OUT <span class="st0">&quot;$linea<span class="es0">\n</span>&quot;</span> <span class="kw1">or</span> <a href="http://perldoc.perl.org/functions/warn.html"><span class="kw3">warn</span></a> <span class="st0">&quot;Fin de archivo?&quot;</span><span class="sy0">;</span>
<span class="br0">&#125;</span>
<span class="st0">`txt2html &quot;$oldname.txt&quot; &gt; &quot;$oldname.html&quot;`</span><span class="sy0">;</span></pre></div></div>
<p>El documento original usa un par de patrones para los títulos de cada capítulo y para las páginas, entonces de eso me aproveché para poder dividir en archivos cada capítulo, y bueno, eliminar la molesta etiqueta de &#8220;Page 1&#8230; Page 2&#8230;&#8221;. Con lo cual doy el primer paso para dedicarme a convertidor de textos a ebooks <img src='http://thegaraged.org/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' /> </p>
<p>SPOILER: El libro es &#8220;The host&#8221; o &#8220;La Huesped&#8221; creo se llama en español, de Stephenie Meyer de quien me declaro fans ! (en realidad esto es pa ayudarle a google a indexar el post <img src='http://thegaraged.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </file></p>
]]></content:encoded>
			<wfw:commentRss>http://thegaraged.org/2009/07/15/archivo-de-word-txt-perlazo-html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>CGI::Aplication el fino arte de hacer web perl-style</title>
		<link>http://thegaraged.org/2009/07/14/cgiaplication-el-fino-arte-de-hacer-web-perl-style</link>
		<comments>http://thegaraged.org/2009/07/14/cgiaplication-el-fino-arte-de-hacer-web-perl-style#comments</comments>
		<pubDate>Tue, 14 Jul 2009 17:50:27 +0000</pubDate>
		<dc:creator>garaged</dc:creator>
				<category><![CDATA[perl]]></category>
		<category><![CDATA[cgi::application]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://thegaraged.org/?p=502</guid>
		<description><![CDATA[Perl es una maravilla en cuanto a robustes y disponibilidad de módulos para hacer lo que sea, no solo es posible analizar logs al más puro estilo geek, sino que se pueden hacer cosas como &#8220;parsear&#8221; un archivo de excel para importarlo a una base de datos, o crear sitios web con todas las características [...]]]></description>
			<content:encoded><![CDATA[<p>Perl es una maravilla en cuanto a robustes y disponibilidad de módulos para hacer lo que sea, no solo es posible analizar logs al más puro estilo geek, sino que se pueden hacer cosas como &#8220;parsear&#8221; un archivo de excel para importarlo a una base de datos, o crear sitios web con todas las características que necesitan.</p>
<p>Para crear aplicaciones Web, Perl tiene un monton de opciones, desde hacer un CGI a mano que haga toda la magia de entender los headers, extraer los argumentos de GET y POST, y desplegar HTML intercalado en el código, al más puro estilo de PHP (porque lo heredó de Perl), sino que existen muchos módulos (CPAN) que nos ayudan a hacer las cosas de manera más ordenada y mantenible.</p>
<p>En esta nota quiero abordar la utilización de un módulo muy robusto, casi podríamos decir que es realmente un Framework de desarrollo web, aunque a mi no me gustan los frameworks,  uno no deja de admirar la simplicidad con la que se puede crear una simple paginita web siguiendo bastante fielmente algunos de las más famosas &#8220;mejores prácticas&#8221;, como el MVC, el uso de capa de abstraccion en la base de datos, y sobre todo el crear código seguro contra ataques de injeccion SQL y XSS.</p>
<p>Para empezar vamos a plantear el clásico ejemplo de crear un blog muy sencillo, que tenga autenticación, guarde en mysql, y nos permita mandar noticias y poner comentarios en ellas, nada exótico.</p>
<p>Empezemos por crear una base de datos:<br />
<div id="wpshdo_2" class="wp-synhighlighter-outer"><div id="wpshdt_2" class="wp-synhighlighter-expanded"><table border="0" width="100%"><tr><td align="left" width="80%"><a name="#codesyntax_2"></a><a id="wpshat_2" class="wp-synhighlighter-title" href="#codesyntax_2"  onClick="javascript:wpsh_toggleBlock(2)" title="Click to show/hide code block">Code block</a></td><td align="right"><a href="#codesyntax_2" onClick="javascript:wpsh_code(2)" title="Show code only"><img border="0" style="border: 0 none" src="http://thegaraged.org/wp-content/plugins/wp-synhighlight/themes/default/images/code.png" /></a>&nbsp;<a href="#codesyntax_2" onClick="javascript:wpsh_print(2)" title="Print code"><img border="0" style="border: 0 none" src="http://thegaraged.org/wp-content/plugins/wp-synhighlight/themes/default/images/printer.png" /></a>&nbsp;<a href="http://thegaraged.org/wp-content/plugins/wp-synhighlight/About.html" target="_blank" title="Show plugin information"><img border="0" style="border: 0 none" src="http://thegaraged.org/wp-content/plugins/wp-synhighlight/themes/default/images/info.gif" /></a>&nbsp;</td></tr></table></div><div id="wpshdi_2" class="wp-synhighlighter-inner" style="display: block;"><div class="sql" style="font-family:monospace;">mysql<span class="sy0">&gt;</span> <span class="kw1">CREATE</span> <span class="kw1">DATABASE</span> perlblog;<br />
Query OK<span class="sy0">,</span> 1 row affected <span class="br0">&#40;</span>0<span class="sy0">.</span>09 sec<span class="br0">&#41;</span><br />
mysql<span class="sy0">&gt;</span> <span class="kw1">GRANT</span> <span class="kw1">ALL</span> privileges <span class="kw1">ON</span> perlblog<span class="sy0">.*</span> <span class="kw1">TO</span> blog@localhost <span class="kw1">IDENTIFIED</span> <span class="kw1">BY</span> <span class="st0">`20y1337`</span> ;<br />
Query OK<span class="sy0">,</span> <span class="nu0">0</span> rows affected <span class="br0">&#40;</span><span class="nu0">0.27</span> sec<span class="br0">&#41;</span><br />
mysql<span class="sy0">&gt;</span></div></div></div><br />
Necesitamos varias columnas, una para los datos del usuario (user), otra para las noticias (news), y otra para comentarios (comments), luego veremos si se requiere algo extra.<br />
<div id="wpshdo_3" class="wp-synhighlighter-outer"><div id="wpshdt_3" class="wp-synhighlighter-expanded"><table border="0" width="100%"><tr><td align="left" width="80%"><a name="#codesyntax_3"></a><a id="wpshat_3" class="wp-synhighlighter-title" href="#codesyntax_3"  onClick="javascript:wpsh_toggleBlock(3)" title="Click to show/hide code block">Code block</a></td><td align="right"><a href="#codesyntax_3" onClick="javascript:wpsh_code(3)" title="Show code only"><img border="0" style="border: 0 none" src="http://thegaraged.org/wp-content/plugins/wp-synhighlight/themes/default/images/code.png" /></a>&nbsp;<a href="#codesyntax_3" onClick="javascript:wpsh_print(3)" title="Print code"><img border="0" style="border: 0 none" src="http://thegaraged.org/wp-content/plugins/wp-synhighlight/themes/default/images/printer.png" /></a>&nbsp;<a href="http://thegaraged.org/wp-content/plugins/wp-synhighlight/About.html" target="_blank" title="Show plugin information"><img border="0" style="border: 0 none" src="http://thegaraged.org/wp-content/plugins/wp-synhighlight/themes/default/images/info.gif" /></a>&nbsp;</td></tr></table></div><div id="wpshdi_3" class="wp-synhighlighter-inner" style="display: block;"><div class="sql" style="font-family:monospace;">mysql<span class="sy0">&gt;</span> <span class="kw1">CREATE</span> <span class="kw1">TABLE</span> user <span class="br0">&#40;</span>id int <span class="kw1">UNSIGNED</span> <span class="kw1">NOT</span> <span class="kw1">NULL</span> <span class="kw1">AUTO_INCREMENT</span><span class="sy0">,</span> login varchar<span class="br0">&#40;</span>50<span class="br0">&#41;</span> <span class="kw1">UNIQUE</span><span class="sy0">,</span> password char<span class="br0">&#40;</span>32<span class="br0">&#41;</span><span class="sy0">,</span> name varchar<span class="br0">&#40;</span>150<span class="br0">&#41;</span><span class="sy0">,</span> created datetime<span class="sy0">,</span> last_log datetime<span class="sy0">,</span> <span class="kw1">PRIMARY</span> <span class="kw1">KEY</span> <span class="br0">&#40;</span>id<span class="br0">&#41;</span><span class="br0">&#41;</span>;<br />
Query OK<span class="sy0">,</span> 0 rows affected <span class="br0">&#40;</span>0<span class="sy0">.</span>21 sec<span class="br0">&#41;</span><br />
mysql<span class="sy0">&gt;</span> <span class="kw1">CREATE</span> <span class="kw1">TABLE</span> news <span class="br0">&#40;</span>id int <span class="kw1">UNSIGNED</span> <span class="kw1">NOT</span> <span class="kw1">NULL</span> <span class="kw1">AUTO_INCREMENT</span><span class="sy0">,</span> title varchar<span class="br0">&#40;</span>254<span class="br0">&#41;</span><span class="sy0">,</span> summary tinytext <span class="sy0">,</span> news text<span class="sy0">,</span> posted datetime<span class="sy0">,</span> last_edit datetime<span class="sy0">,</span> user_id int <span class="kw1">UNSIGNED</span> <span class="kw1">NOT</span> <span class="kw1">NULL</span> <span class="kw1">DEFAULT</span> 1<span class="sy0">,</span> <span class="kw1">PRIMARY</span> <span class="kw1">KEY</span> <span class="br0">&#40;</span>id<span class="br0">&#41;</span><span class="br0">&#41;</span>;<br />
Query OK<span class="sy0">,</span> 0 rows affected <span class="br0">&#40;</span>0<span class="sy0">.</span>43 sec<span class="br0">&#41;</span><br />
mysql<span class="sy0">&gt;</span> <span class="kw1">CREATE</span> <span class="kw1">TABLE</span> comment <span class="br0">&#40;</span>id int <span class="kw1">UNSIGNED</span> <span class="kw1">NOT</span> <span class="kw1">NULL</span> <span class="kw1">AUTO_INCREMENT</span><span class="sy0">,</span> title varchar<span class="br0">&#40;</span>254<span class="br0">&#41;</span><span class="sy0">,</span> comment text<span class="sy0">,</span> posted datetime<span class="sy0">,</span> last_edit datetime<span class="sy0">,</span> user_id int <span class="kw1">UNSIGNED</span> <span class="kw1">NOT</span> <span class="kw1">NULL</span> <span class="kw1">DEFAULT</span> 0<span class="sy0">,</span> name varchar<span class="br0">&#40;</span>255<span class="br0">&#41;</span><span class="sy0">,</span> email varchar<span class="br0">&#40;</span>255<span class="br0">&#41;</span><span class="sy0">,</span> <span class="kw1">PRIMARY</span> <span class="kw1">KEY</span> <span class="br0">&#40;</span>id<span class="br0">&#41;</span><span class="br0">&#41;</span>;<br />
Query OK<span class="sy0">,</span> <span class="nu0">0</span> rows affected <span class="br0">&#40;</span><span class="nu0">0.09</span> sec<span class="br0">&#41;</span></div></div></div></p>
<p>El la columna del usuario al menos nos hace falta su correo electrónico, agreguémoslo:<br />
<div id="wpshdo_4" class="wp-synhighlighter-outer"><div id="wpshdt_4" class="wp-synhighlighter-expanded"><table border="0" width="100%"><tr><td align="left" width="80%"><a name="#codesyntax_4"></a><a id="wpshat_4" class="wp-synhighlighter-title" href="#codesyntax_4"  onClick="javascript:wpsh_toggleBlock(4)" title="Click to show/hide code block">Code block</a></td><td align="right"><a href="#codesyntax_4" onClick="javascript:wpsh_code(4)" title="Show code only"><img border="0" style="border: 0 none" src="http://thegaraged.org/wp-content/plugins/wp-synhighlight/themes/default/images/code.png" /></a>&nbsp;<a href="#codesyntax_4" onClick="javascript:wpsh_print(4)" title="Print code"><img border="0" style="border: 0 none" src="http://thegaraged.org/wp-content/plugins/wp-synhighlight/themes/default/images/printer.png" /></a>&nbsp;<a href="http://thegaraged.org/wp-content/plugins/wp-synhighlight/About.html" target="_blank" title="Show plugin information"><img border="0" style="border: 0 none" src="http://thegaraged.org/wp-content/plugins/wp-synhighlight/themes/default/images/info.gif" /></a>&nbsp;</td></tr></table></div><div id="wpshdi_4" class="wp-synhighlighter-inner" style="display: block;"><div class="sql" style="font-family:monospace;">mysql<span class="sy0">&gt;</span> <span class="kw1">ALTER</span> <span class="kw1">TABLE</span> user <span class="kw1">ADD</span> <span class="kw1">COLUMN</span> email varchar<span class="br0">&#40;</span>255<span class="br0">&#41;</span> after password;<br />
Query OK<span class="sy0">,</span> <span class="nu0">0</span> rows affected <span class="br0">&#40;</span><span class="nu0">0.18</span> sec<span class="br0">&#41;</span><br />
Records: <span class="nu0">0</span>  Duplicates: <span class="nu0">0</span>  Warnings: <span class="nu0">0</span></div></div></div></p>
<p>Ya estamos listos para empezar, posiblemente lo primero que queremos hacer es poder insertar una noticia, así que vamos a crear una paginita de captura. Para esto necesitamos crear el ambiente inicial:</p>
<div id="wpshdo_5" class="wp-synhighlighter-outer"><div id="wpshdt_5" class="wp-synhighlighter-expanded"><table border="0" width="100%"><tr><td align="left" width="80%"><a name="#codesyntax_5"></a><a id="wpshat_5" class="wp-synhighlighter-title" href="#codesyntax_5"  onClick="javascript:wpsh_toggleBlock(5)" title="Click to show/hide code block">Code block</a></td><td align="right"><a href="#codesyntax_5" onClick="javascript:wpsh_code(5)" title="Show code only"><img border="0" style="border: 0 none" src="http://thegaraged.org/wp-content/plugins/wp-synhighlight/themes/default/images/code.png" /></a>&nbsp;<a href="#codesyntax_5" onClick="javascript:wpsh_print(5)" title="Print code"><img border="0" style="border: 0 none" src="http://thegaraged.org/wp-content/plugins/wp-synhighlight/themes/default/images/printer.png" /></a>&nbsp;<a href="http://thegaraged.org/wp-content/plugins/wp-synhighlight/About.html" target="_blank" title="Show plugin information"><img border="0" style="border: 0 none" src="http://thegaraged.org/wp-content/plugins/wp-synhighlight/themes/default/images/info.gif" /></a>&nbsp;</td></tr></table></div><div id="wpshdi_5" class="wp-synhighlighter-inner" style="display: block;"><pre class="perl" style="font-family:monospace;"><a href="http://perldoc.perl.org/functions/package.html"><span class="kw3">package</span></a> Blog<span class="sy0">;</span>
<span class="kw2">use</span> strict<span class="sy0">;</span>
<span class="kw2">use</span> warnings<span class="sy0">;</span>
<span class="kw2">use</span> base <span class="st_h">'CGI::Application'</span><span class="sy0">;</span>
<span class="kw2">use</span> CGI<span class="sy0">::</span><span class="me2">Application</span><span class="sy0">::</span><span class="me2">Plugin</span><span class="sy0">::</span><span class="me2">AutoRunmode</span><span class="sy0">;</span>
<span class="kw2">use</span> CGI<span class="sy0">::</span><span class="me2">Application</span><span class="sy0">::</span><span class="me2">Plugin</span><span class="sy0">::</span><span class="me2">DBH</span> <span class="br0">&#40;</span><span class="co2">qw/dbh_config dbh/</span><span class="br0">&#41;</span><span class="sy0">;</span>
<span class="kw2">sub</span> cgiapp_init <span class="br0">&#123;</span>
<span class="kw1">my</span> <span class="re0">$self</span> <span class="sy0">=</span> <a href="http://perldoc.perl.org/functions/shift.html"><span class="kw3">shift</span></a><span class="sy0">;</span>
<span class="re0">$self</span><span class="sy0">-&gt;</span><span class="me1">dbh_config</span><span class="br0">&#40;</span><span class="st0">&quot;dbi:mysql:perlblog&quot;</span><span class="sy0">,</span> <span class="st0">&quot;blog&quot;</span><span class="sy0">,</span> <span class="st0">`20y1337`</span><span class="br0">&#41;</span><span class="sy0">;</span>
<span class="br0">&#125;</span>
<span class="kw2">sub</span> news_list <span class="sy0">:</span> StartRunmode <span class="br0">&#123;</span>
<span class="kw1">my</span> <span class="re0">$self</span> <span class="sy0">=</span> <a href="http://perldoc.perl.org/functions/shift.html"><span class="kw3">shift</span></a><span class="sy0">;</span>
<span class="kw1">my</span> <span class="re0">$q</span> <span class="sy0">=</span> <span class="re0">$self</span><span class="sy0">-&gt;</span><span class="me1">query</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
<span class="kw1">my</span> <span class="re0">$sth</span> <span class="sy0">=</span> <span class="re0">$self</span><span class="sy0">-&gt;</span><span class="me1">dbh</span><span class="sy0">-&gt;</span><span class="me1">prepare</span><span class="br0">&#40;</span><span class="st0">&quot;SELECT * FROM news ORDER BY posted DESC&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span>
<span class="re0">$sth</span><span class="sy0">-&gt;</span><span class="me1">execute</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
<span class="kw1">my</span> <span class="re0">@rows</span><span class="sy0">;</span>
<span class="kw1">while</span> <span class="br0">&#40;</span> <span class="kw1">my</span> <span class="re0">$row</span> <span class="sy0">=</span> <span class="re0">$sth</span><span class="sy0">-&gt;</span><span class="me1">fetchrow_hashref</span> <span class="br0">&#41;</span> <span class="br0">&#123;</span>
<a href="http://perldoc.perl.org/functions/push.html"><span class="kw3">push</span></a><span class="br0">&#40;</span><span class="re0">@rows</span><span class="sy0">,</span> <span class="re0">$row</span><span class="br0">&#41;</span><span class="sy0">;</span>
<span class="br0">&#125;</span>
<a href="http://perldoc.perl.org/functions/return.html"><span class="kw3">return</span></a> <span class="re0">@rows</span><span class="sy0">;</span>
<span class="br0">&#125;</span>
<span class="nu0">1</span><span class="sy0">;</span></pre></div></div>
<p>Con esto estamos armando el ambiente más mínimo posible, estamos creando un paquete que va a contener todas las rutinas que requiere la aplicación, y estamos usando uso de CGI::Application que será nuestra base para hacer prácticamente toda la programación.</p>
<p>La subrutina &#8220;cgiapp_init&#8221; es la encargada de inicializar todos los requerimientos, que por lo pronto solamente es la conección a la base de datos, para lo cual estamos usando un plugin para CGI::Application que se llama CGI::Application::Plugin::DBH, en síntesis es meterle la capa DBI directamente nuestro &#8220;framework&#8221;.</p>
<p>Para poder ejecutar lo que llevamos de aplicación tenemos que crear un script que ejecuta el paquete, lo cual es bastante sencillo, y no volveremos a tocarlo una vez escrito lo siguiente a &#8220;index.pl&#8221;:</p>
<div id="wpshdo_6" class="wp-synhighlighter-outer"><div id="wpshdt_6" class="wp-synhighlighter-expanded"><table border="0" width="100%"><tr><td align="left" width="80%"><a name="#codesyntax_6"></a><a id="wpshat_6" class="wp-synhighlighter-title" href="#codesyntax_6"  onClick="javascript:wpsh_toggleBlock(6)" title="Click to show/hide code block">Code block</a></td><td align="right"><a href="#codesyntax_6" onClick="javascript:wpsh_code(6)" title="Show code only"><img border="0" style="border: 0 none" src="http://thegaraged.org/wp-content/plugins/wp-synhighlight/themes/default/images/code.png" /></a>&nbsp;<a href="#codesyntax_6" onClick="javascript:wpsh_print(6)" title="Print code"><img border="0" style="border: 0 none" src="http://thegaraged.org/wp-content/plugins/wp-synhighlight/themes/default/images/printer.png" /></a>&nbsp;<a href="http://thegaraged.org/wp-content/plugins/wp-synhighlight/About.html" target="_blank" title="Show plugin information"><img border="0" style="border: 0 none" src="http://thegaraged.org/wp-content/plugins/wp-synhighlight/themes/default/images/info.gif" /></a>&nbsp;</td></tr></table></div><div id="wpshdi_6" class="wp-synhighlighter-inner" style="display: block;"><pre class="perl" style="font-family:monospace;"><span class="co1">#!/opt/local/bin/perl -w</span>
<span class="kw2">use</span> strict<span class="sy0">;</span>
<span class="kw2">use</span> warnings<span class="sy0">;</span>
<span class="kw2">use</span> Blog<span class="sy0">;</span>
<span class="kw1">my</span> <span class="re0">$app</span> <span class="sy0">=</span> Blog<span class="sy0">-&gt;</span><span class="me1">new</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
<span class="re0">$app</span><span class="sy0">-&gt;</span><span class="me1">run</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div>
<p>Noten que estoy usando un path para perl medio extraño, el 99% de los casos se usará el estandar &#8220;#!/usr/bin/perl -w&#8221;, yo uso ese pq me gusta más trabajar con el perl instalado por macports, el perl nativo de Mac OS X está medio chafita en algunos aspectos y prefiero algo más estandar, con suerte casi nadie que lea este post va a desarrollar sobre Mac <img src='http://thegaraged.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Una vez creados estos 2 archivos en el directorio de los &#8220;cgi-bin&#8221;, entonces visitamos en el navegador algo como http://localhost/cgi-bin/index.pl y vamos a ver un número entero, posiblemente cero, que será el número de renglones que existan en la columna &#8220;news&#8221; de la base de datos.</p>
<p>Con esto estamos aprendiendo un truco útil cuando estemos usando CGI::Application, siempre que quieras debugear algo, puedes poner un return de la variable que sea interesante, funciona como el típico &#8220;print&#8221; para debuguear, la diferencia es que el return termina en ese punto la ejecución de la rutina, y nos devuelve a la pantalla del navegador solamente el valor de dicha variable. Podríamos haber puesto &#8220;return &#8216;hola mundo&#8217;&#8221;, pero no sería tan divertido.<br />
Ahora insertemos un renglon en &#8220;news&#8221;, ejecutando:</p>
<div id="wpshdo_7" class="wp-synhighlighter-outer"><div id="wpshdt_7" class="wp-synhighlighter-expanded"><table border="0" width="100%"><tr><td align="left" width="80%"><a name="#codesyntax_7"></a><a id="wpshat_7" class="wp-synhighlighter-title" href="#codesyntax_7"  onClick="javascript:wpsh_toggleBlock(7)" title="Click to show/hide code block">Code block</a></td><td align="right"><a href="#codesyntax_7" onClick="javascript:wpsh_code(7)" title="Show code only"><img border="0" style="border: 0 none" src="http://thegaraged.org/wp-content/plugins/wp-synhighlight/themes/default/images/code.png" /></a>&nbsp;<a href="#codesyntax_7" onClick="javascript:wpsh_print(7)" title="Print code"><img border="0" style="border: 0 none" src="http://thegaraged.org/wp-content/plugins/wp-synhighlight/themes/default/images/printer.png" /></a>&nbsp;<a href="http://thegaraged.org/wp-content/plugins/wp-synhighlight/About.html" target="_blank" title="Show plugin information"><img border="0" style="border: 0 none" src="http://thegaraged.org/wp-content/plugins/wp-synhighlight/themes/default/images/info.gif" /></a>&nbsp;</td></tr></table></div><div id="wpshdi_7" class="wp-synhighlighter-inner" style="display: block;"><div class="sql" style="font-family:monospace;"><span class="kw1">INSERT</span> <span class="kw1">INTO</span> news <span class="kw1">VALUES</span> <span class="br0">&#40;</span><span class="kw1">NULL</span><span class="sy0">,</span> <span class="st0">'titulo 1'</span><span class="sy0">,</span> <span class="st0">'estes es un resumen'</span><span class="sy0">,</span> <span class="st0">'y esta es la noticia extendida'</span><span class="sy0">,</span> now<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">,</span> now<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">,</span> 1<span class="br0">&#41;</span>;</div></div></div>
<p>Si recargamos la página en el navegador veremos un &#8220;1&#8243;, nada excitante, pero podemos meterle más emoción retornando &#8220;$rows[0]{&#8216;title&#8217;}&#8221; en vez de &#8220;@rows&#8221;, con lo cual ahora veremos un excitante &#8220;titulo 1&#8243; !!! solo estamos demostrandonos a nosotros mismos que &#8220;podemos interactuar con una base de datos de verdad&#8221;.</p>
<p>Ahora vamos al paso de presentar esa información en un formato decenton, vamos a crear una plantilla en HTML muy sencilla, solo para llenar el requisito, una vez entendido todo el proceso, será trivial ir a buscar un diseño gratuito y adaptarlo.</p>
<div id="wpshdo_8" class="wp-synhighlighter-outer"><div id="wpshdt_8" class="wp-synhighlighter-expanded"><table border="0" width="100%"><tr><td align="left" width="80%"><a name="#codesyntax_8"></a><a id="wpshat_8" class="wp-synhighlighter-title" href="#codesyntax_8"  onClick="javascript:wpsh_toggleBlock(8)" title="Click to show/hide code block">Code block</a></td><td align="right"><a href="#codesyntax_8" onClick="javascript:wpsh_code(8)" title="Show code only"><img border="0" style="border: 0 none" src="http://thegaraged.org/wp-content/plugins/wp-synhighlight/themes/default/images/code.png" /></a>&nbsp;<a href="#codesyntax_8" onClick="javascript:wpsh_print(8)" title="Print code"><img border="0" style="border: 0 none" src="http://thegaraged.org/wp-content/plugins/wp-synhighlight/themes/default/images/printer.png" /></a>&nbsp;<a href="http://thegaraged.org/wp-content/plugins/wp-synhighlight/About.html" target="_blank" title="Show plugin information"><img border="0" style="border: 0 none" src="http://thegaraged.org/wp-content/plugins/wp-synhighlight/themes/default/images/info.gif" /></a>&nbsp;</td></tr></table></div><div id="wpshdi_8" class="wp-synhighlighter-inner" style="display: block;"><pre class="html4strict" style="font-family:monospace;"><span class="sc2">&lt;?xml <span class="kw3">version</span><span class="sy0">=</span><span class="st0">&quot;1.0&quot;</span> encoding<span class="sy0">=</span><span class="st0">&quot;UTF-8&quot;</span>?&gt;</span>
<span class="sc0">&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.1//EN&quot;</span>
<span class="sc0">&quot;http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd&quot;&gt;</span>
<span class="sc2">&lt;<a href="http://december.com/html/4/element/html.html"><span class="kw2">html</span></a> xmlns<span class="sy0">=</span><span class="st0">&quot;http://www.w3.org/1999/xhtml&quot;</span> xml:<span class="kw3">lang</span><span class="sy0">=</span><span class="st0">&quot;en&quot;</span> &gt;</span>
<span class="sc2">&lt;<a href="http://december.com/html/4/element/head.html"><span class="kw2">head</span></a>&gt;</span>
<span class="sc2">&lt;<a href="http://december.com/html/4/element/title.html"><span class="kw2">title</span></a>&gt;</span>[% title %]<span class="sc2">&lt;<span class="sy0">/</span><a href="http://december.com/html/4/element/title.html"><span class="kw2">title</span></a>&gt;</span>
<span class="sc2">&lt;<span class="sy0">/</span><a href="http://december.com/html/4/element/head.html"><span class="kw2">head</span></a>&gt;</span>
<span class="sc2">&lt;<a href="http://december.com/html/4/element/body.html"><span class="kw2">body</span></a>&gt;</span>
<span class="sc2">&lt;<a href="http://december.com/html/4/element/p.html"><span class="kw2">p</span></a>&gt;</span>[% title %]<span class="sc2">&lt;&lt;<span class="sy0">/</span><a href="http://december.com/html/4/element/p.html"><span class="kw2">p</span></a>&gt;</span>
<span class="sc2">&lt;<span class="sy0">/</span><a href="http://december.com/html/4/element/body.html"><span class="kw2">body</span></a>&gt;</span>
<span class="sc2">&lt;<span class="sy0">/</span><a href="http://december.com/html/4/element/html.html"><span class="kw2">html</span></a>&gt;</span></pre></div></div>
<p>Tenemos un documento básico de XHTML, pero noten que el título tiene algo extraño ([% title %]), es la presentación del contenido de una variable (title) en el &#8220;lenguaje&#8221; de Template Toolkit (TT), que será lo que utilizaremos para las plantillas.</p>
<p>El código de nuestro paquete necesita unos cambios ligeros, necesitamos inicializar el sistema de plantillas, y necesitamos decirle a &#8220;news_list&#8221; que interprete la plantilla &#8220;index.html&#8221;, vamos a agregar a la rutina &#8220;cgiapp_init&#8221; esto:</p>
<div id="wpshdo_9" class="wp-synhighlighter-outer"><div id="wpshdt_9" class="wp-synhighlighter-expanded"><table border="0" width="100%"><tr><td align="left" width="80%"><a name="#codesyntax_9"></a><a id="wpshat_9" class="wp-synhighlighter-title" href="#codesyntax_9"  onClick="javascript:wpsh_toggleBlock(9)" title="Click to show/hide code block">Code block</a></td><td align="right"><a href="#codesyntax_9" onClick="javascript:wpsh_code(9)" title="Show code only"><img border="0" style="border: 0 none" src="http://thegaraged.org/wp-content/plugins/wp-synhighlight/themes/default/images/code.png" /></a>&nbsp;<a href="#codesyntax_9" onClick="javascript:wpsh_print(9)" title="Print code"><img border="0" style="border: 0 none" src="http://thegaraged.org/wp-content/plugins/wp-synhighlight/themes/default/images/printer.png" /></a>&nbsp;<a href="http://thegaraged.org/wp-content/plugins/wp-synhighlight/About.html" target="_blank" title="Show plugin information"><img border="0" style="border: 0 none" src="http://thegaraged.org/wp-content/plugins/wp-synhighlight/themes/default/images/info.gif" /></a>&nbsp;</td></tr></table></div><div id="wpshdi_9" class="wp-synhighlighter-inner" style="display: block;"><div class="perl" style="font-family:monospace;"><span class="re0">$self</span><span class="sy0">-&gt;</span><span class="me1">tt_config</span><span class="br0">&#40;</span><br />
TEMPLATE_OPTIONS <span class="sy0">=&gt;</span> <span class="br0">&#123;</span><br />
INCLUDE_PATH <span class="sy0">=&gt;</span> <span class="st_h">'/Users/max/templates/'</span><span class="sy0">,</span><br />
<span class="br0">&#125;</span><span class="sy0">,</span><br />
<span class="br0">&#41;</span><span class="sy0">;</span></div></div></div>
<p>Y en &#8220;news_list&#8221; vamos a sustituir la última linea, la del return, por esto:</p>
<div id="wpshdo_10" class="wp-synhighlighter-outer"><div id="wpshdt_10" class="wp-synhighlighter-expanded"><table border="0" width="100%"><tr><td align="left" width="80%"><a name="#codesyntax_10"></a><a id="wpshat_10" class="wp-synhighlighter-title" href="#codesyntax_10"  onClick="javascript:wpsh_toggleBlock(10)" title="Click to show/hide code block">Code block</a></td><td align="right"><a href="#codesyntax_10" onClick="javascript:wpsh_code(10)" title="Show code only"><img border="0" style="border: 0 none" src="http://thegaraged.org/wp-content/plugins/wp-synhighlight/themes/default/images/code.png" /></a>&nbsp;<a href="#codesyntax_10" onClick="javascript:wpsh_print(10)" title="Print code"><img border="0" style="border: 0 none" src="http://thegaraged.org/wp-content/plugins/wp-synhighlight/themes/default/images/printer.png" /></a>&nbsp;<a href="http://thegaraged.org/wp-content/plugins/wp-synhighlight/About.html" target="_blank" title="Show plugin information"><img border="0" style="border: 0 none" src="http://thegaraged.org/wp-content/plugins/wp-synhighlight/themes/default/images/info.gif" /></a>&nbsp;</td></tr></table></div><div id="wpshdi_10" class="wp-synhighlighter-inner" style="display: block;"><div class="perl" style="font-family:monospace;"><span class="kw1">my</span> <span class="re0">$vars</span> <span class="sy0">=</span> <span class="br0">&#123;</span><br />
title <span class="sy0">=&gt;</span> <span class="st_h">'Soy el blog m&amp;aacute;s 1337'</span><span class="sy0">,</span><br />
rows <span class="sy0">=&gt;</span> <span class="re0">\@rows</span><span class="sy0">,</span><br />
<span class="br0">&#125;</span><span class="sy0">;</span><br />
<span class="co1">#return $rows[0]{'title'};</span><br />
<a href="http://perldoc.perl.org/functions/return.html"><span class="kw3">return</span></a> <span class="re0">$self</span><span class="sy0">-&gt;</span><span class="me1">tt_process</span><span class="br0">&#40;</span><span class="st_h">'index.html'</span><span class="sy0">,</span> <span class="re0">$vars</span><span class="br0">&#41;</span><span class="sy0">;</span></div></div></div>
<p>Con esto estamos mandandole a la plantilla 2 variables, aunque solo está utilizando una de ellas. Puedes darle &#8220;recargar&#8221;, &#8220;reload&#8221;, o como diga tu navegador <img src='http://thegaraged.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
<p>Ahora vamos a usar la segunda variable, que en realidad es una ·$&amp;%$&amp;/· referencia a un arreglo que tiene por elementos hashes (o arreglos asociativos), pa su madre no ?? como nota personal, odio las referencias en perl, siempre me confundo en que es una referencia y que no, pero bueno, sigamos.</p>
<p>Queremos cliclar sobre las noticias, pero solo hemos insertado una, inserta unas 2 o 3 más, incluso pueden usar exactamente los mismos datos que la primera, pero a veces ayuda tener una pista de que algo diferente se está haciendo, puedes cambiar el 1 por 2 y luego 3 y luego 4 en el título, y ya con eso tenemos.</p>
<p>Lo que haremos en la plantilla es agregar un ciclo sobre el arreglo &#8220;@rows&#8221;, no es nada complicado, queda más o menos así:</p>
<div id="wpshdo_11" class="wp-synhighlighter-outer"><div id="wpshdt_11" class="wp-synhighlighter-expanded"><table border="0" width="100%"><tr><td align="left" width="80%"><a name="#codesyntax_11"></a><a id="wpshat_11" class="wp-synhighlighter-title" href="#codesyntax_11"  onClick="javascript:wpsh_toggleBlock(11)" title="Click to show/hide code block">Code block</a></td><td align="right"><a href="#codesyntax_11" onClick="javascript:wpsh_code(11)" title="Show code only"><img border="0" style="border: 0 none" src="http://thegaraged.org/wp-content/plugins/wp-synhighlight/themes/default/images/code.png" /></a>&nbsp;<a href="#codesyntax_11" onClick="javascript:wpsh_print(11)" title="Print code"><img border="0" style="border: 0 none" src="http://thegaraged.org/wp-content/plugins/wp-synhighlight/themes/default/images/printer.png" /></a>&nbsp;<a href="http://thegaraged.org/wp-content/plugins/wp-synhighlight/About.html" target="_blank" title="Show plugin information"><img border="0" style="border: 0 none" src="http://thegaraged.org/wp-content/plugins/wp-synhighlight/themes/default/images/info.gif" /></a>&nbsp;</td></tr></table></div><div id="wpshdi_11" class="wp-synhighlighter-inner" style="display: block;"><pre class="html4strict" style="font-family:monospace;">.....
<span class="sc2">&lt;<a href="http://december.com/html/4/element/p.html"><span class="kw2">p</span></a>&gt;</span>[% title %]<span class="sc2">&lt;<span class="sy0">/</span><a href="http://december.com/html/4/element/p.html"><span class="kw2">p</span></a>&gt;</span>
[% FOREACH row IN rows %]
<span class="sc2">&lt;<a href="http://december.com/html/4/element/p.html"><span class="kw2">p</span></a>&gt;</span>[% row.title %] ([% row.posted %])<span class="sc2">&lt;<span class="sy0">/</span><a href="http://december.com/html/4/element/p.html"><span class="kw2">p</span></a>&gt;</span>
<span class="sc2">&lt;<a href="http://december.com/html/4/element/p.html"><span class="kw2">p</span></a>&gt;</span>[% row.summary %]<span class="sc2">&lt;<span class="sy0">/</span><a href="http://december.com/html/4/element/p.html"><span class="kw2">p</span></a>&gt;</span>
<span class="sc2">&lt;<a href="http://december.com/html/4/element/p.html"><span class="kw2">p</span></a>&gt;&lt;<a href="http://december.com/html/4/element/a.html"><span class="kw2">a</span></a> <span class="kw3">href</span><span class="sy0">=</span><span class="st0">&quot;index.pl?rm=view&amp;id=[% row.id%]&quot;</span>&gt;</span>Ver noticia<span class="sc2">&lt;<span class="sy0">/</span><a href="http://december.com/html/4/element/a.html"><span class="kw2">a</span></a>&gt;&lt;<span class="sy0">/</span><a href="http://december.com/html/4/element/p.html"><span class="kw2">p</span></a>&gt;</span>
....</pre></div></div>
<p>Con esto ya tenemos el listado de las noticias, ahora falta que podamos ver la noticia en extenso, y agregarle comentarios. Con el siguiente paso vamos a aprender como se definen más actividades a través de un solo módulo.</p>
<p>En el último cambio a la plantilla estamos agregando una liga, la cual contiene 2 variables con sus respectivos valores, &#8220;rm&#8221;, e &#8220;id&#8221;, el primero contiene el nombre de la rutina que se desea ejecutar en el módulo &#8220;Blog&#8221;, en este caso es &#8220;view&#8221;, y la segunda variable es el dato extra que necesitamos para saber cual noticia desean ver.</p>
<p>Lo que necesitamos ahora es tener la rutina &#8220;view&#8221;, donde vamos a seleccionar de la base de datos la noticia con el &#8220;id&#8221; que el usuario desea ver, y la vamos a mostrar en su respectiva plantilla.</p>
<p>La vista es sencilla, solamente tenemos que seleccionar el ID de la noticia que se desea ver, y mandarla a la plantilla:</p>
<p><div id="wpshdo_12" class="wp-synhighlighter-outer"><div id="wpshdt_12" class="wp-synhighlighter-expanded"><table border="0" width="100%"><tr><td align="left" width="80%"><a name="#codesyntax_12"></a><a id="wpshat_12" class="wp-synhighlighter-title" href="#codesyntax_12"  onClick="javascript:wpsh_toggleBlock(12)" title="Click to show/hide code block">Code block</a></td><td align="right"><a href="#codesyntax_12" onClick="javascript:wpsh_code(12)" title="Show code only"><img border="0" style="border: 0 none" src="http://thegaraged.org/wp-content/plugins/wp-synhighlight/themes/default/images/code.png" /></a>&nbsp;<a href="#codesyntax_12" onClick="javascript:wpsh_print(12)" title="Print code"><img border="0" style="border: 0 none" src="http://thegaraged.org/wp-content/plugins/wp-synhighlight/themes/default/images/printer.png" /></a>&nbsp;<a href="http://thegaraged.org/wp-content/plugins/wp-synhighlight/About.html" target="_blank" title="Show plugin information"><img border="0" style="border: 0 none" src="http://thegaraged.org/wp-content/plugins/wp-synhighlight/themes/default/images/info.gif" /></a>&nbsp;</td></tr></table></div><div id="wpshdi_12" class="wp-synhighlighter-inner" style="display: block;"><pre class="perl" style="font-family:monospace;"><span class="kw2">sub</span> view <span class="sy0">:</span> Runmode <span class="br0">&#123;</span>
<span class="kw1">my</span> <span class="re0">$self</span> <span class="sy0">=</span> <a href="http://perldoc.perl.org/functions/shift.html"><span class="kw3">shift</span></a><span class="sy0">;</span>
<span class="kw1">my</span> <span class="re0">$q</span> <span class="sy0">=</span> <span class="re0">$self</span><span class="sy0">-&gt;</span><span class="me1">query</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
<span class="kw1">my</span> <span class="re0">$sth</span> <span class="sy0">=</span> <span class="re0">$self</span><span class="sy0">-&gt;</span><span class="me1">dbh</span><span class="sy0">-&gt;</span><span class="me1">prepare</span><span class="br0">&#40;</span><span class="st0">&quot;SELECT * FROM news where id = ?&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span>
<span class="re0">$sth</span><span class="sy0">-&gt;</span><span class="me1">execute</span><span class="br0">&#40;</span><span class="re0">$q</span><span class="sy0">-&gt;</span><span class="me1">param</span><span class="br0">&#40;</span><span class="st_h">'id'</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span>
<span class="kw1">my</span> <span class="re0">$row</span> <span class="sy0">=</span> <span class="re0">$sth</span><span class="sy0">-&gt;</span><span class="me1">fetchrow_hashref</span><span class="sy0">;</span>
<span class="kw1">my</span> <span class="re0">$vars</span> <span class="sy0">=</span> <span class="br0">&#123;</span>
title <span class="sy0">=&gt;</span> <span class="re0">$row</span><span class="sy0">-&gt;</span><span class="br0">&#123;</span><span class="st_h">'title'</span><span class="br0">&#125;</span><span class="sy0">,</span>
row <span class="sy0">=&gt;</span> <span class="re0">$row</span><span class="sy0">,</span>
<span class="br0">&#125;</span><span class="sy0">;</span>
<a href="http://perldoc.perl.org/functions/return.html"><span class="kw3">return</span></a> <span class="re0">$self</span><span class="sy0">-&gt;</span><span class="me1">tt_process</span><span class="br0">&#40;</span><span class="st_h">'view.html'</span><span class="sy0">,</span> <span class="re0">$vars</span><span class="br0">&#41;</span><span class="sy0">;</span>
<span class="br0">&#125;</span></pre></div></div><br />
Podemos ver que la vista se define solamente con &#8220;Runmode&#8221;, esto quiere decir que este módulo solo se va a ejecutar cuando sea llamado explícitamente (rm=view en GET). Y la plantilla puede ser tan sencilla como esto:<br />
<div id="wpshdo_13" class="wp-synhighlighter-outer"><div id="wpshdt_13" class="wp-synhighlighter-expanded"><table border="0" width="100%"><tr><td align="left" width="80%"><a name="#codesyntax_13"></a><a id="wpshat_13" class="wp-synhighlighter-title" href="#codesyntax_13"  onClick="javascript:wpsh_toggleBlock(13)" title="Click to show/hide code block">Code block</a></td><td align="right"><a href="#codesyntax_13" onClick="javascript:wpsh_code(13)" title="Show code only"><img border="0" style="border: 0 none" src="http://thegaraged.org/wp-content/plugins/wp-synhighlight/themes/default/images/code.png" /></a>&nbsp;<a href="#codesyntax_13" onClick="javascript:wpsh_print(13)" title="Print code"><img border="0" style="border: 0 none" src="http://thegaraged.org/wp-content/plugins/wp-synhighlight/themes/default/images/printer.png" /></a>&nbsp;<a href="http://thegaraged.org/wp-content/plugins/wp-synhighlight/About.html" target="_blank" title="Show plugin information"><img border="0" style="border: 0 none" src="http://thegaraged.org/wp-content/plugins/wp-synhighlight/themes/default/images/info.gif" /></a>&nbsp;</td></tr></table></div><div id="wpshdi_13" class="wp-synhighlighter-inner" style="display: block;"><pre class="html4strict" style="font-family:monospace;"><span class="sc2">&lt;<a href="http://december.com/html/4/element/p.html"><span class="kw2">p</span></a>&gt;</span>[% title %]<span class="sc2">&lt;<span class="sy0">/</span><a href="http://december.com/html/4/element/p.html"><span class="kw2">p</span></a>&gt;</span>
<span class="sc2">&lt;<a href="http://december.com/html/4/element/div.html"><span class="kw2">div</span></a>&gt;</span>
<span class="sc2">&lt;<a href="http://december.com/html/4/element/h1.html"><span class="kw2">h1</span></a>&gt;</span>[% row.title|html %] ([% row.posted|html %])<span class="sc2">&lt;<span class="sy0">/</span><a href="http://december.com/html/4/element/h1.html"><span class="kw2">h1</span></a>&gt;</span>
<span class="sc2">&lt;<a href="http://december.com/html/4/element/h2.html"><span class="kw2">h2</span></a>&gt;</span>[% row.summary|html %]<span class="sc2">&lt;<span class="sy0">/</span><a href="http://december.com/html/4/element/h2.html"><span class="kw2">h2</span></a>&gt;</span>
<span class="sc2">&lt;<a href="http://december.com/html/4/element/div.html"><span class="kw2">div</span></a>&gt;</span>[% row.news|html %]<span class="sc2">&lt;<span class="sy0">/</span><a href="http://december.com/html/4/element/div.html"><span class="kw2">div</span></a>&gt;</span>
<span class="sc2">&lt;<a href="http://december.com/html/4/element/p.html"><span class="kw2">p</span></a>&gt;&lt;<a href="http://december.com/html/4/element/a.html"><span class="kw2">a</span></a> <span class="kw3">href</span><span class="sy0">=</span><span class="st0">&quot;index.pl&quot;</span>&gt;</span>Ir al Inicio<span class="sc2">&lt;<span class="sy0">/</span><a href="http://december.com/html/4/element/a.html"><span class="kw2">a</span></a>&gt;&lt;<span class="sy0">/</span><a href="http://december.com/html/4/element/p.html"><span class="kw2">p</span></a>&gt;</span>
<span class="sc2">&lt;<span class="sy0">/</span><a href="http://december.com/html/4/element/div.html"><span class="kw2">div</span></a>&gt;</span></pre></div></div><br />
Con esto tenemos la base de la aplicación, pero solo visualmente, todavía no podemos mandar comentarios, ni mandar noticias.<br />
Lo que necesitamos hacer es crear una forma en la plantilla, y recibir en una vista lo que se envía por POST. El modulo &#8220;view&#8221; cambia un poco, queda mas o menos como esto:<br />
<div id="wpshdo_14" class="wp-synhighlighter-outer"><div id="wpshdt_14" class="wp-synhighlighter-expanded"><table border="0" width="100%"><tr><td align="left" width="80%"><a name="#codesyntax_14"></a><a id="wpshat_14" class="wp-synhighlighter-title" href="#codesyntax_14"  onClick="javascript:wpsh_toggleBlock(14)" title="Click to show/hide code block">Code block</a></td><td align="right"><a href="#codesyntax_14" onClick="javascript:wpsh_code(14)" title="Show code only"><img border="0" style="border: 0 none" src="http://thegaraged.org/wp-content/plugins/wp-synhighlight/themes/default/images/code.png" /></a>&nbsp;<a href="#codesyntax_14" onClick="javascript:wpsh_print(14)" title="Print code"><img border="0" style="border: 0 none" src="http://thegaraged.org/wp-content/plugins/wp-synhighlight/themes/default/images/printer.png" /></a>&nbsp;<a href="http://thegaraged.org/wp-content/plugins/wp-synhighlight/About.html" target="_blank" title="Show plugin information"><img border="0" style="border: 0 none" src="http://thegaraged.org/wp-content/plugins/wp-synhighlight/themes/default/images/info.gif" /></a>&nbsp;</td></tr></table></div><div id="wpshdi_14" class="wp-synhighlighter-inner" style="display: block;"><pre class="perl" style="font-family:monospace;"><span class="kw2">sub</span> view <span class="sy0">:</span> Runmode <span class="br0">&#123;</span>
    <span class="kw1">my</span> <span class="re0">$self</span> <span class="sy0">=</span> <a href="http://perldoc.perl.org/functions/shift.html"><span class="kw3">shift</span></a><span class="sy0">;</span>
    <span class="kw1">my</span> <span class="re0">$sth</span><span class="sy0">;</span>
    <span class="kw1">my</span> <span class="re0">$q</span> <span class="sy0">=</span> <span class="re0">$self</span><span class="sy0">-&gt;</span><span class="me1">query</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
    <span class="kw1">if</span> <span class="br0">&#40;</span> <span class="re0">$q</span><span class="sy0">-&gt;</span><span class="me1">param</span><span class="br0">&#40;</span><span class="st_h">'submit'</span><span class="br0">&#41;</span> <span class="br0">&#41;</span> <span class="br0">&#123;</span> <span class="co1"># POST METHOD, let's save the comment</span>
        <span class="re0">$sth</span> <span class="sy0">=</span> <span class="re0">$self</span><span class="sy0">-&gt;</span><span class="me1">dbh</span><span class="sy0">-&gt;</span><span class="me1">prepare</span><span class="br0">&#40;</span><span class="st0">&quot;INSERT INTO comment (title, comment, posted, last_edit, user_id, name, em
ail, news_id) VALUES ( ?, ?, now(), now(), 0, ?, ?, ?)&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span>
        <span class="re0">$sth</span><span class="sy0">-&gt;</span><span class="me1">execute</span><span class="br0">&#40;</span> <span class="re0">$q</span><span class="sy0">-&gt;</span><span class="me1">param</span><span class="br0">&#40;</span><span class="st_h">'title'</span><span class="br0">&#41;</span><span class="sy0">,</span> <span class="re0">$q</span><span class="sy0">-&gt;</span><span class="me1">param</span><span class="br0">&#40;</span><span class="st_h">'comment'</span><span class="br0">&#41;</span><span class="sy0">,</span> <span class="re0">$q</span><span class="sy0">-&gt;</span><span class="me1">param</span><span class="br0">&#40;</span><span class="st_h">'name'</span><span class="br0">&#41;</span><span class="sy0">,</span> <span class="re0">$q</span><span class="sy0">-&gt;</span><span class="me1">param</span><span class="br0">&#40;</span><span class="st_h">'email'</span><span class="br0">&#41;</span><span class="sy0">,</span> <span class="re0">$q</span><span class="sy0">-&gt;</span><span class="me1">param</span><span class="br0">&#40;</span><span class="st_h">'id'</span><span class="br0">&#41;</span>
        <span class="br0">&#41;</span><span class="sy0">;</span>
    <span class="br0">&#125;</span>
    <span class="re0">$sth</span> <span class="sy0">=</span> <span class="re0">$self</span><span class="sy0">-&gt;</span><span class="me1">dbh</span><span class="sy0">-&gt;</span><span class="me1">prepare</span><span class="br0">&#40;</span><span class="st0">&quot;SELECT * FROM news WHERE id = ?&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span>
    <span class="re0">$sth</span><span class="sy0">-&gt;</span><span class="me1">execute</span><span class="br0">&#40;</span><span class="re0">$q</span><span class="sy0">-&gt;</span><span class="me1">param</span><span class="br0">&#40;</span><span class="st_h">'id'</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span>
    <span class="kw1">my</span> <span class="re0">$row</span> <span class="sy0">=</span> <span class="re0">$sth</span><span class="sy0">-&gt;</span><span class="me1">fetchrow_hashref</span><span class="sy0">;</span>
    <span class="re0">$sth</span> <span class="sy0">=</span> <span class="re0">$self</span><span class="sy0">-&gt;</span><span class="me1">dbh</span><span class="sy0">-&gt;</span><span class="me1">prepare</span><span class="br0">&#40;</span><span class="st0">&quot;SELECT * FROM comment WHERE news_id = ? ORDER BY posted DESC&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span>
    <span class="re0">$sth</span><span class="sy0">-&gt;</span><span class="me1">execute</span><span class="br0">&#40;</span><span class="re0">$q</span><span class="sy0">-&gt;</span><span class="me1">param</span><span class="br0">&#40;</span><span class="st_h">'id'</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span>
    <span class="kw1">my</span> <span class="re0">@comms</span><span class="sy0">;</span>
    <span class="kw1">while</span> <span class="br0">&#40;</span> <span class="kw1">my</span> <span class="re0">$comm</span> <span class="sy0">=</span> <span class="re0">$sth</span><span class="sy0">-&gt;</span><span class="me1">fetchrow_hashref</span> <span class="br0">&#41;</span> <span class="br0">&#123;</span>
        <a href="http://perldoc.perl.org/functions/push.html"><span class="kw3">push</span></a><span class="br0">&#40;</span><span class="re0">@comms</span><span class="sy0">,</span> <span class="re0">$comm</span><span class="br0">&#41;</span><span class="sy0">;</span>
    <span class="br0">&#125;</span>
    <span class="kw1">my</span> <span class="re0">$num_c</span> <span class="sy0">=</span> <span class="re0">@comms</span><span class="sy0">;</span>
    <span class="kw1">my</span> <span class="re0">$vars</span> <span class="sy0">=</span> <span class="br0">&#123;</span>
        title <span class="sy0">=&gt;</span> <span class="re0">$row</span><span class="sy0">-&gt;</span><span class="br0">&#123;</span><span class="st_h">'title'</span><span class="br0">&#125;</span><span class="sy0">,</span>
        num_c <span class="sy0">=&gt;</span> <span class="re0">$num_c</span><span class="sy0">,</span>
        row <span class="sy0">=&gt;</span> <span class="re0">$row</span><span class="sy0">,</span>
        comms <span class="sy0">=&gt;</span> <span class="re0">\@comms</span><span class="sy0">,</span>
    <span class="br0">&#125;</span><span class="sy0">;</span>
    <a href="http://perldoc.perl.org/functions/return.html"><span class="kw3">return</span></a> <span class="re0">$self</span><span class="sy0">-&gt;</span><span class="me1">tt_process</span><span class="br0">&#40;</span><span class="st_h">'view.html'</span><span class="sy0">,</span> <span class="re0">$vars</span><span class="br0">&#41;</span><span class="sy0">;</span>
<span class="br0">&#125;</span></pre></div></div><br />
Con esto está casi completo el objetivo de este pequeño tutorial, pero falta una parte importante, la autenticación, pero como estamos haciendo todo al menor estilo de CGI::Application, solo tenemos que agregar unas cuantas lineas:<br />
<div id="wpshdo_15" class="wp-synhighlighter-outer"><div id="wpshdt_15" class="wp-synhighlighter-expanded"><table border="0" width="100%"><tr><td align="left" width="80%"><a name="#codesyntax_15"></a><a id="wpshat_15" class="wp-synhighlighter-title" href="#codesyntax_15"  onClick="javascript:wpsh_toggleBlock(15)" title="Click to show/hide code block">Code block</a></td><td align="right"><a href="#codesyntax_15" onClick="javascript:wpsh_code(15)" title="Show code only"><img border="0" style="border: 0 none" src="http://thegaraged.org/wp-content/plugins/wp-synhighlight/themes/default/images/code.png" /></a>&nbsp;<a href="#codesyntax_15" onClick="javascript:wpsh_print(15)" title="Print code"><img border="0" style="border: 0 none" src="http://thegaraged.org/wp-content/plugins/wp-synhighlight/themes/default/images/printer.png" /></a>&nbsp;<a href="http://thegaraged.org/wp-content/plugins/wp-synhighlight/About.html" target="_blank" title="Show plugin information"><img border="0" style="border: 0 none" src="http://thegaraged.org/wp-content/plugins/wp-synhighlight/themes/default/images/info.gif" /></a>&nbsp;</td></tr></table></div><div id="wpshdi_15" class="wp-synhighlighter-inner" style="display: block;"><pre class="perl" style="font-family:monospace;"><span class="kw2">use</span> CGI<span class="sy0">::</span><span class="me2">Application</span><span class="sy0">::</span><span class="me2">Plugin</span><span class="sy0">::</span><span class="me2">Session</span><span class="sy0">;</span>
<span class="kw2">use</span> CGI<span class="sy0">::</span><span class="me2">Application</span><span class="sy0">::</span><span class="me2">Plugin</span><span class="sy0">::</span><span class="me2">Authentication</span><span class="sy0">;</span>
Blog<span class="sy0">-&gt;</span><span class="me1">authen</span><span class="sy0">-&gt;</span><span class="me1">config</span><span class="br0">&#40;</span>
    DRIVER <span class="sy0">=&gt;</span> <span class="br0">&#91;</span>
    <span class="st_h">'DBI'</span><span class="sy0">,</span>
    TABLE <span class="sy0">=&gt;</span> <span class="st_h">'user'</span><span class="sy0">,</span>    CONSTRAINTS <span class="sy0">=&gt;</span> <span class="br0">&#123;</span>
        <span class="st_h">'user.login'</span> <span class="sy0">=&gt;</span> <span class="st_h">'__CREDENTIAL_1__'</span><span class="sy0">,</span>
        <span class="st_h">'MD5:user.password'</span> <span class="sy0">=&gt;</span> <span class="st_h">'__CREDENTIAL_2__'</span><span class="sy0">,</span>
    <span class="br0">&#125;</span><span class="sy0">,</span>
    <span class="br0">&#93;</span><span class="sy0">,</span>
    LOGOUT_URL <span class="sy0">=&gt;</span> <span class="st_h">'http://latin.example.com/cgi-bin/index.pl'</span><span class="sy0">,</span>
    STORE <span class="sy0">=&gt;</span> <span class="st_h">'Session'</span><span class="sy0">,</span>
<span class="br0">&#41;</span><span class="sy0">;</span>
Blog<span class="sy0">-&gt;</span><span class="me1">authen</span><span class="sy0">-&gt;</span><span class="me1">protected_runmodes</span><span class="br0">&#40;</span><a href="http://perldoc.perl.org/functions/qw.html"><span class="kw3">qw</span></a><span class="br0">&#40;</span>view<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div><br />
y un hacer un INSERT en la tabla &#8220;user&#8221;:<br />
<div id="wpshdo_16" class="wp-synhighlighter-outer"><div id="wpshdt_16" class="wp-synhighlighter-expanded"><table border="0" width="100%"><tr><td align="left" width="80%"><a name="#codesyntax_16"></a><a id="wpshat_16" class="wp-synhighlighter-title" href="#codesyntax_16"  onClick="javascript:wpsh_toggleBlock(16)" title="Click to show/hide code block">Code block</a></td><td align="right"><a href="#codesyntax_16" onClick="javascript:wpsh_code(16)" title="Show code only"><img border="0" style="border: 0 none" src="http://thegaraged.org/wp-content/plugins/wp-synhighlight/themes/default/images/code.png" /></a>&nbsp;<a href="#codesyntax_16" onClick="javascript:wpsh_print(16)" title="Print code"><img border="0" style="border: 0 none" src="http://thegaraged.org/wp-content/plugins/wp-synhighlight/themes/default/images/printer.png" /></a>&nbsp;<a href="http://thegaraged.org/wp-content/plugins/wp-synhighlight/About.html" target="_blank" title="Show plugin information"><img border="0" style="border: 0 none" src="http://thegaraged.org/wp-content/plugins/wp-synhighlight/themes/default/images/info.gif" /></a>&nbsp;</td></tr></table></div><div id="wpshdi_16" class="wp-synhighlighter-inner" style="display: block;"><pre class="sql" style="font-family:monospace;"><span class="kw1">INSERT</span> <span class="kw1">INTO</span> user <span class="kw1">VALUES</span> <span class="br0">&#40;</span><span class="kw1">NULL</span><span class="sy0">,</span> <span class="st0">'admin'</span><span class="sy0">,</span> MD5<span class="br0">&#40;</span><span class="st0">'admin'</span><span class="br0">&#41;</span><span class="sy0">,</span> <span class="st0">'email@example.com'</span><span class="sy0">,</span> <span class="st0">'Admin'</span><span class="sy0">,</span> now<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">,</span> now<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;</pre></div></div><br />
El módulo de autenticación tiene la capacidad de reusar la instancia de DBI, y además nos crea una página de logueo, e incluso redirecciona &#8220;inteligentemente&#8221; a la página que estabamos tratando de accesar. La información que ponemos en su inicialización es la estrictamente necesaria, la tabla donde están las columnas de usuario y clave, las columnas, el método de &#8220;encriptación&#8221;, y por supuesto el método que se usará para autenticar, no tiene que ser una base de datos escrictamente, se puede crear un driver personalizado para soportar cosas más exóticas. </p>
<p>Y finalmente un punto importante que debemos notar, el uso de sesión, es necesario que guardemos en sesión los datos de autenticación, o el usuario final va a tener que estar metiendo su nombre usuario y clave con demasiada frecuencia, con solo agregar el módulo de session, y decirle al driver de autenticación que guarde las variables en él, ya tenemos un método de autenticación completo y funcional.</p>
<p>Noten que solo estoy poniendo como protegido al módulo &#8220;view&#8221;, podemos poner a cualquier módulo protegido, (ej. qw(view list otro_modulo) pero normalmente la lista de noticias nos gusta mantenerla pública, y de hecho normalmente la vista extendida de la noticia también, pero en este caso tenemos en el mísmo módulo tanto la vista extensa, como el agregar comentarios, es una buena idea separar los comentarios en otro módulo, de tal manera que podamos atomizar mejor los privilegios sobre la página.</p>
<p>Obviamente este ejemplo es muy mínimo, y se ve terriblemente mal, porque no tiene ni siquiera CSS, pero todo eso se corrige con la ayuda de un diseñador, los programadores no somos buenos diseñadores, así que pa que le hacemos al cuento? (tip: baja una plantilla gratuita de algun sitio <img src='http://thegaraged.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Espero que a alguien le parezca interesante este resumen de cómo usar CGI::Application, la documentación es bastante buena, pero cada módulo está documentado independientemente, y a veces es un poco complicado para alguien (como yo) de encontrarle la hilación, pero una vez que se entiende la base, lo demás es muy sencillo.<br />
Ah !!, y una de las grandes ventajas de usar CGI::Application es que fácilmente se puede montar tanto sobre CGI como en mod_perl, aunque nunca he usado mod_perl <img src='http://thegaraged.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> , pero en teoría no hay prácticamente nada que hacer para que funcione en ambos.</p>
<p>Eso es todo amigos, buen día <img src='http://thegaraged.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fthegaraged.org%2F2009%2F07%2F14%2Fcgiaplication-el-fino-arte-de-hacer-web-perl-style&amp;linkname=CGI%3A%3AAplication%20el%20fino%20arte%20de%20hacer%20web%20perl-style"><img src="http://thegaraged.org/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a> </p>]]></content:encoded>
			<wfw:commentRss>http://thegaraged.org/2009/07/14/cgiaplication-el-fino-arte-de-hacer-web-perl-style/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>
