<?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>/dev/GON.cl &#187; Zend Framework</title>
	<atom:link href="http://blog.gon.cl/cat/development/php/zf/feed" rel="self" type="application/rss+xml" />
	<link>http://blog.gon.cl</link>
	<description>blog respaldo anti-amnesia</description>
	<lastBuildDate>Thu, 12 Jan 2012 19:03:18 +0000</lastBuildDate>
	<language>es</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Gonium tiene nuevo blog</title>
		<link>http://blog.gon.cl/post/402</link>
		<comments>http://blog.gon.cl/post/402#comments</comments>
		<pubDate>Mon, 29 Dec 2008 09:52:23 +0000</pubDate>
		<dc:creator>gon</dc:creator>
				<category><![CDATA[wordpress]]></category>
		<category><![CDATA[Zend Framework]]></category>
		<category><![CDATA[blog]]></category>
		<category><![CDATA[gonium]]></category>
		<category><![CDATA[temas wordpress]]></category>

		<guid isPermaLink="false">http://blog.gon.cl/?p=402</guid>
		<description><![CDATA[Ya que tengo espacio, hay que aprovecharlo. Un lugar donde explicar las cosas Mientras no tengo un m&#243;dulo de para blogear funcional en Gonium, no me queda otra que usar al enemigo (WordPress). Lo cual no es del todo malo, sino justamente lo contrario. La idea de tener un blog exclusivamente para el desarrollo de [...]]]></description>
			<content:encoded><![CDATA[<p>Ya que tengo espacio, hay que aprovecharlo.</p>
<h2>Un lugar donde explicar las cosas</h2>
<p>Mientras no tengo un m&oacute;dulo de para blogear funcional en Gonium, no me queda otra que usar al enemigo (WordPress). Lo cual no es del todo malo, sino justamente lo contrario.</p>
<p><a href="http://gon.boaboa.org/wblog/"><img class="aligncenter size-full wp-image-400" title="gonium_blog_120x60" src="http://blog.gon.cl/wp-content/uploads/2008/12/gonium_blog_120x60.png" alt="gonium_blog_120x60" width="120" height="60" /></a></p>
<p>La idea de tener un blog exclusivamente para el desarrollo de Gonium, me permitir&aacute; poder dejar en claro cuales son las ideas que se est&aacute;n implementando o se desarrollaran a futuro, all&aacute; en su propio lugar. Hay mucho por hacer, por lo tanto, mantener una bit&aacute;cora de desarrollo (m&aacute;s que un precario Roadmap), espero me sirva mucho m&aacute;s.</p>
<p>Un detalle importante: el blog,  el proyecto en Google en Code, los mensajes en Twitter, los commits de svn e incluso la documentaci&oacute;n autogenerada del API, se mantendr&aacute;n todos en idioma ingl&eacute;s principalmente.</p>
<p>La raz&oacute;n de esto es muy sencilla: <strong>universalidad</strong>. Aunque no me gusta la idea, lamentablemente en comunicaciones, el ingl&eacute;s es lo m&aacute;s universal. No por ser de origen chileno quisiera que solo alg&uacute;n amigo m&iacute;o de ac&aacute; lo ocupe. Espero que a todo a quien le sirva tenga la posibilidad de ocuparlo. &iquest;Quien me dice que alguien por ah&iacute; no estar&aacute; ya husmeando el c&oacute;digo? &iquest;Y si este alguien hablara en italiano? &iquest;O franc&eacute;s? &iquest;o alem&aacute;n? &iquest;o chino?</p>
<p>Adem&aacute;s, habiendo tenido experiencia en el proyecto <a href="http://gdt.sourceforge.net">GDT</a>, not&eacute; como muchos usuarios, aun cuando en su mayor&iacute;a se trataba de hispano-parlantes, simplemente no les gust&oacute; la idea de usar objetos y m&eacute;todos nombrados en espa&ntilde;ol. No entiendo estas ma&ntilde;as, pero se que son frecuentes y extendidas. De hecho, <a href="http://edsiper.linuxchile.cl/blog/">Eduardo Silva</a>, en su charla de <a href="http://monkeyd.sourceforge.net/blog/">Monkey HTTP Daemon</a> en el <a href="http://2008.encuentrolinux.cl/">Encuentro Linux</a>, mencion&oacute; haber tenido ese problema con los hispano-parlantes, as&iacute; que decidi&oacute; simplemente dejar todo, lista de correo, blog, documentaci&oacute;n, etc, en ingl&eacute;s. Esta vez, adoptar&eacute; la misma idea y ver&eacute; que sucede.</p>
<p>Por el momento, no espero una explosi&oacute;n de usuarios, ni mucho menos mientras la versi&oacute;n funcional brilla por su ausencia, pero s&iacute; espero ideas, comentarios y en general <strong>feedback.</strong> Ya me han estado preguntando cosas como &#8220;&iquest;est&aacute;s reclutando gente?&#8221;, lo cual es un alivio para esos minutos en que me cuestiono el &#8220;&iquest;para que diablos estoy haciendo algo que solo me importa a m&iacute;?&#8221;. Por si acaso, s&iacute; estoy reclutando gente <img src='http://blog.gon.cl/wp-content/plugins/smilies-themer/GON/=B_1.gif' alt=':B' class='wp-smiley' /> . &iquest;Desarrolladores en Zend Framework? Bienvenidos! Cualquier tipo de aporte ser&aacute; igualmente bien recibido, ya sea de parte de un <strong>PHP</strong>ero, <strong>jQuery</strong>sta, <strong>CSS</strong>ero, Traductor, Dise&ntilde;ador o Art&iacute;sta son plenamente bienvenidos.</p>
<p><span id="more-402"></span></p>
<h2>Confirmando lo que pensaba</h2>
<p>Gracias a todo esto, tuve una ocurrencia del tipo &#8220;oh, &iquest;y si hago que el template de wordpress sea el mismo que el de Gonium?&#8221;. Con eso basto para ponerme a meter un poco de mano en la creaci&oacute;n de un tema. Nuevamente confirmo lo que pens&eacute; hace mucho tiempo atr&aacute;s acerca de wordpress, es espagetti.</p>
<p>Realmente es una de las APIs (si es que puede siquiera llamarse as&iacute; a su &#8220;codex&#8221;) m&aacute;s espantosas que he visto. Gracias a que participo en tecnosquad.org y a que dedicamos un d&iacute;a para &#8220;la &eacute;pica b&uacute;squeda de un tema nuevo&#8221;, fue como aquella tarde recolecte bastantes temas atractivos y los guarde &#8220;por si acaso&#8221;. Finalmente no encontramos nada que nos hiciera sentir ese &#8220;wow, es tema est&aacute; pintado para tecnosquad&#8221;, pero igualmente la b&uacute;squeda me trajo un buen producto.</p>
<p>Ocupe uno de esos temas para codear el mio. Entonces fue cuando note la importancia de ciertos detalles.</p>
<p>El primero es sobre el tama&ntilde;o de un tema. Por ejemplo los temas m&aacute;s &#8220;profesionales&#8221; suelen tener m&aacute;s archivos e incluso permiten agregar paneles de opciones al backend de wordpress. En esos archivos extra, los temas definen sus propias funciones, las cuales no tienen ninguna interfaz com&uacute;n, cada tema implementa sus cosas a su pinta. Algunos usaban clases/objetos, pero la mayor&iacute;a solo funciones sueltas.</p>
<p>Otro detalle importante, es que aun cuando las funciones &#8220;del n&uacute;cleo&#8221; para plantillas est&aacute;n documentadas, el solo hecho de leer un archivo fuente resulta ca&oacute;tico. Casi nada de pulcritud, incluso me atrevo a aventurar que ning&uacute;n tema de los que termine bajando (y fueron muchos), ni si quiera ten&iacute;an el c&oacute;digo propiamente indentado.</p>
<p>Una de las primeras cosas que aprend&iacute; con el Zend Framework, fue el patr&oacute;n de dise&ntilde;o &#8220;Two Steps&#8221; para plantillas, es decir, una plantilla &#8220;layout&#8221; que crea el esqueleto de la p&aacute;gina, y luego se agregan los contenidos sobre este layout, que pueden provenir de otros scripts de vista. En wordpress, simplemente no existe tal cosa. No quise mirar m&aacute;s hacia adentro del c&oacute;digo, pero lo que vi por fuera (las plantillas), me dan m&aacute;s ganas de &#8220;terminar&#8221; de una vez una versi&oacute;n usable de Gonium. Estoy seguro que ser&iacute;a una delicia para los dise&ntilde;adores.</p>
<p>M&aacute;s tarde, cuando ya pueda blogear tranquilo en Gonium, migrar&eacute; el contenido y me deshar&eacute; del wordpress. La idea principal est&aacute; m&aacute;s viva que nunca: el objetivo es crear un administrador de contenido de prop&oacute;sito general, pero BIEN HECHO.</p>
<div class="bottomcontainerBox" style="">
			<div style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;">
			<iframe src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fblog.gon.cl%2Fpost%2F402&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width=85px; height:21px;" allowTransparency="true"></iframe></div>
			<div style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;">
			<g:plusone size="medium" href="http://blog.gon.cl/post/402"></g:plusone>
			</div>
			<div style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;">
			<a href="http://twitter.com/share" class="twitter-share-button" data-url="http://blog.gon.cl/post/402"  data-text="Gonium tiene nuevo blog" data-count="horizontal" data-via="sir_gon">Tweet</a>
			</div>			
			</div><div style="clear:both"></div><div style="padding-bottom:4px;"></div>]]></content:encoded>
			<wfw:commentRss>http://blog.gon.cl/post/402/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Gonium, nuevo demo y nuevos componentes</title>
		<link>http://blog.gon.cl/post/357</link>
		<comments>http://blog.gon.cl/post/357#comments</comments>
		<pubDate>Thu, 11 Dec 2008 04:17:46 +0000</pubDate>
		<dc:creator>gon</dc:creator>
				<category><![CDATA[Zend Framework]]></category>
		<category><![CDATA[datagrid]]></category>
		<category><![CDATA[docbook]]></category>
		<category><![CDATA[gonium]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[php5]]></category>
		<category><![CDATA[phpdocumentor]]></category>
		<category><![CDATA[xml]]></category>
		<category><![CDATA[zend framework]]></category>

		<guid isPermaLink="false">http://blog.gon.cl/?p=357</guid>
		<description><![CDATA[Gracias a la wena onda de Tecnoman, que se auspicio con hosting y me dejo hincharle las pelotas para que instalara PDO en un servidor en producci&#243;n, tengo el demo de Gonium en un hosting nuevo. Ahora intentar&#233; de alg&#250;n modo recompensar aquello, posteando m&#225;s seguido en tecnosquad.org. Aprovechando eso, sub&#237; una copia m&#225;s reciente. [...]]]></description>
			<content:encoded><![CDATA[<p>Gracias a la <em>wena onda</em> de Tecnoman, que se auspicio con hosting <span style="text-decoration:line-through;">y me dejo hincharle las pelotas para que instalara PDO en un servidor en producci&oacute;n</span>, tengo el demo de Gonium en un <a href="http://gon.boaboa.org">hosting nuevo</a>. Ahora intentar&eacute; de alg&uacute;n modo recompensar aquello, posteando m&aacute;s seguido en <a href="http://tecnosquad.org">tecnosquad.org</a>.</p>
<p>Aprovechando eso, sub&iacute; una copia m&aacute;s reciente.</p>
<p>Hace unos d&iacute;as agregu&eacute; al trunk del repositorio, una copia propia del proyecto <cite><a href="code.google.com/p/zend-framework-datagrid/"><strong>zend-framework-datagrid</strong></a></cite>, con la diferencia de que mi copia permite traducirlo con Zend_Translate y los comentarios est&aacute;n corregidos. Tambi&eacute;n correg&iacute; unos <em>warnings</em> menores. Adem&aacute;s le cambi&eacute; el prefijo a las clases de &#8220;Core_&#8221; (originalmente en zf-datagrid) a &#8220;Rox_&#8221;, para darle concordancia a mi estructura de directorios. Podr&iacute;a decir entonces que es un peque&ntilde;o fork <img src='http://blog.gon.cl/wp-content/plugins/smilies-themer/GON/=B_1.gif' alt=':B' class='wp-smiley' /> </p>
<p>Tambi&eacute;n agregu&eacute; todo jQuery UI al directorio p&uacute;blico. Una ejemplo de esto es la peque&ntilde;a demostraci&oacute;n con el efecto acorde&oacute;n que le agregu&eacute; al widget de Login.</p>
<p>Y por &uacute;ltimo, agregu&eacute; un directorio con XML&#8217;s en formato docbook, para poder usarlos en conjunto con la documentaci&oacute;n creada con phpDocumentor.</p>
<p>Espero tener una documentaci&oacute;n un poco m&aacute;s completa m&aacute;s adelante.</p>
<div class="bottomcontainerBox" style="">
			<div style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;">
			<iframe src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fblog.gon.cl%2Fpost%2F357&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width=85px; height:21px;" allowTransparency="true"></iframe></div>
			<div style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;">
			<g:plusone size="medium" href="http://blog.gon.cl/post/357"></g:plusone>
			</div>
			<div style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;">
			<a href="http://twitter.com/share" class="twitter-share-button" data-url="http://blog.gon.cl/post/357"  data-text="Gonium, nuevo demo y nuevos componentes" data-count="horizontal" data-via="sir_gon">Tweet</a>
			</div>			
			</div><div style="clear:both"></div><div style="padding-bottom:4px;"></div>]]></content:encoded>
			<wfw:commentRss>http://blog.gon.cl/post/357/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Gonium: Rompiendo el RoadMap</title>
		<link>http://blog.gon.cl/post/352</link>
		<comments>http://blog.gon.cl/post/352#comments</comments>
		<pubDate>Tue, 25 Nov 2008 23:16:10 +0000</pubDate>
		<dc:creator>gon</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[Zend Framework]]></category>
		<category><![CDATA[gonium]]></category>
		<category><![CDATA[php5]]></category>
		<category><![CDATA[zend framework]]></category>

		<guid isPermaLink="false">http://blog.gon.cl/?p=352</guid>
		<description><![CDATA[A veces no es bueno quedarse pegado con un objetivo, pudiendo romper otro m&#225;s r&#225;pidamente. Entre ayer y hoy, logr&#233; romper el segundo objetivo del Roadmap inicial de Gonium, consistente en crear la arquitectura modular para el Backend administrativo. Ahora, la aplicaci&#243;n cuenta con 2 sistemas modulares independientes, uno para el Frontend (el sitio visible [...]]]></description>
			<content:encoded><![CDATA[<p>A veces no es bueno quedarse pegado con un objetivo, pudiendo romper otro m&aacute;s r&aacute;pidamente.</p>
<p>Entre ayer y hoy, logr&eacute; romper el segundo objetivo del Roadmap inicial de Gonium, consistente en crear la arquitectura modular para el Backend administrativo.</p>
<p>Ahora, la aplicaci&oacute;n cuenta con 2 sistemas modulares independientes, uno para el Frontend (el sitio visible para todo usuario) y otro para el Backend (donde solo usuarios con privilegios pueden modificar cosas).</p>
<p>Esto significa, por ejemplo, que el m&oacute;dulo &#8220;user&#8221; que puede ver un usuario corriente (donde podr&aacute; modificar su perfil y esas cosas), ser&aacute; distinto del m&oacute;dulo &#8220;user&#8221; del administrador (donde se podr&aacute; crear/borrar/modificar cuantas usuarios).</p>
<p>Para dejarlo plenamente funcional, a&uacute;n falta crear los m&oacute;dulos administrativos (as&iacute; como los de usuario corriente), pero al menos, la arquitectura de directorios y bootstraping ya est&aacute;n adaptados para trabajar de esta manera.</p>
<p><span id="more-352"></span></p>
<h2>Implementaci&oacute;n</h2>
<p>La t&eacute;cnica utilizada, consisti&oacute; de los siguientes pasos:</p>
<h3>Separar el bootstrap de Frontend del boostrap del Backend</h3>
<p>Se creo un admin.php en el public_html, al mismo nivel de index.php, el cual carga el Core/boostrap.php pero cambiando el Environment a &#8216;Admin&#8217;.</p>
<p>Esto signific&oacute; modificar las reglas de .htaccess para redirigir las peticiones que pasaran por la url <strong>admin/</strong> a admin.php</p>
<h3>Crear clases &#8220;inicializadoras&#8221; para cada Environment distinto</h3>
<p>Esto debido a que ciertos plugins b&aacute;sicos y configuraciones especificas del Frontend no tienen sentido en el Backend (y los futuros de Backend no tienen sentido en el Frontend).</p>
<h3>Cambiar la estructura de directorios</h3>
<p>Casi vuelvo a dejar la embarr&aacute; con la copia de trabajo, pero finalmente lo salv&eacute;. Se tuvo que armar una nueva arquitectura de directorios para alojar los m&oacute;dulos administrativos. Aprovechando eso, tambi&eacute;n se movieron los m&oacute;dulos b&aacute;sico del Frontend y el controlador de errores, los 3 ahora son subcarpetas de /application/Core/Module. Esto fue pensado debido a que las clases controladoras son las &uacute;nica que no respetan el codding-standar de usar prefijos por cada carpeta, para separarlas como si fueran distintos namespaces. No lo necesitan tampoco, porque estas clases jam&aacute;s se deber&iacute;an cargar como librer&iacute;as (al estilo de Zend_Loader).</p>
<h3>Separar el controlador de errores del Frontend</h3>
<p>Ya ten&iacute;a implementado un controlador de errors, que despliega por pantalla cualquier Exception disparada durante el proceso del dispatcher. El problema es que este controlador estaba sujeto al m&oacute;dulo &#8220;default&#8221; del frontend, por lo tanto, no se pod&iacute;a usar desde el backend directamente. Se resolvi&oacute; separar este controlador de ambos directorios, dejandolo independiente, y siendo este agragado al &#8220;Front Controller&#8221;. como una carpeta independiente. Este controlador DEBE estar disponible en todos los &#8216;Environments&#8217;.</p>
<h3>Agregar un enrutador especial para el Backend</h3>
<p>Hab&iacute;a estado trabajando con un enrutador corriente como lo es el Zend_Controller_Router_Route con una regla sencilla. Pero no me percat&eacute; que el enrutador predeterminado, usaba internamente (y por defecto) un enrutador llamado <code class="code">Zend_Controller_Router_Route_Module. Cambiandolo a ese, logr&eacute; crear un enrutador 'admin' que funciona bien en la estructura modular separada del backend.</code></p>
<p>Pens&eacute; que ser&iacute;a m&aacute;s sencillo&#8230; D:</p>
<p>No me quedo otra que hacerlo por esta v&iacute;a, ya que las rutas se resuelven en tiempo de &#8220;dispatching&#8221;, por ende no puedo configurarlas despues que la aplicaci&oacute;n ya empieza a correr.</p>
<p>Si alguien conoce alguna soluci&oacute;n m&aacute;s limpia, favor de comunicarse conmigo, sino pruebenlo, ya hice el respectivo commit al repositorio del proyecto.</p>
<div class="bottomcontainerBox" style="">
			<div style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;">
			<iframe src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fblog.gon.cl%2Fpost%2F352&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width=85px; height:21px;" allowTransparency="true"></iframe></div>
			<div style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;">
			<g:plusone size="medium" href="http://blog.gon.cl/post/352"></g:plusone>
			</div>
			<div style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;">
			<a href="http://twitter.com/share" class="twitter-share-button" data-url="http://blog.gon.cl/post/352"  data-text="Gonium: Rompiendo el RoadMap" data-count="horizontal" data-via="sir_gon">Tweet</a>
			</div>			
			</div><div style="clear:both"></div><div style="padding-bottom:4px;"></div>]]></content:encoded>
			<wfw:commentRss>http://blog.gon.cl/post/352/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Roxydemo!</title>
		<link>http://blog.gon.cl/post/285</link>
		<comments>http://blog.gon.cl/post/285#comments</comments>
		<pubDate>Mon, 22 Sep 2008 03:02:38 +0000</pubDate>
		<dc:creator>gon</dc:creator>
				<category><![CDATA[Desarrollo]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[Zend Framework]]></category>
		<category><![CDATA[cms]]></category>
		<category><![CDATA[demo]]></category>
		<category><![CDATA[gonium]]></category>
		<category><![CDATA[mvc]]></category>
		<category><![CDATA[php5]]></category>
		<category><![CDATA[poo]]></category>
		<category><![CDATA[zend framework]]></category>

		<guid isPermaLink="false">http://blog.gon.cl/?p=285</guid>
		<description><![CDATA[Ayer no se porque me di&#243; ganas de probar mi c&#243;digo in&#250;til proyecto personal en un hosting gratuito. Mientras lo hac&#237;a, coment&#233; aquello en mi canal de irc favorito. Fue entonces cuando @janitux me comenta que tenia un hosting y un dominio en desuso. Igualmente planeaba contratar un dominio y hosting m&#225;s adelante para levantar [...]]]></description>
			<content:encoded><![CDATA[<p>Ayer no se porque me di&oacute; ganas de probar mi <span style="text-decoration:line-through;">c&oacute;digo in&uacute;til</span> <a href="http://code.google.com/p/gonium">proyecto personal</a> en un hosting gratuito.</p>
<p>Mientras lo hac&iacute;a, coment&eacute; aquello en <a href="http://embed.mibbit.com/?server=irc.powers.cl&amp;channel=%2C%23linux&amp;forcePrompt=true&amp;promptPass=true">mi canal de irc favorito</a>. Fue entonces cuando <a href="https://twitter.com/janitux">@janitux</a> me comenta que tenia un hosting y un dominio en desuso.</p>
<p>Igualmente planeaba contratar un dominio y hosting m&aacute;s adelante para levantar un demo. Pero gracias a esto puedo adelantarlo.</p>
<p style="text-align:center;">Para mirarlo (por ahora nada m&aacute;s que un simple home), pueden acceder ac&aacute;:</p>
<p style="text-align:center;"><a href="http://gon.boaboa.org/"><img class="size-full wp-image-287" title="Gonium Demo" src="http://blog.gon.cl/wp-content/uploads/2008/09/gonium_demo_120x60.png" alt="Demostraci&oacute;n" width="120" height="60" /></a></p>
<p style="text-align:center;">Y para mirar las fuentes, pueden acceder al repositorio ac&aacute;:</p>
<p style="text-align:center;"><a href="http://code.google.com/p/gonium"><img class="size-full wp-image-286" title="Gonium Project" src="http://blog.gon.cl/wp-content/uploads/2008/09/gonium_project_120x60.png" alt="" width="120" height="60" /></a></p>
<p>No esperen mucho, pues muchas caracter&iacute;sticas b&aacute;sicas de uso a&uacute;n no est&aacute;n implementadas. Lo importante es probar como funciona el <a href="http://es.wikipedia.org/wiki/Back_end#En_dise.C3.B1o_web_.28o_desarrollo_web.29">backend</a> en un &#8220;ambiente de producci&oacute;n&#8221; . Es muy distinto probar las aplicaciones as&iacute; que en el &#8220;&aacute;mbiente de desarrollo&#8221;, donde todas las condiciones necesarias son modificables por el desarrollador.</p>
<p>Por el momento, el &uacute;nico m&oacute;dulo o sub-aplicaci&oacute;n interesante que puedo mostrar es <a href="http://gon.boaboa.org/twitter">http://gon.boaboa.org/twitter</a> Espero que les guste. <img src='http://blog.gon.cl/wp-content/plugins/smilies-themer/GON/=B_1.gif' alt=':B' class='wp-smiley' /> </p>
<p>Por el momento va bien. Gracias a ello logr&eacute; encontrar algunos detalles que no hab&iacute;a visto en mi ambiente de desarrollo.</p>
<p>Gracias <a href="https://twitter.com/janitux">@janitux</a>, espero poder sacarle provecho <img src='http://blog.gon.cl/wp-content/plugins/smilies-themer/GON/biggrin.png' alt=':D' class='wp-smiley' /> .</p>
<div class="bottomcontainerBox" style="">
			<div style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;">
			<iframe src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fblog.gon.cl%2Fpost%2F285&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width=85px; height:21px;" allowTransparency="true"></iframe></div>
			<div style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;">
			<g:plusone size="medium" href="http://blog.gon.cl/post/285"></g:plusone>
			</div>
			<div style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;">
			<a href="http://twitter.com/share" class="twitter-share-button" data-url="http://blog.gon.cl/post/285"  data-text="Roxydemo!" data-count="horizontal" data-via="sir_gon">Tweet</a>
			</div>			
			</div><div style="clear:both"></div><div style="padding-bottom:4px;"></div>]]></content:encoded>
			<wfw:commentRss>http://blog.gon.cl/post/285/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>ZendFramework: problemas de codificaci&#243;n de caract&#233;res con la Base de datos.</title>
		<link>http://blog.gon.cl/post/275</link>
		<comments>http://blog.gon.cl/post/275#comments</comments>
		<pubDate>Tue, 16 Sep 2008 05:14:55 +0000</pubDate>
		<dc:creator>gon</dc:creator>
				<category><![CDATA[Desarrollo]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[Zend Framework]]></category>
		<category><![CDATA[juego de caractÃ©res]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[zend db]]></category>
		<category><![CDATA[zend form]]></category>
		<category><![CDATA[zend framework]]></category>

		<guid isPermaLink="false">http://blog.gon.cl/?p=275</guid>
		<description><![CDATA[Este es otro caso en que me pena el tema de las codificaciones de caracteres. SIEMPRE que uno trabaje con Bases de datos, sobre todo en paises de habla no-inglesa, se esta expuesto al tremendo cacho (problema) de manipular datos con caracteres no-ascii, como por ejemplo las &#241;-Ñ y diversas vocales acentuadas, tildes, apostrofes, cremillas, [...]]]></description>
			<content:encoded><![CDATA[<p>Este es otro caso en que me pena el tema de las codificaciones de caracteres.</p>
<p>SIEMPRE que uno trabaje con Bases de datos, sobre todo en paises de habla no-inglesa, se esta expuesto al tremendo cacho (problema) de manipular datos con caracteres no-ascii, como por ejemplo las &ntilde;-Ñ y diversas vocales acentuadas, tildes, apostrofes, cremillas, tongos y cuanta modificacion rara se le pueda hacer a una letra.</p>
<p>Hasta ahora, he trabajado TODO con codificaci&oacute;n utf8 por ser m&aacute;s amplia en este sentido que las otras codificaciones corrientes (iso-8859-1*, latin1, &#8230;).</p>
<h2>Motivo</h2>
<p>Trabajando con Zend Form, note un extra&ntilde;o comportamiento. Cuando establec&iacute;a manualmente un dato en un campo, si este ven&iacute;a acentuado, entonces al dibujar por la vista, <strong>aparec&iacute;a en blanco</strong>.</p>
<p>Haciendo un <code>var_dump( $dato );</code> descubr&iacute; que la cadena de texto ven&iacute;a con caracteres mal formados. Preguntando en <a href="http://www.forosdelweb.com/f68/zend-form-zend-db-no-llevan-bien-624967/">Foros del Web</a> y navegando, d&iacute; con una pista.</p>
<p>El m&eacute;todo escape() de Zend_View provocaba que la cadena mal formada retornara en blanco. Seguramente si me pongo a mirar el c&oacute;digo fuente de Zend_Form* llegar&eacute; a encontrar una llamada a ese m&eacute;todo (no lo he hecho, pero por el efecto lo deduzco).</p>
<p>Adem&aacute;s, buscando por este problema, tanto en listas de correo sobre ZF, como en la documentaci&oacute;n de Mysql y adem&aacute;s en otra respuesta a mi pregunta en el mismo foro, encontr&eacute; que existen 2 consultas SQL (para MySQL) que arreglan el problema:</p>
<blockquote>
<pre>SET NAMES 'UTF8'
SET CHARACTER SET UTF8</pre>
</blockquote>
<p>Pero eso es espec&iacute;fico a Mysql. La otra soluci&oacute;n es manipular la configuraci&oacute;n del servidor, cosa que no se puede hacer en un hosting.</p>
<h2>Soluci&oacute;n</h2>
<p>La soluci&oacute;n b&aacute;sica es ejecutar esa par de consultas SQL. Pero hay que ver globalmente el problema para saber donde, como y cuando hacerlo.</p>
<p>De partida, mi aplicaci&oacute;n pretender ser no-dependiente del motor de base de datos.</p>
<p>Lo otro, es que intento mantener &#8220;limpio&#8221; el dise&ntilde;o del c&oacute;digo, en el sentido de que cada cosa valla en el lugar que corresponde, dependiendo del patr&oacute;n y/o paradigma adoptado.</p>
<p>Entonces, no es cosa de llegar y ponerlo en el index.php</p>
<p>Una soluci&oacute;n podr&iacute;a ser extender la clase Zend_Db_Adaptar_PdoMysql y a&ntilde;adir la consulta. Pero esto a&ntilde;ade un prop&oacute;sito espec&iacute;fico a algo que pretende ser general.</p>
<p>Bajo el mismo sentido de llegar a una soluci&oacute;n generalizada, se me ocurri&oacute; externalizar el charset de la consulta. As&iacute; que simplemente, a&ntilde;ad&iacute; un dato m&aacute;s al config.ini</p>
<blockquote>
<pre>database.adapter          = pdo_mysql   ; php extension, or Object adapter (1)
<strong>database.charset          = utf8        ; (optional) Character Set </strong>
database.params.host      = localhost   ; database host
database.params.username  = username    ; username to conect database
database.params.password  = password    ; password to conect database
database.params.dbname    = goniumdb   ; name of database
database.params.prefix    = rox_        ; table prefix
database.params.profiler  = "1"         ; Enable/disable profiler</pre>
</blockquote>
<p>Los Controller Plugins b&aacute;sicos de Gonium los dise&ntilde;&eacute; con el prop&oacute;sito de configurar cosas espec&iacute;ficas, asi que decid&iacute; por el momento, hacer ah&iacute; las consultas, PERO solo cuando el adapter ocupado sea alguno basado en mysql. As&iacute; que finalmente mi c&oacute;digo quedo as&iacute;:</p>
<blockquote>
<pre>$config = Zend_Registry::get('core_config');
$db = Zend_Registry::get('core_db');
$db-&gt;getConnection();

// Set charset
if( isset($config-&gt;database-&gt;charset) &amp;&amp; $config-&gt;database-&gt;charset !== null )
{
    switch( $config-&gt;database-&gt;adapter )
    {
        case 'mysql':
        case 'mysqli':
        case 'pdo_mysql':
            $db-&gt;query('SET NAMES \''.strtoupper($config-&gt;database-&gt;charset).'\'');
            $db-&gt;query('SET CHARACTER SET '.strtoupper($config-&gt;database-&gt;charset));
        break;
    }
}</pre>
</blockquote>
<p>Todo eso en el plugin Database. Es cosa de gustos en donde ponerlo, yo lo hice en un plugin, tambi&eacute;n se puede poner directo en el bootstrap, o extendiendo Zend_Db*, o que se yo&#8230;</p>
<h2>&iquest;Y luego que?</h2>
<p>Creo que me ver&eacute; obligado a probar YA en otros motores de base de datos, haber como se comportan&#8230;</p>
<div class="bottomcontainerBox" style="">
			<div style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;">
			<iframe src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fblog.gon.cl%2Fpost%2F275&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width=85px; height:21px;" allowTransparency="true"></iframe></div>
			<div style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;">
			<g:plusone size="medium" href="http://blog.gon.cl/post/275"></g:plusone>
			</div>
			<div style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;">
			<a href="http://twitter.com/share" class="twitter-share-button" data-url="http://blog.gon.cl/post/275"  data-text="ZendFramework: problemas de codificaci&oacute;n de caract&eacute;res con la Base de datos." data-count="horizontal" data-via="sir_gon">Tweet</a>
			</div>			
			</div><div style="clear:both"></div><div style="padding-bottom:4px;"></div>]]></content:encoded>
			<wfw:commentRss>http://blog.gon.cl/post/275/feed</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Traducci&#243;n de Zend Validate con gettext y poedit</title>
		<link>http://blog.gon.cl/post/210</link>
		<comments>http://blog.gon.cl/post/210#comments</comments>
		<pubDate>Sat, 06 Sep 2008 07:54:37 +0000</pubDate>
		<dc:creator>gon</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[Zend Framework]]></category>
		<category><![CDATA[i18n]]></category>
		<category><![CDATA[internationalization]]></category>
		<category><![CDATA[l10n]]></category>
		<category><![CDATA[localizaciÃ³n]]></category>
		<category><![CDATA[mvc]]></category>
		<category><![CDATA[php5]]></category>
		<category><![CDATA[poo]]></category>
		<category><![CDATA[traducciÃ³n]]></category>
		<category><![CDATA[zend form]]></category>
		<category><![CDATA[zend framework]]></category>
		<category><![CDATA[zend validate]]></category>

		<guid isPermaLink="false">http://blog.gon.cl/?p=210</guid>
		<description><![CDATA[Zend Framework cuenta con una l&#243;gica de Formularios bastante &#8220;chori&#8221;. Consta de una clase Zend_Form, algunas cuantas Zend_Form_Element_* y algunos Zend_Form_Decorator_*. Lo &#8220;chori&#8221; es como funciona. Integra en un solo objeto la l&#243;gica de los datos de un formulario, la vista html, el procesamiento de las entradas por cada campo (elemento) y la validaci&#243;n de [...]]]></description>
			<content:encoded><![CDATA[<p>Zend Framework cuenta con una l&oacute;gica de Formularios bastante &#8220;chori&#8221;.</p>
<p>Consta de una clase Zend_Form, algunas cuantas Zend_Form_Element_* y algunos Zend_Form_Decorator_*.</p>
<p>Lo &#8220;chori&#8221; es como funciona. Integra en un solo objeto la l&oacute;gica de los datos de un formulario, la vista html, el procesamiento de las entradas por cada campo (elemento) y la validaci&oacute;n de los valores ingresados.</p>
<p>As&iacute; nos ahorramos la lata de escribir varios scripts por separado. Antes era necesario coordinar los nombres de los elementos con las claves que llegaban por $_GET o $_POST. Al hacer cualquier cambio al formulario html, pod&iacute;a provocarle hipo al script validador.</p>
<p>Ahora solo es necesario declarar el formulario, agregarle los validadores a cada elemento (que sea necesario), los decoradores del formulario y/o de los elementos y ya esta todo cocinado. Se pasa el objeto $form al script de vista y autom&aacute;ticamente es dibujado como HTML, y nuestro script Controller puede perfectamente procesar los mismos inputs declarados en el Form.</p>
<p><a href="http://bolsadeideas.cl/zsamer/2008/05/sistema-de-login/">Tutoriales</a> y <a href="http://framework.zend.com/manual/en/zend.form.quickstart.html">documentaci&oacute;n</a> para trabajar con Zend Form abundan, as&iacute; que no voy a profundizar en ello.</p>
<h1>El Problema</h1>
<p>Los validadores arrojan mensajes de error cuando el valor recibido no coincide con su criterio de validaci&oacute;n. Pero estos mensajes estan en idioma ingl&eacute;s, definidos en constantes de clase en cada clase Zend_Validate_*.</p>
<h1>La soluci&oacute;n</h1>
<p>Zend_Translate permite introducir texto traducible en nuestro c&oacute;digo.</p>
<h2>Escoger un adaptador de traducci&oacute;n</h2>
<p>Entre sus adaptadores, mi favorito por el momento es el basado en Gettext. Las ventajas de gettext son m&uacute;ltiples:</p>
<ul>
<li>Las traducciones est&aacute;n en un formato binario y no texto plano, lo que facilita evitar problemas como la codificaci&oacute;n de caracteres en distintos sistemas operativos. De hecho, la codificaci&oacute;n es un par&aacute;metro que se guarda en el mismo binario, ahorrando el &#8220;parseo&#8221; para detectarlo.</li>
<li>PHP es compatible con gettext, por lo tanto, la integraci&oacute;n es directa. Cuanta con funciones nativas para cargar las traducciones y adem&aacute;s soporta la macro <strong>_(&#8216;texto&#8217;)</strong> para convertir cualquier <strong>string</strong> en su traducci&oacute;n.</li>
<li>El rendimiento de carga uso es alt&iacute;simo comparado con cualquier otro adaptador basado en texto.</li>
</ul>
<p>Por su puesto que, dada las circunstancias, se puede escoger cualquier otro adaptador. Solo que gettext es mi favorito <img src='http://blog.gon.cl/wp-content/plugins/smilies-themer/GON/biggrin.png' alt=':D' class='wp-smiley' /> .</p>
<p><a href="http://framework.zend.com/manual/en/zend.translate.html">Ac&aacute; hay m&aacute;s detalles</a> sobre Zend_Translate y sus adaptadores.</p>
<p>Zend_Form permite usar autom&aacute;ticamente los mensajes que ya est&eacute;n traducidos cuando ocupamos validadores con &eacute;l. &iquest;Pero como se hace la magia?</p>
<p><span id="more-210"></span></p>
<h2>Directorios de traducci&oacute;n</h2>
<p>Debemos escoger tambien donde y como guardar las traducciones.</p>
<p>En mi caso hice esta estructura de directorios:</p>
<pre>/language/*/LC_MESSAGES</pre>
<p>Donde * es el c&oacute;digo del idioma (es, en, fr, &#8230;, es_CL). Es la forma corriente para las traducciones usando gettext. Para el ejemplo, usese &#8220;es&#8221;.</p>
<h2>Iniciar Zend_Translate</h2>
<p>Es cosa de poner el siguiente c&oacute;digo en alg&uacute;n lugar previo a la carga de los controladores de acci&oacute;n:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">Zend_Loader<span style="color: #339933;">::</span><span style="color: #004000;">loadClass</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Zend_Translate'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$translate</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Zend_Translate<span style="color: #009900;">&#40;</span>
        <span style="color: #0000ff;">'gettext'</span><span style="color: #339933;">,</span>
        APP_ROOT<span style="color: #339933;">.</span><span style="color: #0000ff;">'/language/'</span><span style="color: #339933;">,</span>
        <span style="color: #009900; font-weight: bold;">null</span><span style="color: #339933;">,</span>
        <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'scan'</span> <span style="color: #339933;">=&gt;</span> Zend_Translate<span style="color: #339933;">::</span><span style="color: #004000;">LOCALE_DIRECTORY</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$translate</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setLocale</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'es'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
Zend_Registry<span style="color: #339933;">::</span><span style="color: #004000;">set</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Zend_Translate'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$translate</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>En mi caso, lo hice en un Controller Plugin, pero tambi&eacute;n es posible dejarlo en el Bootstrap. Es importante usar el Zend_Registry para guardar nuestro objeto de traducci&oacute;n. Tambi&eacute;n es importante guardarlo con la clave<strong>&#8216;Zend_Translate&#8217;</strong>, pues Zend_Form busca ese nombre autom&aacute;ticamente en el registry para traducir los mensajes de error que retornan los validadores. Si no le ponemos <strong><strong>&#8216;Zend_Translate&#8217;</strong></strong>, la documentaci&oacute;n del api de Zend_Form tiene unos m&eacute;todos para establecer el objeto de traducci&oacute;n.</p>
<h2>&iquest;C&oacute;mo hacer el texto &#8220;traducible&#8221;?</h2>
<p>Primero, debe haber texto traducible. De ac&aacute; en adelante se asume que estamos trabajando con el patr&oacute;n MVC.</p>
<p>Podemos hacer 3 cosas, separadas o mezcladas:</p>
<h3>1) Helper de Vista</h3>
<p>Usar el m&eacute;todo helper de vista <strong>translate</strong> para traducir en los scripts de vista (si tenemos todo autom&aacute;tico, deber&iacute;a funcionar de inmediato).</p>
<p>Ejemplo:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">&lt;h1&gt;<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">translate</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Hello World'</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>&lt;/h1&gt;
&lt;p&gt;<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">translate</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'This is an example'</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>&lt;/p&gt;</pre></div></div>

<h3>2) Usar la macro _()</h3>
<p>La macro _() puede usarse para mandar el texto traducible a las vistas desde los controladores.</p>
<p>Vease esta m&aacute;cro como si fuera una funci&oacute;n cualquiera, que realiza lo siguiente: <em>Si existe texto traducido para la cadena de entrada, entonces retorna una cadena con el texto traducido, sino retorna la misma cadena de entrada.</em></p>
<p>Ejemplo:</p>
<p>MyController.php</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #000000; font-weight: bold;">class</span> MyModule_IndexController <span style="color: #000000; font-weight: bold;">extends</span> Zend_Controller_Action
<span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> indexAction<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">view</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">title</span> <span style="color: #339933;">=</span> _<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Hello world'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">view</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">message</span> <span style="color: #339933;">=</span> _<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'This is an example'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>index.phtml</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">&lt;h1&gt;<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">message</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>&lt;/h1&gt;
&lt;p&gt;<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>&lt;/p&gt;</pre></div></div>

<h3>3) Usar directamente el objeto Zend_Translate</h3>
<p>Esta es la forma que &#8220;deber&iacute;a usarse&#8221; siempre, mientras no sea el script de vista donde podemos usar el helper.</p>
<p>Variando un poco el ejemplo anterior, quedar&iacute;a as&iacute;:</p>
<p>MyController.php</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #000000; font-weight: bold;">class</span> MyModule_IndexController <span style="color: #000000; font-weight: bold;">extends</span> Zend_Controller_Action
<span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> indexAction<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$lang</span> <span style="color: #339933;">=</span> Zend_Registry<span style="color: #339933;">::</span><span style="color: #004000;">get</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Zend_Translate'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">view</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">title</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$lang</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">translate</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Hello world'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">view</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">message</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$lang</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">translate</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'This is an example'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>index.phtml</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">&lt;h1&gt;<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">title</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>&lt;/h1&gt;
&lt;p&gt;<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">message</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>&lt;/p&gt;</pre></div></div>

<p>Hasta ahora, solo se ha preparado el terreno. Al probar el controlador y al vista, deber&iacute;a</p>
<h2>&iquest;C&oacute;mo Traducir?</h2>
<p>Ac&aacute; est&aacute; la gracia. Entra en juego la herramienta <a href="www.poedit.net/ ">Poedit</a>.</p>
<p>Instalarla en windows es cosa de bajar el instalador y click, click, &#8230;</p>
<p>Instalarla en linux, es cosa de buscar en los repositorios, en debian/ubuntu ser&iacute;a as&iacute;:</p>
<pre>
<blockquote>
sudo apt-get install poedit</blockquote>
</pre>
<p>Luego, es necesario hacerle un peque&ntilde;o arregl&iacute;n.</p>
<p>Una caracter&iacute;stica de trabajar con poedit, es que puede encontrar el texto traducible en la aplicaci&oacute;n, examinando los archivos fuente. Autom&aacute;ticamente, cualquier cadena de texto encerrada en la macro _() ser&aacute; considerada &#8220;una cadena traducible&#8221;. Nos interesa que tambien tome las cadenas que aparecen dentro del m&eacute;todo translate().</p>
<p>Otra cosa importante. No se puede agregar otras cadenas manualmente en poedit. Aparentemente eso es malo en felixibilidad, pues no se puede agregar cualquier texto que uno quiera a la traducci&oacute;n. Sin embargo, esto es bueno por eficiencia, as&iacute; no habr&aacute;n cadenas basura en el binario de traducci&oacute;n, solo estar&aacute;n presentes aquellas que realmente est&eacute;n en el c&oacute;digo fuente de la aplicaci&oacute;n.</p>
<p>El arregl&iacute;n consiste en:</p>
<ul>
<li>Ir al men&uacute; Archivo -&gt; Preferencias &#8230;</li>
<li>Pesta&ntilde;a &#8220;Procesadores&#8221;, escoger PHP y presionar Editar</li>
<li>En la lista de extensiones, dejar la caja as&iacute;: *.php;*.phtml</li>
<li>En la caja &#8220;Linea de comandos para procesar&#8221; agregar al final: -L php</li>
</ul>
<p>Luego, al crear un cat&aacute;logo (as&iacute; se llama el archivo *.mo que contendr&aacute; la traducci&oacute;n), debemos configurarlo con lo siguiente:</p>
<ul>
<li>Ir al men&uacute; Cat&aacute;logo -&gt; Opciones &#8230;</li>
<li>Pesta&ntilde;a &#8220;Palabras clave&#8221;, agregar una nueva y poner: translate</li>
<li>En la pesta&ntilde;a &#8220;Carpetas&#8221;, se debe poner la ruta al c&oacute;digo fuente que se va a traducir. Recomiendo poner una ruta relativa. Relativa a la posici&oacute;n donde guardar&eacute;mos el cat&aacute;logo (*.po y *.mo)</li>
</ul>
<p>Listo. Esto har&aacute; que el procesador de gettext lea los archivos .php y .phtml dentro de la carpeta de inter&eacute;s. Adem&aacute;s tomar&aacute; traducciones desde el m&eacute;todo translate().</p>
<h1>&iquest;C&oacute;mo traduje los mensajes de los validadores de Zend Framework?</h1>
<p>Una opci&oacute;n abr&iacute;a sido pasar poedit por la carpeta Zend/Validate del framework, pero lamentablemente, los mensajes de error no est&aacute;n en una forma que se pueda escanear con gettext. Cada mensaje de error es un c&oacute;digo (string) guardado en una constante de clase, adem&aacute;s de un array donde la clave es la constante de clase correspondiente, y su valor contiene un string con el mensaje en s&iacute;.</p>
<p>As&iacute; que opte por hacer algo un poco m&aacute;s sucio, pero v&aacute;lido.</p>
<p>Cree un archivo template.php, el cual contiene un array, pero de la siguiente forma:</p>
<pre><?php
$translate[_('isEmpty')] = 'Value is empty, but a non-empty value is required';
$translate[_('stringEmpty')] = "'%value%' is an empty string";

//... Y as&iacute; con todos los mensajes de error que aparecen en Zend/Validate/*
</pre>
<p>Si se fijan, cada clave de array est&aacute; encerrada por la macro de traducci&oacute;n _().</p>
<p>&iquest;Cual es la magia?, configurar el cat&aacute;logo en Poedit, para que pase por este archivo, actualizar el catalogo desde el c&oacute;digo fuente, y listo.</p>
<p>El archivo finalmente <a href="http://code.google.com/p/gonium/source/browse/trunk/app/language/templates/form/zend_validate.php">qued&oacute; as&iacute;</a>.</p>
<p>Ahora, la otra alternativa, es actualizar el cat&aacute;logo desde una plantilla *.pot. En el fondo, es igual a un .po, que podemos editar afuera y Poedit no va a alegar, pero si lo har&aacute; si volvemos a actualizar desde el c&oacute;digo fuente.</p>
<p>El .po qued&oacute; <a href="http://code.google.com/p/gonium/source/browse/trunk/app/language/es/LC_MESSAGES/zend_validate.po">as&iacute; finalmente</a>.</p>
<p>As&iacute; que si alguien necesita traducir los mensajes de los validadores de Zend Framework, ac&aacute; hay 2 formas ya listas para bajar y "compilar".</p>
<div class="bottomcontainerBox" style="">
			<div style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;">
			<iframe src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fblog.gon.cl%2Fpost%2F210&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width=85px; height:21px;" allowTransparency="true"></iframe></div>
			<div style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;">
			<g:plusone size="medium" href="http://blog.gon.cl/post/210"></g:plusone>
			</div>
			<div style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;">
			<a href="http://twitter.com/share" class="twitter-share-button" data-url="http://blog.gon.cl/post/210"  data-text="Traducci&oacute;n de Zend Validate con gettext y poedit" data-count="horizontal" data-via="sir_gon">Tweet</a>
			</div>			
			</div><div style="clear:both"></div><div style="padding-bottom:4px;"></div>]]></content:encoded>
			<wfw:commentRss>http://blog.gon.cl/post/210/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Mi nuevo proyecto: Gonium</title>
		<link>http://blog.gon.cl/post/180</link>
		<comments>http://blog.gon.cl/post/180#comments</comments>
		<pubDate>Mon, 25 Aug 2008 21:16:15 +0000</pubDate>
		<dc:creator>gon</dc:creator>
				<category><![CDATA[Desarrollo]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[Zend Framework]]></category>
		<category><![CDATA[cms]]></category>
		<category><![CDATA[gonium]]></category>
		<category><![CDATA[php5]]></category>
		<category><![CDATA[rss]]></category>
		<category><![CDATA[seo]]></category>
		<category><![CDATA[web2.0]]></category>

		<guid isPermaLink="false">http://blog.gon.cl/?p=180</guid>
		<description><![CDATA[Tal vez se vea como una tremenda reinvenci&#243;n de rueda. &#191;Por qu&#233;? Hay un dicho muy cierto: si quieres las cosas bien hechas, hazlas tu mismo. Hay una infinidad de CMS&#8217;s a lo largo y ancho de la web. Realmente la fauna es inmensa. Hay CMS&#8217;s f&#225;ciles de instalar, otros f&#225;ciles de administrar, f&#225;ciles de [...]]]></description>
			<content:encoded><![CDATA[<p>Tal vez se vea como una tremenda reinvenci&oacute;n de rueda.</p>
<h1>&iquest;Por qu&eacute;?</h1>
<p>Hay un dicho muy cierto: si quieres las cosas bien hechas, hazlas tu mismo.</p>
<div id="attachment_192" class="wp-caption aligncenter" style="width: 310px"><a href="http://blog.gon.cl/wp-content/uploads/2008/08/img.png"><img class="size-medium wp-image-192" src="http://blog.gon.cl/wp-content/uploads/2008/08/img.png?w=300" alt="Gonium" width="300" height="177" /></a><p class="wp-caption-text">Captura de pantalla de Gonium</p></div>
<p>Hay una infinidad de CMS&#8217;s a lo largo y ancho de la web. Realmente la fauna es inmensa. Hay CMS&#8217;s f&aacute;ciles de instalar, otros f&aacute;ciles de administrar, f&aacute;ciles de extender, f&aacute;ciles de modificar, etc&#8230;</p>
<p>Mi propia reinvenci&oacute;n partir&aacute; siendo <a href="http://code.google.com/p/gonium/">Gonium</a>. Espero poder agregar lo bueno y evitar lo malo de los otros CMS&#8217;s. Pero para que no sea una reinvenci&oacute;n total, decid&iacute; ocupar un Framework PHP: Zend Framework. &iquest;Por qu&eacute; ZF? B&aacute;sicamente porque ya lo conoc&iacute;a. Cuenta con documentaci&oacute;n bastante buena, ciclos de desarrollo &aacute;giles, es libre, tiene buena comunidad, etc&#8230;</p>
<p>No esperen mucho, est&aacute; en una etapa embrionaria muy temprana a&uacute;n. Pr&aacute;cticamente TODO se debe hacer a mano, incluyendo instalaci&oacute;n, configuraci&oacute;n de la base de datos, crear/instalar m&oacute;dulos, etc&#8230;</p>
<p>Adem&aacute;s es una buena oportunidad para probar Google Code como repositorio del proyecto.</p>
<h1>Inspiraci&oacute;n</h1>
<p>Lamentablemente ninguno de los CMS&#8217;s que he ocupado me ha logrado satisfacer del todo. Generalmente cumplen con su objetivo, pero siempre hay algo que le falta a alguno que s&iacute; tiene el otro. O algo que le sobra&#8230; As&iacute; que pretendo juntar lo bueno y evitar lo malo de aquellos que he probado.</p>
<p>Por ejemplo, admiro y me inspiro en los siguientes:</p>
<ul>
<li>Joomla
<ul>
<li>Ventajas
<ul>
<li>Facil de instalar. Adem&aacute;s el instalador da datos precisos y recomendaciones de ajustes del servidor.</li>
<li>Permite usar URL optimizadas para los motores de b&uacute;squeda (SEO)</li>
<li>Tiene miles de extensiones, el sistema de instalaci&oacute;n de extensiones es NOTABLEMENTE sencillo y f&aacute;cil de ocupar.</li>
<li>Muchas partes internas se puede modificar con extensiones (por ejemplo el editor enriquecido)</li>
<li>Existen muchas extensiones de terceros bastante &uacute;tiles. A veces permiten hacer cosas bastante complejas.</li>
<li>Los temas, aun cuando mezclan html y php, son f&aacute;ciles de editar. Generalmente son el esquema completo (layout) de header a body. El css tambi&eacute;n es f&aacute;cil de editar. Incluso se pueden editar v&iacute;a web.</li>
</ul>
</li>
</ul>
</li>
<li>Joomla
<ul>
<li>Desventajas
<ul>
<li>La programaci&oacute;n es algo enredada. No es dificil, pero a veces no es f&aacute;cil entender &#8220;de donde viene&#8221; alguna cosa.</li>
<li>Muchas extensiones son sucias, tanto en su HTML (no w3c-est&aacute;ndar), javascript semifuncional (funciona bien en 1 o 2 navegadores) lleno de errores o excepciones.</li>
<li>No es f&aacute;cil traducirlo completamente, sobre todo las extensiones.</li>
<li>Ocasionalmente, el motor rompe compatibilidad con las extensiones o viceversa.</li>
<li>javascript funcional, pero para usos muy simples. Se hechan de menos algunos detalles de otros CMS&#8217;s, como por ejemplo un editor enriquecido.</li>
</ul>
</li>
</ul>
</li>
<li>Phpbb3
<ul>
<li>Ventajas
<ul>
<li>Ampl&iacute;sima documentaci&oacute;n.</li>
<li>Permite uno de varios motores de base de datos.</li>
<li>Comunidad de usuarios enorme.</li>
<li>Manejo de permisos con una precisi&oacute;n tremenda. Se pueden establecer permisos realmente complejos.</li>
</ul>
</li>
</ul>
</li>
<li>Phpbb3
<ul>
<li>Desventajas
<ul>
<li>Como CMS, es buen foro.</li>
<li>NO TRAE RSS. Error fatal para los tiempos actuales.</li>
<li>NO TIENE URL&#8217;S OPTIMIZADAS PARA SEO.</li>
<li>Los temas son muy complejos de escribir.</li>
<li>Sus extensiones se basan en &#8220;mods&#8221;, que se deben implementar a mano (editando archivos, y base de datos). M&aacute;s conviene encontrar un phpbb-enchulado que intentar implementar mod&#8217;s. En este caso, la mayor&iacute;a de las veces conviene solo usar Mysql como base de datos.</li>
</ul>
</li>
</ul>
</li>
<li>WordPress
<ul>
<li>Ventajas
<ul>
<li>Much&iacute;simo m&aacute;s f&aacute;cil de adminstrar que joomla o phpbb</li>
<li>F&aacute;cil de traducir.</li>
<li>Incorpora de fabrica varios detalles que lo hacen agradable de usar, por ejemplo: rss, ajax, un dise&ntilde;o css/javascript agradable. Por lo general, usa javascript no-intrusivo, lo que lo hace m&aacute;s accesible.</li>
</ul>
</li>
</ul>
</li>
<li>WordPress
<ul>
<li>Deventajas
<ul>
<li>Dependiente de Mysql</li>
<li>Como CMS, es un grandioso blog.</li>
<li>Su sistema de extensiones (plugins) es muy simple. Hacer efectivo algun cambio generalmente consiste tambi&eacute;n en editar el tema.</li>
<li>Los temas est&aacute;n PÉSIMAMENTE mal escritos. Son como un espagueti pegoteado.</li>
<li>Lamentablemente la traducci&oacute;n es muy &#8220;monol&iacute;tica&#8221; (1 archivo traduce TODO el sitio).</li>
<li>Como sistema, se siente igualmente &#8220;monol&iacute;tico&#8221;. Se siente, en el sentido de que hacer cualquier modificaci&oacute;n mayor a veces significa intervenir archivos del motor, despu&eacute;s de actualizas el motor, pierdes los cambios, o se rompe compatibilidad, etc&#8230; Por ejemplo: me paso que al instalar un plugin para widgets en una versi&oacute;n antigua, luego de una actualizaci&oacute;n, el plugin ven&iacute;a preinstalado, pero no se pod&iacute;a deshabilitar, por lo tanto tuvo un choque con mi plugin anterior.</li>
</ul>
</li>
</ul>
</li>
</ul>
<h1>Metas</h1>
<p>Lo que me interesa conciliar de todo esto en Gonium es:</p>
<ul>
<li>Opensource. Libre, c&oacute;digo abierto, blablablah&#8230;</li>
<li>Bien programado desde el principio. Usando el patr&oacute;n de dise&ntilde;o MVC. A medida que crezca, se incorporar&aacute;n librer&iacute;as que ocupen otros patrones de dise&ntilde;o.</li>
<li>Compatible con los est&aacute;ndares W3C. Siempre.</li>
<li>Usar URL&#8217;s Optimizadas SÍ o SÍ.</li>
<li>Temas f&aacute;ciles de editar (el trabajo del dise&ntilde;ador no es programar).</li>
<li>Estructura f&aacute;cilmente extensible. Un buen sistema de instalaci&oacute;n de paquetes.</li>
<li>Permita incorporar Ajax. Javascript no-intrusivo, compatible y est&aacute;ndar (aunque no descarto la necesidad de hacks raros para IE, ya saben&#8230;).</li>
<li>F&aacute;cil de traducir (el trabajo del traductor no es programar). Pienso ocupar gettext (.po) por lo r&aacute;pido, permite usar plantillas (.pot), y adem&aacute;s porque existe Poedit que permite obtener las claves del texto traducible desde el c&oacute;digo fuente.</li>
<li>Incorporar extensiones de primera necesidad (blog, galer&iacute;a, &iquest;foro?, lector rss, descargas, &#8230;)</li>
<li>Evitar romper compatibilidad hacia atr&aacute;s. Lamentablemente no puedo dar garant&iacute;a de esto mientras no libere una versi&oacute;n &#8220;1.0&#8243;, pero intentar&eacute; todo lo posible.</li>
</ul>
<p>Y adem&aacute;s agregar a futuro Implementar novedades de la web 2.0 como por ejemplo</p>
<ul>
<li>Cuadros, men&uacute;es, bontoncitos y efectos Ajax, &#8230;</li>
<li>Extensiones que usen <a href="http://es.wikipedia.org/wiki/API">API&#8217;s</a> de servicios externos (mashups).</li>
</ul>
<p>Si lo pruebas, te gusta, no te gusta, cualquier cr&iacute;tica, idea, ayuda, bienvenida sea.</p>
<div class="bottomcontainerBox" style="">
			<div style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;">
			<iframe src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fblog.gon.cl%2Fpost%2F180&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width=85px; height:21px;" allowTransparency="true"></iframe></div>
			<div style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;">
			<g:plusone size="medium" href="http://blog.gon.cl/post/180"></g:plusone>
			</div>
			<div style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;">
			<a href="http://twitter.com/share" class="twitter-share-button" data-url="http://blog.gon.cl/post/180"  data-text="Mi nuevo proyecto: Gonium" data-count="horizontal" data-via="sir_gon">Tweet</a>
			</div>			
			</div><div style="clear:both"></div><div style="padding-bottom:4px;"></div>]]></content:encoded>
			<wfw:commentRss>http://blog.gon.cl/post/180/feed</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
	</channel>
</rss>

<!-- Dynamic page generated in 3.398 seconds. -->
<!-- Cached page generated by WP-Super-Cache on 2012-02-05 14:41:32 -->

