<?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>Vinco Orbis Proyectos, S.A. de C.V.</title>
	<atom:link href="http://vincoorbis.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://vincoorbis.com</link>
	<description>Desarrollo Web + SEO + App</description>
	<lastBuildDate>Thu, 09 Feb 2012 18:57:54 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Encontrar bugs usando git bisect</title>
		<link>http://vincoorbis.com/encontrar-bugs-usando-git-bisect/</link>
		<comments>http://vincoorbis.com/encontrar-bugs-usando-git-bisect/#comments</comments>
		<pubDate>Thu, 09 Feb 2012 18:53:56 +0000</pubDate>
		<dc:creator>Jair Trejo</dc:creator>
				<category><![CDATA[Consultoría]]></category>

		<guid isPermaLink="false">http://vincoorbis.com/?p=516</guid>
		<description><![CDATA[<p>Hace unos días tuve que hacer un cambio importante que requirió varias alteraciones al sistema en el que estoy trabajando. Uso git como sistema de control de versiones, así que abrí una rama específica para ello, completé la tarea en una larga serie de commits y finalmente corrí mis pruebas automáticas. No pasaron.</p>
El problema
<p>Había un bug complejo y, como todos los bugs, inesperado. Claramente había sido introducido por el &#8220;gran cambio&#8221; (las pruebas automáticas en la rama principal pasaban sin problemas), pero el cambio se había dado en una serie larga y compleja de alteraciones a varios puntos del sistema. Si hubiera hecho pruebas automáticas en cada paso me hubiera dado cuenta, pero ahora la tarea se complicaba.</p>
<p>¿Acaso hay alguna manera sencilla y práctica de regresar a ver cada cambio y descubrir cuál causó el error?</p>
<p>En git la tenemos: el ...]]></description>
			<content:encoded><![CDATA[<p>Hace unos días tuve que hacer un cambio importante que requirió varias alteraciones al sistema en el que estoy trabajando. Uso <a href="http://git-scm.com">git</a> como sistema de control de versiones, así que abrí una rama específica para ello, completé la tarea en una larga serie de commits y finalmente corrí mis <a href="http://es.wikipedia.org/wiki/Desarrollo_guiado_por_pruebas">pruebas automáticas</a>. No pasaron.</p>
<h3>El problema</h3>
<p>Había un <em>bug</em> complejo y, como todos los <em>bugs</em>, inesperado. Claramente había sido introducido por el &#8220;gran cambio&#8221; (las pruebas automáticas en la rama principal pasaban sin problemas), pero el cambio se había dado en una serie larga y compleja de alteraciones a varios puntos del sistema. Si hubiera hecho pruebas automáticas en cada paso me hubiera dado cuenta, pero ahora la tarea se complicaba.</p>
<p>¿Acaso hay alguna manera sencilla y práctica de regresar a ver cada cambio y descubrir cuál causó el error?</p>
<p>En git la tenemos: el comando <code>git bisect</code>.</p>
<h3>La solución</h3>
<p><code>git bisect</code> es, según la propia documentación de git, un comando para &#8220;<a href="http://schacon.github.com/git/git-bisect.html">encontrar por búsqueda binaria el cambio que introdujo un <em>bug</em></a>&#8220;. Para usarlo, hay que localizar un commit con el bug (en mi caso, el más reciente) y uno sin el bug (para mí, el punto en el que me separé de la rama principal, digamos 495e8b). Para comenzar la bisección corrí:</p>
<pre><code>$ git bisect start </code></pre>
<p>Marqué como malo mi commit más reciente con:</p>
<pre><code>$ git bisect bad </code></pre>
<p>Y marqué como bueno el commit de la separación:</p>
<pre><code>$ git bisect good 495e8b </code></pre>
<p>A lo que git me respondió con:</p>
<pre><code>Bisecting: 16 revisions left to test after this. </code></pre>
<p>Y automáticamente hizo checkout de una versión intermedia entre <code>HEAD</code> y <code>495e8b</code>.</p>
<p>En mi caso había un problema con mis pruebas (apuntaban a URL&#8217;s que se hicieron incorrectas con el cambio), así que lo corregí, las corrí y al ver que pasaban marqué la revisión como buena con:</p>
<pre><code>$ git bisect good </code></pre>
<p>Y obtuve como respuesta:</p>
<pre><code>Bisecting: 8 revisions left to test after this. </code></pre>
<p>Y git hizo checkout de una nueva versión intermedia. Tras repetir este proceso (corregir las pruebas, correrlas, determinar si el commit era bueno o malo y avisarle a git) varias veces finalmente quedó una sola revisión por probar, la marqué como buena y git me respondió:</p>
<pre><code>b824cd36abed30de79e6765a684a4a22d5838bf3 is the first bad commit. </code></pre>
<p>¡Ajá! El culpable. Usé <code>git show b824cd</code> para ver el <em>patch</em> con los cambios, identifiqué el error y volví a mi commit más reciente:</p>
<pre><code>$ git bisect reset </code></pre>
<p>Arreglé el problema y listo, a seguir trabajando.</p>
<h3>¿Y si lo quiero automático?</h3>
<p>Por diversas razones yo tuve que estar ajustando los tests a mano para hacerlos funcionar, pero si hubieran funcionado para todos los commits por revisar, habría podido escribir un pequeño script que regresara 0 si un commit es bueno o 1 si es malo:</p>
<pre>#! /bin/bash
# Script para correr las pruebas automáticas.
python manage.py test miapp # O cualquier comando que corra tus pruebas.</pre>
<p>Y le pediría a git que lo corriera para revisar los commits y determinar si son buenos o malos.</p>
<pre><code>$ git bisect run script-de-pruebas </code></pre>
<p>Incluso pude haber automatizado los ajustes dentro del script, pero para este caso me pareció más sencillo hacerlo a mano.</p>
]]></content:encoded>
			<wfw:commentRss>http://vincoorbis.com/encontrar-bugs-usando-git-bisect/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>jQuerify bookmarklet</title>
		<link>http://vincoorbis.com/jquerify-bookmarklet/</link>
		<comments>http://vincoorbis.com/jquerify-bookmarklet/#comments</comments>
		<pubDate>Thu, 09 Feb 2012 15:59:56 +0000</pubDate>
		<dc:creator>eg</dc:creator>
				<category><![CDATA[Consultoría]]></category>

		<guid isPermaLink="false">http://vincoorbis.com/?p=533</guid>
		<description><![CDATA[<p>En algunas ocasiones es necesario tener acceso a la funcionalidad que jQuery nos proporciona en sitios en que no está disponible. Por ejemplo, si queremos diagnosticar un error, realizar cambios en el DOM o simplemente jugar con la página. En estos casos, un bookmarklet que incluye automáticamente jQuery en la página visualizada nos puede salvar la vida.</p>
<p>En la siguiente dirección podemos encontrar esta herramienta, proporcionada por learningjquery.com :</p>
<p>http://goo.gl/RZDzC</p>
<p>Sólo hay que arrastrar el link a la barra de bookmarks o de favoritos, y una vez que necesitemos jQuery damos click al mismo y nos despliega una notificación indicando si se ha cargado correctamente, que versión se cargó o si ya estaba disponible en la página.</p>
]]></description>
			<content:encoded><![CDATA[<p>En algunas ocasiones es necesario tener acceso a la funcionalidad que jQuery nos proporciona en sitios en que no está disponible. Por ejemplo, si queremos diagnosticar un error, realizar cambios en el DOM o simplemente jugar con la página. En estos casos, un bookmarklet que incluye automáticamente jQuery en la página visualizada nos puede salvar la vida.</p>
<p>En la siguiente dirección podemos encontrar esta herramienta, proporcionada por learningjquery.com :</p>
<p>http://goo.gl/RZDzC</p>
<p>Sólo hay que arrastrar el link a la barra de bookmarks o de favoritos, y una vez que necesitemos jQuery damos click al mismo y nos despliega una notificación indicando si se ha cargado correctamente, que versión se cargó o si ya estaba disponible en la página.</p>
]]></content:encoded>
			<wfw:commentRss>http://vincoorbis.com/jquerify-bookmarklet/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Bootstrap: Bueno, bonito y libre.</title>
		<link>http://vincoorbis.com/bootstrap-bueno-bonito-y-libre/</link>
		<comments>http://vincoorbis.com/bootstrap-bueno-bonito-y-libre/#comments</comments>
		<pubDate>Thu, 09 Feb 2012 04:15:04 +0000</pubDate>
		<dc:creator>Rafael Vargas</dc:creator>
				<category><![CDATA[Desarrollo en Grails]]></category>
		<category><![CDATA[Diseño de Interfaz (GUI)]]></category>

		<guid isPermaLink="false">http://vincoorbis.com/?p=518</guid>
		<description><![CDATA[<p></p>
<p>Yo se que les ha pasado. Necesitan entregar los avances de un proyecto, o es mas, el proyecto terminado pero no tienen un diseño para poder finalizarlo. Una solución buena, rápida y bonita es Bootstrap, de la gente que esta detras de twitter.  Bootstrap es un conjunto de herramientas (HTML + CSS + jQuery) para facilitar y apoyar en el desarrollo de aplicaciones web.</p>
<p>Algunas características padres de Bootstrap son:</p>

* Es compatible con los navegadores mas populares (si, Internet Explorer 7), incluyendo tablets y smartphones
* Completamente responsivo
* Tiene soporte de HTML5 y CSS3
* Es código abierto
* No es pesado

<p>Para nuestro framework favorito de desarrollo, existen plugins que reemplazan el scaffolding por default. Aquí pueden ver un ejemplo rápido de Grails + Bootstrap.</p>
]]></description>
			<content:encoded><![CDATA[<p><a href="http://twitter.github.com/bootstrap/"><img class="size-medium wp-image-522 " title="bootstrap" src="http://vincoorbis.com/wp-content/uploads/2012/02/bootstrap.png" alt="Bootstrap de Twitter" /></a></p>
<p>Yo se que les ha pasado. Necesitan entregar los avances de un proyecto, o es mas, el proyecto terminado pero no tienen un diseño para poder finalizarlo. Una solución buena, rápida y bonita es <strong><a title="Bootstrap" href="http://twitter.github.com/bootstrap/">Bootstrap</a></strong>, de la gente que esta detras de twitter.  Bootstrap es un conjunto de herramientas (HTML + CSS + jQuery) para facilitar y apoyar en el desarrollo de aplicaciones web.</p>
<p>Algunas características padres de Bootstrap son:</p>
<ul>
<li>* Es compatible con los navegadores mas populares (si, Internet Explorer 7), incluyendo tablets y smartphones</li>
<li>* Completamente responsivo</li>
<li>* Tiene soporte de HTML5 y CSS3</li>
<li>* Es <a title="Bootstrap en GitHub" href="https://github.com/twitter/bootstrap/">código abierto</a></li>
<li>* No es pesado</li>
</ul>
<p>Para nuestro <a title="Grails" href="http://grails.org/">framework favorito de desarrollo</a>, existen <a title="Twitter Bootstrap Scaffolding" href="https://github.com/robfletcher/twitter-bootstrap-scaffolding">plugins</a> que reemplazan el scaffolding por default. <a title="Ejemplo de Twitter y Bootstrap" href="http://grails-twitter-bootstrap.cloudfoundry.com/">Aquí</a> pueden ver un ejemplo rápido de Grails + Bootstrap.</p>
]]></content:encoded>
			<wfw:commentRss>http://vincoorbis.com/bootstrap-bueno-bonito-y-libre/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Notificaciones en Android</title>
		<link>http://vincoorbis.com/notificaciones-en-android/</link>
		<comments>http://vincoorbis.com/notificaciones-en-android/#comments</comments>
		<pubDate>Tue, 07 Feb 2012 21:39:26 +0000</pubDate>
		<dc:creator>cc</dc:creator>
				<category><![CDATA[Desarrollo y Programación]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[notificaciones]]></category>
		<category><![CDATA[toast]]></category>

		<guid isPermaLink="false">http://vincoorbis.com/?p=490</guid>
		<description><![CDATA[<p>Las notificaciones son una parte importante en las aplicaciones, pues estan le pueden garantizar al usuario que algo ha cambiado o esta cambiando de estado en la aplicación,  Android cuenta con la clase Toast que permite mostrar notificaciones sencillas que serán visibles solo por algunos segundos y desaparecerán sin necesidad de la interacción del usuario.</p>
<p>Realizar una notificación con Toast es muy sencillo , solo necesitamos seguir los siguientes pasos.</p>

Crear el objeto Toast
Posicionar el mensaje en pantalla (opcional)
Mostrar el mensaje

<p>Crear el objecto Toast</p>
<p>La clase Toast tiene el método de clase makeText() que construye un objecto Toast a partir de los siguientes parámetros:</p>

El contexto de la actividad.
El mensaje que desea mostrarse.
La duración del mensaje. Este parámetros puede tomar los valores LENGTH_LONG o LENGTH_SHORT, dependiendo de la duración que deseemos tenga el mensaje.

<p>Así por ejemplo si deseamos crear una notificación con el mensaje ...]]></description>
			<content:encoded><![CDATA[<p>Las notificaciones son una parte importante en las aplicaciones, pues estan le pueden garantizar al usuario que algo ha cambiado o esta cambiando de estado en la aplicación,  Android cuenta con la clase Toast que permite mostrar notificaciones sencillas que serán visibles solo por algunos segundos y desaparecerán sin necesidad de la interacción del usuario.</p>
<p>Realizar una notificación con Toast es muy sencillo , solo necesitamos seguir los siguientes pasos.</p>
<ol>
<li>Crear el objeto Toast</li>
<li>Posicionar el mensaje en pantalla (opcional)</li>
<li>Mostrar el mensaje</li>
</ol>
<p><strong>Crear el objecto Toast</strong></p>
<p>La clase Toast tiene el método de clase makeText() que construye un objecto Toast a partir de los siguientes parámetros:</p>
<ol>
<li>El contexto de la actividad.</li>
<li>El mensaje que desea mostrarse.</li>
<li>La duración del mensaje. Este parámetros puede tomar los valores LENGTH_LONG o LENGTH_SHORT, dependiendo de la duración que deseemos tenga el mensaje.</li>
</ol>
<p>Así por ejemplo si deseamos crear una notificación con el mensaje HOLA MUNDO el código seria el siguiente:</p>
<p>Toast toast = Toast.makeText(getApplicationContext(), &#8220;HOLA MUNDO&#8221;, Toast.LENGTH_SHORT);</p>
<p><strong>Posicionar el mensaje en pantalla</strong></p>
<p>El método que permite posicionar el mensaje en la pantalla es setGravity que funciona con los siguientes parámetros</p>
<ol>
<li>La zona donde se mostrará el mensaje, las opciones están contenidas en la clase Gravity: CENTER, RIGHT, LEFT, BOTTOM e inclusive se pueden hacer combinaciones utilizando “|”. (Por default el mensaje se muestra con la opción BOTTOM).</li>
<li>Desplazamiento en X.</li>
<li>Desplazamiento en Y.</li>
</ol>
<p>Los desplazamientos X y Y se realizan a partir de la zona en que se posiciono el mensaje en el primer parámetro.</p>
<p>Ahora supongamos que deseamos que el mensaje se muestre en la parte derecha del centro:</p>
<p>toast.setGravity(Gravity.RIGHT | Gravity.CENTER, 0, 0);</p>
<p><strong>Mostrar el mensaje</strong></p>
<p>Por ultimo tenemos el método show que será el que mostrara el mensaje en la pantalla.</p>
<p>Toast.show()</p>
<p><img src="http://vincoorbis.com/wp-content/uploads/2012/02/toast.png" alt="" /></p>
<p>&nbsp;</p>
<p><strong>Código del ejemplo</strong></p>
<p>button.setOnClickListener( new View.OnClickListener() {<br />
@Override<br />
public void onClick(View v) {<br />
// TODO Auto-generated method stub<br />
Toast toast = Toast.makeText(getApplicationContext(), &#8220;HOLA MUNDO&#8221;, Toast.LENGTH_LONG);<br />
toast.setGravity(Gravity.RIGHT | Gravity.CENTER, 0, 0);<br />
toast.show();<br />
}<br />
});</p>
]]></content:encoded>
			<wfw:commentRss>http://vincoorbis.com/notificaciones-en-android/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Trabajando desde casa.</title>
		<link>http://vincoorbis.com/trabajando-desde-casa/</link>
		<comments>http://vincoorbis.com/trabajando-desde-casa/#comments</comments>
		<pubDate>Tue, 07 Feb 2012 21:06:16 +0000</pubDate>
		<dc:creator>is</dc:creator>
				<category><![CDATA[Consultoría]]></category>

		<guid isPermaLink="false">http://vincoorbis.com/?p=486</guid>
		<description><![CDATA[<p>Trabajar desde casa puede ser una actividad mutuamente benéfica, tanto para la empresa como para uno mismo. Uno puede ahorrarse el tráfico citadino, el costo del transporte y ganar tiempo para estar con la familia. La empresa ahorra en electricidad, en equipo y en mantener un lugar más dentro de sus instalaciones.</p>
<p>Pero trabajar en casa también exige tal vez mas compromiso que una labor normal de oficina. Sobre todo por estar rodeado del ambiente mas cómodo que existe, tu propio hogar.</p>
<p>Trabajar en casa necesita:</p>

Un fuerte compromiso: El que no esté el jefe viendo sobre tu hombro cada cinco minutos no quiere decir que no te comprometas a sacar el trabajo. Al contrario, aprovecha que no existen ese tipo de distracciones.
Comunicación: Cuando uno trabaja en la oficina, ciertamente es muy fácil levantar la cabeza y preguntar en caso de existir alguna duda sobre ...]]></description>
			<content:encoded><![CDATA[<p>Trabajar desde casa puede ser una actividad mutuamente benéfica, tanto para la empresa como para uno mismo. Uno puede ahorrarse el tráfico citadino, el costo del transporte y ganar tiempo para estar con la familia. La empresa ahorra en electricidad, en equipo y en mantener un lugar más dentro de sus instalaciones.</p>
<p>Pero trabajar en casa también exige tal vez mas compromiso que una labor normal de oficina. Sobre todo por estar rodeado del ambiente mas cómodo que existe, tu propio hogar.</p>
<p>Trabajar en casa necesita:</p>
<ul>
<li><strong>Un fuerte compromiso:</strong> El que no esté el jefe viendo sobre tu hombro cada cinco minutos no quiere decir que no te comprometas a sacar el trabajo. Al contrario, aprovecha que no existen ese tipo de distracciones.</li>
<li><strong>Comunicación:</strong> Cuando uno trabaja en la oficina, ciertamente es muy fácil levantar la cabeza y preguntar en caso de existir alguna duda sobre los requerimientos de un proyecto. Cuando estás en casa, no hay nadie a quien preguntarle y dependes de varias herramientas de comunicación (Google Talk, Skype, teléfono). Mantén siempre tus herramientas de comunicación conectadas y procura mantener siempre esa aura de información. Siempre la vas a necesitar.</li>
<li><strong>Cero distracciones:</strong> Televisión, Xbox, Playstation, juegos de computadora, Netflix. Esos villanos que parece que siempre están tratando de obtener tu atención. Déjalos a un lado y mejor utilízalos en horarios no hábiles. Hasta te la vas a pasar mejor y sin cargos de conciencia por no saber que está pasando en la oficina.</li>
<li><strong>Respeta tus horarios:</strong> Imponte horarios como entrar siempre a las 9 de la mañana y dentro de lo posible salir a las 6. Toma 1 hora para comer, salir, pasear, atender algún mandado, lo que sea que te distraiga un rato. Si estas atorado en algo, un buen baño de agua tibia siempre trae la solución.</li>
<li><strong>Vístete:</strong> Cuando piensas en trabajar en casa siempre te imaginas estar en pijama (en el mejor de los casos), crocs, despeinado, y sin siquiera haberte lavado los dientes. Recuerda que estás trabajando y eres un profesional. No te pongas traje si no lo acostumbras, pero ropa cómoda es mejor que tus chones de bolitas. Y si de repente te piden un Skype con cámara?</li>
<li><strong>La familia</strong>: Hazle saber a la familia que estás trabajando y no estás de vacaciones. Esa línea es tan delgada que se llega a perder entre las múltiples labores domésticas.</li>
</ul>
<p>Concéntrate en tu trabajo y si es necesario, promete que sacarás esa basura en la tarde después de trabajar. Pero ni un segundo después.</p>
<p>Trabajar en casa suena delicioso, tiene sus encantos, pero pide mucha fuerza de voluntad y compromiso. Al final de un trabajo bien hecho, verás que vale la pena.</p>
]]></content:encoded>
			<wfw:commentRss>http://vincoorbis.com/trabajando-desde-casa/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Los clientes son amigos, no comida</title>
		<link>http://vincoorbis.com/los-clientes-son-amigos-no-comida/</link>
		<comments>http://vincoorbis.com/los-clientes-son-amigos-no-comida/#comments</comments>
		<pubDate>Sat, 04 Feb 2012 03:32:57 +0000</pubDate>
		<dc:creator>eg</dc:creator>
				<category><![CDATA[Consultoría]]></category>

		<guid isPermaLink="false">http://vincoorbis.com/?p=483</guid>
		<description><![CDATA[<p>Un cliente es más que su dinero, es más que el proyecto que desarrolla con nosotros, es parte del gran ecosistema de empresas que existen en este país. Nuestra filosofía de trabajo nos permite percibir al cliente como lo que en realidad es: una organización que requiere ser auxiliada en la resolución de una problemática para poder brindar un servicio que mejora la calidad de vida de cientos, miles o incluso de millones de personas. De esta forma, VincoOrbis se percibe a sí misma como una empresa cuyo rango de acción no se reduce a las personas que utilizarán los sistemas o sitios web que desarrollamos, sino que es capaz de intervenir de una forma positiva en el diario acontecer de la sociedad mexicana.</p>
<p>Es muy fácil satanizar al cliente y verlo como el malo de la película. Lo verdaderamente difícil ...]]></description>
			<content:encoded><![CDATA[<p>Un cliente es más que su dinero, es más que el proyecto que desarrolla con nosotros, es parte del gran ecosistema de empresas que existen en este país. Nuestra filosofía de trabajo nos permite percibir al cliente como lo que en realidad es: una organización que requiere ser auxiliada en la resolución de una problemática para poder brindar un servicio que mejora la calidad de vida de cientos, miles o incluso de millones de personas. De esta forma, VincoOrbis se percibe a sí misma como una empresa cuyo rango de acción no se reduce a las personas que utilizarán los sistemas o sitios web que desarrollamos, sino que es capaz de intervenir de una forma positiva en el diario acontecer de la sociedad mexicana.</p>
<p>Es muy fácil satanizar al cliente y verlo como el malo de la película. Lo verdaderamente difícil es comprender la esencia de las necesidades que presenta, buscar la forma más óptima de resolverla y entregarle un producto que le cambie la vida. Esto sólo puede lograrse con una definición de requerimientos completa y precisa, con un proceso de desarrollo integral y de calidad, y manteniendo la comunicación y realimentación en todo momento.</p>
]]></content:encoded>
			<wfw:commentRss>http://vincoorbis.com/los-clientes-son-amigos-no-comida/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Creación de documentos Word con php</title>
		<link>http://vincoorbis.com/creacion-de-documentos-word-con-php/</link>
		<comments>http://vincoorbis.com/creacion-de-documentos-word-con-php/#comments</comments>
		<pubDate>Fri, 03 Feb 2012 23:51:34 +0000</pubDate>
		<dc:creator>cc</dc:creator>
				<category><![CDATA[Desarrollo en PHP]]></category>

		<guid isPermaLink="false">http://vincoorbis.com/?p=461</guid>
		<description><![CDATA[<p>En ocaciones los sistemas informáticos necesitan crear algun tipo de documentos basados en la información que se maneja en el sistema. Y aunque el navegador siempre tiene la opción de imprimir lo que mostramos en pantalla, aquí propongo una solución elegante y que permite a los usuarios llenar una plantilla en el navegador y poder exportarla a un documento en formato word que resultará más practico y familiar para los usuarios.</p>
<p>La plantilla en word</p>
<p>Primero necesitamos crear una plantilla en formato word, para este ejemplo usaré el formato de una carta de recomendación donde los recuadros amarillos son los que serán, rellenados con ayuda de php.</p>
<p></p>
<p>Al asignar las etiquetas al documento, es importante que las estas sean únicas en el documento y que estas no sean sub palabras de otra etiqueta ó palabra del documento, esto es importante dado que el ...]]></description>
			<content:encoded><![CDATA[<p>En ocaciones los sistemas informáticos necesitan crear algun tipo de documentos basados en la información que se maneja en el sistema. Y aunque el navegador siempre tiene la opción de imprimir lo que mostramos en pantalla, aquí propongo una solución elegante y que permite a los usuarios llenar una plantilla en el navegador y poder exportarla a un documento en formato word que resultará más practico y familiar para los usuarios.</p>
<p><strong>La plantilla en word</strong></p>
<p>Primero necesitamos crear una plantilla en formato word, para este ejemplo usaré el formato de una carta de recomendación donde los recuadros amarillos son los que serán, rellenados con ayuda de php.</p>
<p><img src="http://vincoorbis.com/wp-content/uploads/2012/02/plantilla-doc.png" alt="" /></p>
<p>Al asignar las etiquetas al documento, es importante que las estas sean únicas en el documento y que estas no sean sub palabras de otra etiqueta ó palabra del documento, esto es importante dado que el algoritmo de PHPWord al reemplazar los valores a las etiquetas, revisa secuencialmente el documento en busca de la etiqueta y si el texto que encuentra en el documento coincide con alguno de los casos señalados anteriormente estos serán sustituidos.</p>
<p>Una vez que tenemos lista nuestra plantilla debemos guardarla en un directorio que sea accesible desde nuestro programa php.</p>
<p><strong>El formulario de la plantilla</strong></p>
<p>Hay que crear un formulario que de preferencia debe ser los más similar a la plantilla para que pueda ser rellenada por el usuario, tal como se muestra en la siguiente imagen</p>
<p><img src="http://vincoorbis.com/wp-content/uploads/2012/02/plantilla-html.png" alt="" /></p>
<p>En ocaciones algunos de los campos podran ser rellenados de forma automatica con php, como por ejemplo en este caso la fecha que es rellenada con el siguiente código.</p>
<p>$date = getDate();</p>
<p>$months = array(1 =&gt; &#8220;Enero&#8221; , 2 =&gt; &#8220;Febrero&#8221; , 3 =&gt; &#8220;Marzo&#8221; , 4 =&gt; &#8220;Abril&#8221; , 5 =&gt; &#8220;Mayo&#8221; , 6 =&gt; &#8220;Junio&#8221; , 7 =&gt; &#8220;Julio&#8221;, 8 =&gt; &#8220;Agosto&#8221; , 9 =&gt; &#8220;Septiembre&#8221; , 10 =&gt; &#8220;Octubre&#8221; , 11=&gt;&#8221;Noviembre&#8221;,12=&gt;&#8221;Diciembre&#8221;);</p>
<p>echo $date['mday'] . &#8221; de &#8221; . $months[(int)$date["mon"]] . &#8221; de &#8221; . $date["year"];</p>
<p>También es conveniento añadir etiquestas o tooltips en las casillas para que el usuario pueda saber que debe escribir en cada uno de los recuadros.</p>
<p>Suponiendo que contamos con una base de datos con un directorio de personas a recomendar podriamos rellenar todos los demás campos con la información que contamos, o simplemente dejar los campos limpios para que el usuario pueda capturar sus datos.</p>
<p><strong>El documento</strong></p>
<p>Ahora la parte interesante que es implimentar el código necesario para rellenar la plantilla con los datos que que obtenemos del formulario anterior.</p>
<p>Primero necesitamos descargar la librería PHPWord que encontraras  http://phpword.codeplex.com/releases/view/49543, PHPWord es una librería programada con php que permite crear y manipular documentos creados en Word.</p>
<p>Basicamente debemos realizar los siguientes pasos para crear el documento:</p>
<ol start="1">
<li>Leer la plantilla.</li>
<li>Asignar los valores a las etiquetas.</li>
<li>Guardar el archivo.</li>
<li>Descargar el archivo.</li>
</ol>
<p>A continuación explico el código</p>
<ol start="1">
<li>Leer la plantilla.</li>
</ol>
<p>Primero debemos crear un objeto de PHPWord que será el que nos permitira manipular los documentos de Word:</p>
<p>$phpWord = new PHPWord();</p>
<p>Luego con el método loadTemplate del objeto creado anteriormente leemos la plantilla y la almacenamos en el objecto $document de la clase PHPWord_Template.</p>
<p>$document_path = &#8220;plantillas/carta1.docx&#8221;;</p>
<p>$document = $phpWord-&gt;loadTemplate($document_path);</p>
<ol start="2">
<li>Asignar los valores a las etiquetas.</li>
</ol>
<p>La clase PHPWord_Template posee un método llamado setValue el cual admite dos parametros:</p>
<ul>
<li>$search, que es el nombre de la etiqueta en la plantilla a ser remplazada</li>
<li>$replace, Texto que será colcado en el lugar de la etiqueta</li>
</ul>
<p>De esta forma si deseamos que en la etiqueta fechacarta desemos porner el texto que obtenemos del formulario que se encuentra en el input fechacarta, escribiremos lo siguiente:</p>
<p>$document-&gt;setValue(&#8216;fechacarta&#8217;,$_POST["fechacarta"]);</p>
<p>y de forma similar para todos los demás valores:</p>
<p>$document-&gt;setValue(&#8216;nombredirigido&#8217;,$_POST["nombredirigido"]);</p>
<p>$document-&gt;setValue(&#8216;personarecomendada&#8217;,$_POST["personarecomendada"]);</p>
<p>$document-&gt;setValue(&#8216;fechalaboracion&#8217;,$_POST["fechalaboracion"]);</p>
<p>$document-&gt;setValue(&#8216;puestopersona&#8217;,$_POST["puestopersona"]);</p>
<p>$document-&gt;setValue(&#8216;nombreotorgante&#8217;,$_POST["nombreotorgante"]);</p>
<p>$document-&gt;setValue(&#8216;direccionotorgante&#8217;,$_POST["direccionotorgante"]);</p>
<p>$document-&gt;setValue(&#8216;telefonootorgante&#8217;,$_POST["telefonootorgante"]);</p>
<p>$document-&gt;setValue(&#8216;faxotorgante&#8217;,$_POST["faxotorgante"]);</p>
<p>$document-&gt;setValue(&#8216;correootorgante&#8217;,$_POST["correootorgante"]);</p>
<ol start="3">
<li>Guardar el archivo.</li>
</ol>
<p>Al momento de guardar los cambios aplicados a la plantilla es importante realizarlo en otra dirección para no sobrescribir nuestra plantilla y dejarla inutilizable para la creación de otro documento.</p>
<p>$filename  = &#8220;recomendacion.docx&#8221;;</p>
<p>$document-&gt;save($filename);</p>
<ol start="4">
<li>Descargar el archivo.</li>
</ol>
<p>Ahora debemos indicar al navegador que se realizará una descarga y el archivo que será descargado, eso lo hacemos con el siguiente código:</p>
<p>header(&#8216;Content-Description: File Transfer&#8217;);</p>
<p>header(&#8216;Content-type: application/force-download&#8217;);</p>
<p>header(&#8216;Content-Disposition: attachment; filename=&#8217;.basename($filename));</p>
<p>header(&#8216;Content-Transfer-Encoding: binary&#8217;);</p>
<p>header(&#8216;Content-Length: &#8216;.filesize($filename));</p>
<p>Despues abrimos el archivo que será descargado, para que este sea enviado.</p>
<p>readfile( $filename);</p>
<p>Finalizamos Eliminado el archivo creado pues no deseamos almacenarlo en el servidor</p>
<p>unlink($filename);</p>
]]></content:encoded>
			<wfw:commentRss>http://vincoorbis.com/creacion-de-documentos-word-con-php/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Validación de HTML5 con meta tags de Facebook</title>
		<link>http://vincoorbis.com/validar-html5/</link>
		<comments>http://vincoorbis.com/validar-html5/#comments</comments>
		<pubDate>Tue, 31 Jan 2012 06:06:08 +0000</pubDate>
		<dc:creator>jl</dc:creator>
				<category><![CDATA[Desarrollo en PHP]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Facebook]]></category>
		<category><![CDATA[jsp]]></category>
		<category><![CDATA[meta tags]]></category>
		<category><![CDATA[w3c]]></category>

		<guid isPermaLink="false">http://vincoorbis.com/?p=448</guid>
		<description><![CDATA[<p>Uno de los problemas de la obsesión con la validación de html es que muchas veces tomamos algunos &#8220;warnings&#8221; del resultado de nuestra validación como problemas de vida  o muerte y no nos detenemos hasta corregir lo necesario para eliminar las advertencias.</p>
<p>La verdad es que llevamos la preocupación al extremo y a veces nuestra vanidad gana, olvidamos que el verdadero objetivo de la validación es indicarnos los errores o las advertencias que puedan afectar la funcionalidad del sitio y darnos una pista para ayudarnos a corregirlo, sin embargo, no siempre estamos en un error.</p>
<p>Uno de los ejemplos más claros de problemas que en realidad no lo son, son las meta etiquetas de Facebook en nuestras páginas con html5, desde que decides incluirlas en tus sitios, sabes que algo no va a salir bien:

&#60;meta property="og:type" content="website" /&#62;</p>
<p>El validador de la WC3 ...]]></description>
			<content:encoded><![CDATA[<p>Uno de los problemas de la <strong>obsesión con la validación</strong> de html es que muchas veces tomamos algunos &#8220;warnings&#8221; del resultado de nuestra validación como problemas de vida  o muerte y no nos detenemos hasta corregir lo necesario para eliminar las advertencias.</p>
<p>La verdad es que llevamos la preocupación al extremo y a veces nuestra vanidad gana, olvidamos que el verdadero objetivo de la validación es indicarnos los errores o las advertencias que puedan afectar la funcionalidad del sitio y darnos una pista para ayudarnos a corregirlo, sin embargo, no siempre estamos en un error.</p>
<p>Uno de los ejemplos más claros de problemas que en realidad no lo son, son las meta etiquetas de Facebook en nuestras páginas con html5, desde que decides incluirlas en tus sitios, sabes que algo no va a salir bien:<br />
<code><br />
&lt;meta property="og:type" content="website" /&gt;</code></p>
<p>El <a title="W3C Validator" href="http://validator.w3.org/">validador </a>de la WC3 nos comenzará a marcar cosas como:</p>
<p><code>Attribute property not allowed on element meta at this point</code></p>
<p>Así que, queremos incluir los opengraph meta tags de Facebook en nuestro sitio, pero si lo hacemos, el código no valida. Nos comenzamos a volver locos y no encontramos una solución, queremos que el código valide, pero no queremos perdernos el hype de Facebook, ¿qué hacer?</p>
<p>Pues la respuesta <strong>es muy simple</strong>, básicamente los opengraph meta tags de Facebook únicamente necesitan ser leidos por Facebook mismo, cuando &#8220;escanea&#8221; nuestra página. Así que lo único que necesitamos hacer es identificar de donde viene la petición y así poder devolver los meta tags únicamente cuando Facebook los solicita.</p>
<p>Si trabajamos con Java/JSP , podemos resolverlo:<br />
<code>&lt;%<br />
String ua=request.getHeader("user-agent").toLowerCase();<br />
if(ua.matches(".*facebookexternalhit.*")){<br />
}<br />
%&gt;<br />
&lt;meta property="og:image" content="images/facebook.jpg" /&gt;<br />
...<br />
&lt;%<br />
}<br />
%&gt;</code></p>
<p>También con tags:<br />
<code>&lt;c:set var="ua" value="${header['User-Agent']}" scope="page"/&gt;<br />
&lt;c:if test="${ua.matches('.*facebookexternalhit.*')}"&gt;<br />
&lt;meta property="og:image" content="images/facebook.jpg" /&gt;<br />
...<br />
&lt;/c:if&gt;</code></p>
<p>Si trabajamos con php:<br />
<code>&lt;?<br />
if(eregi("facebookexternalhit", $_SERVER['HTTP_USER_AGENT'])){<br />
echo '&lt;meta property="og:type" content=xxxxxxxxxxxxx';<br />
// continue with the other open graph tags<br />
}<br />
?&gt; </code></p>
<p>Con esto, los meta tags sólo estarán disponibles cuando Facebook los busque y nuestro código validará sin problema.</p>
]]></content:encoded>
			<wfw:commentRss>http://vincoorbis.com/validar-html5/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Generar un archivo WAR de Grails mucho más pequeño.</title>
		<link>http://vincoorbis.com/generar-un-archivo-war-de-grails-mucho-mas-pequeno/</link>
		<comments>http://vincoorbis.com/generar-un-archivo-war-de-grails-mucho-mas-pequeno/#comments</comments>
		<pubDate>Fri, 27 Jan 2012 22:19:56 +0000</pubDate>
		<dc:creator>jl</dc:creator>
				<category><![CDATA[Desarrollo en Grails]]></category>
		<category><![CDATA[grails]]></category>
		<category><![CDATA[nojars]]></category>
		<category><![CDATA[war]]></category>

		<guid isPermaLink="false">http://vincoorbis.com/?p=443</guid>
		<description><![CDATA[<p>Cuando generamos un archivo WAR de una aplicación Grails nos damos cuenta de que este puede ser muy grande. Si estamos utilizando Grails 2.0, por ejemplo, el archivo generado con los plugins instalados por defecto pesa más de 30MB, lo cual no es un problema real de almacenaje con los estándares actuales, pero si lo es a la hora de subirlo vía ftp a un servidor productivo, por ejemplo.</p>
<p>Hacer &#8220;deploys manuales&#8221; en ambientes productivos no es lo más recomendado,  para desplegar aplicaciones en ambientes productivos lo mejor es hacerlo a través de algún software que te permita hacer Integraciones Continuas, Bamboo y CloudBees son buenos ejemplos, sin embargo, no es objeto de este post ahondar en este tema.</p>
<p>En el caso más común, normalmente generamos un archivo WAR con nuestra aplicación y lo subimos vía ftp o http para después desplegarlo en nuestro contenedor, sin embargo, si ...]]></description>
			<content:encoded><![CDATA[<p>Cuando generamos un archivo WAR de una aplicación Grails nos damos cuenta de que este puede ser muy grande. Si estamos utilizando Grails 2.0, por ejemplo, el archivo generado con los plugins instalados por defecto pesa más de 30MB, lo cual no es un problema real de almacenaje con los estándares actuales, pero si lo es a la hora de subirlo vía ftp a un servidor productivo, por ejemplo.</p>
<p>Hacer &#8220;deploys manuales&#8221; en ambientes productivos <strong>no es lo más recomendado</strong>,  para desplegar aplicaciones en ambientes productivos lo mejor es hacerlo a través de algún software que te permita hacer Integraciones Continuas, <a title="Integración continua con Bamboo" href="http://www.atlassian.com/software/bamboo/overview">Bamboo</a> y <a title="Compila, despliega y maneja aplicaciones java." href="http://www.cloudbees.com/">CloudBees</a> son buenos ejemplos, sin embargo, no es objeto de este post ahondar en este tema.</p>
<p>En el caso más común, normalmente generamos un archivo WAR con nuestra aplicación y lo subimos vía ftp o http para después desplegarlo en nuestro contenedor, sin embargo, si usamos la opción -nojars durante la construcción del WAR Grails nos construirá un archivo mucho, mucho más ligero:</p>
<p><code>$grails war -nojars</code></p>
<p>Para un WAR con ambiente productivo:</p>
<p><code>$grails prod war -nojars</code></p>
<p><strong>¿Cuál es el truco?</strong></p>
<p>Ninguno, simplemente Grails construye un WAR sin las librerías que normalmente estarían en la carpeta WEB-INF/lib dentro del WAR, dejándonos la tarea a nosotros de subir estas librerías directamente en nuestro contenedor de aplicaciones (en la carpeta tomcat/lib por ejemplo). Cabe mencionar que no solo tendremos que subir manualmente estas librerías al contenedor, también tendremos que mantenerlas actualizadas.</p>
<p><strong>¿Y la primera vez?</strong></p>
<p>Existen varias formas de generar las librerías la primera vez, sin embargo, la más simple es crear el WAR completo una sola vez, desplegarlo y copiar las librerías necesarias.</p>
<p>Esperamos que esto les ayude y reduzca su consumo de ancho de banda.</p>
]]></content:encoded>
			<wfw:commentRss>http://vincoorbis.com/generar-un-archivo-war-de-grails-mucho-mas-pequeno/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Las 7 maravillas de trabajar con un equipo sumamente talentoso</title>
		<link>http://vincoorbis.com/las-7-maravillas-de-trabajar-con-un-equipo-sumamente-talentoso/</link>
		<comments>http://vincoorbis.com/las-7-maravillas-de-trabajar-con-un-equipo-sumamente-talentoso/#comments</comments>
		<pubDate>Wed, 25 Jan 2012 19:01:57 +0000</pubDate>
		<dc:creator>alice</dc:creator>
				<category><![CDATA[Consultoría]]></category>

		<guid isPermaLink="false">http://vincoorbis.com/?p=416</guid>
		<description><![CDATA[<p>En una empresa eres tan fuerte como la suma de tu equipo.</p>
<p>En Vinco Orbis tenemos la gran fortuna de tener un equipo conformado con gente sumamente talentosa y debo decir que es una de las satisfacciones laborales más grandes que he tenido la oportunidad de vivir.</p>
<p>Claro que existen retos asociados a tener un gran equipo. Como líder de grupo te obliga a mantenerte constantemente alerta de varias cosas, por ejemplo, tienes que estar pendiente de no crear una muerte de la creatividad por aburrimiento ni dejar pasar que por tener talento y que las cosas salgan fácil esto provoque un freno a su crecimiento.</p>
<p>Basado en mi experiencia personal de los últimos dos años, estas son las 7 maravillas de trabajar con un equipo así:</p>
<p>1. Ideas. Grandes ideas.  </p>
<p>De la definición del proyecto original a la versión final entregada hay muchos ...]]></description>
			<content:encoded><![CDATA[<p>En una empresa eres tan fuerte como la suma de tu equipo.</p>
<p>En Vinco Orbis tenemos la gran fortuna de tener un equipo conformado con gente sumamente talentosa y debo decir que es una de las satisfacciones laborales más grandes que he tenido la oportunidad de vivir.</p>
<p>Claro que existen retos asociados a tener un gran equipo. Como líder de grupo te obliga a mantenerte constantemente alerta de varias cosas, por ejemplo, tienes que estar pendiente de no crear una muerte de la creatividad por aburrimiento ni dejar pasar que por tener talento y que las cosas salgan fácil esto provoque un freno a su crecimiento.</p>
<p>Basado en mi experiencia personal de los últimos dos años, estas son las 7 maravillas de trabajar con un equipo así:</p>
<p>1. <strong>Ideas. Grandes ideas.  </strong></p>
<p>De la definición del proyecto original a la versión final entregada hay muchos cambios. Nosotros siempre buscamos incluir las mejores ideas y sugerencias que en la gran mayoría de las ocasiones vienen directamente del equipo encargado de desarrollar el proyecto. Y tenemos la gran ventaja de contar con un equipo que cuando detecta una oportunidad de optimización o mejora no se queda callado sino que lo expresa y lo justifica.</p>
<p>Mi única misión en esos casos es asegurarme de que una idea brillante no se quede en el tintero, que tenga siempre la oportunidad de ser presentada al cliente e incorporada al producto final.</p>
<p>2.<strong> Tienen afición por encontrar la respuesta. </strong></p>
<p>Muchas veces no tenemos la respuesta, pero nos encanta ir a encontrarla. Si no conocen la solución saben que hay muchas herramientas para investigarla, incluyendo involucrar a alguien más del equipo y encontrar en conjunto cómo resolver cualquier obstáculo que encuentren.</p>
<p>3. <strong>Evitan problemas futuros haciendo las cosas bien desde el principio. </strong></p>
<p>No es fácil navegar la línea entre la prisa por cumplir las fechas de entrega y dedicarle tiempo a hacer algo bien desde la primera vez. La preferencia siempre es hacia evitar el retrabajo, incluyendo dedicar un poco de tiempo a lo que podría ser una fase dos del proyecto y dejar de una vez las bases para que el proyecto desde el inicio soporte crecimiento aunque en este momento no exista la certeza de que se vaya a continuar.</p>
<p>4. <strong>Su foco es hacia los resultados. </strong></p>
<p>Consideran que los resultados son más importantes que el tiempo que toma llevarlos a cabo y los presentan con orgullo.</p>
<p>5. <strong>Son necios pero flexibles. </strong></p>
<p>De vez en cuando encuentra una mejor manera de hacer las cosas, y las adoptan. En ocasiones esto significa empezar de nuevo desde cero, en ese momento se evalúa y si vale la pena, adelante, la prioridad es no permanecer en un proceso ineficiente simplemente porque siempre se ha hecho así.</p>
<p>6. <strong>Suben la barra</strong>.</p>
<p>El concepto de &#8220;hasta aquí es suficiente&#8221; es móvil. No podemos perdernos en llevar todo a la perfección, pero si se esfuerzan en hacer pequeñas cosas que suben la calidad de lo que entregan. Que un botón funcione está bien. Pero que ese mismo botón tenga un ícono, un tooltip de ayuda y una etiqueta que indique claramente lo que hace ese botón es aún mejor.</p>
<p>7. <strong>No se estancan</strong>.</p>
<p>El talento te gana algunos pasos, pero no te lleva por si solo al final del camino en la mejor versión posible. Para ello necesitas, estudiar, investigar, proponer, intentar, probar, verificar, adoptar, compartir, continuar.</p>
]]></content:encoded>
			<wfw:commentRss>http://vincoorbis.com/las-7-maravillas-de-trabajar-con-un-equipo-sumamente-talentoso/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

