Páginas

sábado, 24 de diciembre de 2011

Migrando páginas web ASP.NET de Windows a Linux

¿Recuerdan una entrada titulada "Migrando una página web ASP.NET de Windows a Linux"? Esta entrada es como una continuación de aquella así que si esta interesado en el tema tal vez prefiera leer esa primero a modo de antecedentes comenzare por relatar que tuve que migrar varias páginas web hechas en ASP.NET en Windows con NetFramework y servidas mediante IIS hacia servidores Linux con Mono y servirlas mediante Apache + Mod mono.


En el principio del proyecto original hace años se intento pero Apache pero en ese entonces no podía servir páginas ASP.NET por si mismo (aun no puede) y no existía algún complemento como Mod mono y aunque Mono tenia su propio servidor llamado XSP este no era lo suficientemente estable para soportar la carga de trabajo de una empresa como esta, de hecho aun no lo es todavia, y por eso ahora usamos Mod Mono.


Usando SharpDevelop en lugar de Visual Studio para probar las aplicaciones con Mono y XSP previamente a probar en los servidores Linux se pudo afinar las instrucciones y entonces si pasar a ambientes más reales donde solo que hubo que ajustar algunas características de seguridad que resultaron más altas que en Windows y entonces vino el problema. Parecía no haber poder humano que hiciera que los caracteres especiales, ñ y letras acentuadas se vieran correctamente.


La base de datos. Muchos trabajamos con bases de datos PostGreSQL y estas suelen ser creadas por default (desconozco si en algunas versiones pone alguna codificación por default más avanzada) con codificación (encoding) SQL_ASCII, que según la documentación de PostGreSQL con SQL_ASCII el servidor interpretara los valores 0 al 127 del estándar ASCII, así que más que una declaración de que juego de caracteres usar es una orden de ignorar la codificación lo que puede causar problemas cuando se usen caracteres no ASCII como letras acentuadas, la ñ o símbolos. Debido a esto de ser posible hay que tener cuidado de definir desde el principio la base de datos con un juego de caracteres, de preferencia UTF8, que es UNICODE porque es apto para todos los idiomas, y esto es importante independientemente del tipo de tecnología de su base de datos que ustedes utilicen.


Seguramente su manejador de base de datos tendrá alguna opción para consultar el juego de caracteres de su base de datos pero si no lo encuentran, en PostGreSQL pueden ver la codificación de su base de datos con la siguiente instrucción:

SELECT encoding FROM pg_database where datname='[nombre de la base de datos]';

Esto arrojara un número que puede traducirse así, por poner ejemplos de encodings comunes, aunque esta tabla es solo una muestra muy limitada.

0SQL_ASCII
6UTF8 (UNICODE)
8LATIN1
16LATIN9 (ISO 8859-15)

La codificación de la base de datos también puede hacerse a base de datos ya creadas actualizando (Update) el campo “encoding” de “pg_database” que consultamos con la instrucción anterior pero esto no afecta de inmediato y “automagicamente” a toda la información previamente guardada en las tablas de la base de datos, eso lo tendremos que ajustar por nuestros propios medios. Además de que las conexiones abiertas antes del cambio no se verán afectadas, para que tome efecto deberán ser cerradas y volver a establecer la conexión para que se conecten usando el nuevo juego de caracteres, y dependiendo del tipo de cambio de encoding en las consultas podría haber problemas al tratar de leer caracteres que no existen en un juegos de caracteres pero si en el otro o que en ambos encodings un mismo código represente caracteres diferentes y eso altere nuestra información; son cosas a tomar en cuenta.


Lo mejor, de ser posible es empezar la base de datos con el encoding adecuado y grabarle los datos desde un respaldo, si se pasa de SQL_ASCII a un encoding mayor como UTF8, Latin1 o Latin9 no debería haber problemas... en teoría, en la practica ya sabemos como son las cosas.

La codificación de la base de datos

ODBC y la conexión a la base de datos. Aunque los datos estén correctamente guardados en la base de datos estos no vienen solos a nuestras aplicaciones si no que necesitamos conectarnos y la mayoría de las veces lo hacemos usando un ODBC. No creo que halla necesidad de explicar eso pero si de recordar o advertir que hay ODBC ANSI y los hay UNICODE y tengo experiencias de que si consultas una base de datos con caracteres UNICODE usando una conexión ANSI los caracteres especiales no llegan bien sino que llegan símbolos de interrogación (?) y como ya vienen así para nuestras aplicaciones será imposible distinguir que símbolo era originalmente y eso será un gran problema. Los ODBC ANSI funcionan de maravilla con bases de datos SQL_ASCII pero si van a usar una con UNICODE asegúrense de que el ODBC valla a la par.


Además recuerden o sepan que en la cadena de conexión podemos dar indicaciones sobre la codificación de caracteres a utilizar al conectarnos a la base de datos. Así podemos indicarle si queremos que se conecte usando SQL_ASCII, Latin1, UTF8 o lo que sea que nuestra base de datos soporte.

DRIVER={[ODBC]};Server=[IP];Encoding=[Encoding];DATABASE=[DB];UID=[Usuario];PWD=[contraseña];

* Nota extra para desarrolladores en .NET: Ver tutorial para conectarse a bases de datos PostGreSQL sin utilizar ODBC.


Consultando la base de datos. Si no podemos controlar la codificación de caracteres en la base de datos o solo vamos a hacer unos pocos querys ocasionales que no ameriten tanto esfuerzo pero aun así necesitemos el texto consultado a la base de datos en un encoding especifico podemos recurrir a indicarlo dentro de la instrucción de consulta, por ejemplo con la función convert de SQL de la siguiente manera:

SELECT convert( 'texto', 'SQL_ASCII', 'UTF8')

El código anterior convierte el primer parámetro, 'texto' de su codificación original a UTF8.


La codificación de caracteres de las páginas web. Los navegadores web traducen el código de la página en algo visible al usuario y el texto también debe ser interpretado y para eso también manejan los estándares de codificación de caracteres que ya mencionamos antes como podemos ver en la imagen a continuación.


La mayoría de los navegadores te dejan elegir un juego de caracteres por default o ellos mismos lo ponen pero también tienen la capacidad de detectar el juego de caracteres usado por la página para mostrar correctamente el contenido ¿Y cómo es que las páginas le dicen al navegador cual es el estándar que deben usar? Usando una cabecera especial en su código fuente.

<meta http-equiv="Content-Type" content="text/html; charset=utf-8">

Aquí estamos indicando que el texto en la página es UTF8 y el browser así lo interpretará así que tómenlo en cuenta.


* Nota extra para desarrolladores en .NET: En el archivo Web.config de nuestras aplicaciones web podemos indicar explicitamente más detalles sobre el idioma de nuestra página agregando las siguientes configuraciones que ajustan el contenido de la página al formato regional del idioma y país además de en los caracteres especiales también en cosas como las fechas, los signos y formatos de moneda y cosas así.

<globalization
requestEncoding="utf-8"
responseEncoding="utf-8"
fileEncoding="utf-8"
uiCulture="es-MX"
culture="es-MX"
/>

Con lo anterior debería de bastar pero si además desean indicarle al compilador cual es el encoding que debe reconocer cuando genere su dll o ejecutable pueden hacerlo así, aunque en lo personal a mi me parece ya exagerar un poquito pero no esta demás eliminar los posibles cabos sueltos ¿verdad?

<compilation defaultLanguage="c#" debug="true">
<compilers>
<compiler language="cs;csharp"
extension=".cs"
type="Microsoft.CSharp.CSharpCodeProvider,System"
compilerOptions="/codepage:utf8" />
</compilers>
</compilation>

Y hablando de no dejar cabos sueltos, queda un ultimo punto que comentar que si bien no es exactamente el mismo tema de conservar información compatible entre sistemas y plataformas si puede ser un complemento para la parte visual de nuestras aplicaciones web.


HTML. El HTML no es un lenguaje de programación si no uno más limitado para la estructuración y formato de las páginas web donde indicamos donde va cada elemento en pantalla y como se debe de ver, y tiene sus limitaciones. Para HTML la ñ o la á no existen pero si en el código de tu página...

Para ver esto en pantalla...debes poner
á&aacute;
é&eacute;
í&iacute;
ó&oacute;
ú&uacute;
Á&Aacute;
É&Eacute;
Í&Iacute;
Ó&Oacute;
Ú&Uacute;
ñ&ntilde;
Ñ&Ntilde;
ü&uuml;
Ü&Uuml;

Claro, los caracteres arriba mencionados solo son unos pocos, y cambiarlos todos manualmente es tedioso pero podríamos hacer funciones para automatizar el cambio o mejor aún, aprovechar funciones ya incluidas en los lenguajes de programación, por ejemplo en C# tenemos la función HtmlEncode que reemplaza en una cadena de caracteres los caracteres que tienen algún equivalente en código HTML de modo que la cadena resultante donde se han reemplazado sea aceptada y bien interpretada por los navegadores, hasta cambia los saltos de linea por su código HTML.

Server.HtmlEncode(string);

En caso de usar PHP también tenemos un par de funciones que pueden hacer un trabajo similar. htmlspecialchars(string) y htmlentities(string) son algo "parecido pero diferente", pues estas funciones convierten ciertos caracteres que tienen un significado especial en HTML y deben ser representados por entidades HTML si se desea preservar su significado para que se muestren así en pantalla en lugar de ser tomados por código fuente, descuadren la página y no se vean. Estas funciones devuelven una cadena de caracteres con algunas de estas conversiones realizadas. htmlspecialchars solo afecta a los caracteres más útiles para la programación web.


Las traducciones realizadas son:


  • '&' (ampersand) se convierte en '&amp;'

  • '"' (comillas dobles) se convierten en '&quot;'

  • "'" (comilla simple) se convierte en '''

  • '<' (menor que) se convierte en '&lt;'

  • '>' (mayor que) se convierte en '&gt;'

En cambio se usa htmlentities si se requieren traducir todas las entidades de caracteres HTML. Ambas funciones son útiles para prevenir que texto suministrado por el usuario, un archivo o desde la base de datos contenga código HTML.


¿Algo más? Por ultimo recordarles que si su página además usa JavaScript para mostrar algo en pantalla consideren que también maneja códigos para representar los caracteres especiales y que no son iguales que los de HTML.

Para ver esto en pantalla...debes poner
áá
éé
íí
óó
úú
ññ

Para que lo tomen en cuenta si de repente en algún control dinámico les aparece un carácter extraño.


Y bueno, con eso finalizamos de revisar esta serie de puntos a considerar al desarrollar una página web lo más universal posible.

Npgsql. Conectarse a BD PostGreSQL sin usar ODBC

Como sabrán .NET es un Framework de programación que en teoría pretende ser independiente de la plataforma y facilitar el desarrollo aunque en la practica esa portabilidad es un tanto cuanto artificial y depende del proyecto Mono para funcionar en más plataformas además de Windows, pero al menos esta estandarizado y permite crear aplicaciones multiplataforma aunque con algunas restricciones.


Npgsql es un .Net Data Provider (Proveedor de Datos) independiente de NET o Mono que permite a estos establecer conexiones a bases de datos PostGreSQL que son tan comunes. Así Npgsql es una alternativa a los ODBC para cuando no tenemos el control de estos o no nos dan los resultados esperados, y Npgsql para el desarrollador resulta muy similar en uso a ODBC.

¿Cómo utilizarlo?

Podemos descargar la ultima versión desde la página oficial y agregarlas a nuestro proyecto con facilidad copiando la libreria Npgsql.dll en el directorio de la aplicación (o en otro directorio si ha configurado Path to Private Components).


En aplicaciones web ASP.NET y Web Services se debe alojar Npgsql.dll y Mono.Security.dll en la carpeta bin de la aplicación.


Luego agregamos a nuestro sistema como referencia las .dll antes mencionadas y ya podremos usarlas en nuestro código.


Donde las usemos hay que agregar los espacios de nombres Data y Npgsql. Aquí dejo un mínimo ejemplo de la sintaxis.


using System.Data;
using Npgsql;


// Establecer la conexión a base de datos
NpgsqlConnection conn = new NpgsqlConnection("[cadena de conexion]");
// Abrir la conexion
conn.Open();
// Indicar una instrucción a la base de datos
NpgsqlCommand Command = new NpgsqlCommand("[instruccion SQL]", conn);
// Ejecutar la instrucción SQL
Command.ExecuteNonQuery();
// Cerrar la conexión
conn.Close();


Cómo pueden ver es idéntico al uso de conexiones por ODBC, pero ya no dependemos del ODBC instalado en la PC donde nuestra aplicación sea ejecutada. Prácticamente es cambiar todo donde diga ODBC por Npgsql, por ejemplo un OBDCDataReader se reemplaza por NpgsqlDataReader.


La cadena de conexión que usaremos para Npgsql es estandar. Yo la utilizo así:


Server=[IP];Port=[Puerto];Database=[DB];User Id=[Usuario];Password=[Contraseña];


En las versiones más recientes de Npgsql la codificación es siempre UNICODE por lo que el atributo encoding ha quedado obsoleto, pero en caso necesario, las versiones más antiguas si manejan encoding SQL_ASCII o UNICODE según se indique en la cadena de conexión.


Y así es como logramos conectarnos a una base de datos PostGreSQL desde Mono sin depender de ODBC.

Datos curiosos ¿navideños?


Si, todos sabemos que la navidad tiene origenes paganos y tal pero que mientras halla asueto y regalos a la mayoria no les interesa y ya. En este momento no expondre mis negativas teologicas a la navidad pero si dejare una leve lista de datos curiosos... diviértanse:


  • Durante la navidad se festeja el solsticio de invierno y el aumento en la duración de los dias.

  • Según la biblia durante el nacimiento de cristo habia pastores durmiendo al aire libre, cosa imposible en el frio clima invernal de Israel por lo que Jesús debio haber nacido en otra epoca del año de clima más suave como primavera u otoño. Lo cierto es que la biblia hace poco enfasis en el nacimiento de Cristo y no da muchos datos.

  • La mayoria de los datos "tradicionales" sobre el nacimiento de Cristo vienen del evangelio apocrifo Pseudo-Mateo que la propia iglesia reconoce como falso.

  • El papa Fabian (236-250) declaro como herejes sacrilegos a los que intentaran calcular la fecha del nacimiento de Cristo.

  • La iglesia catolica adopto el 25 de diciembre como la natividad para "cristianizar" las fiestas paganas del nacimiento de dioses solares.

  • Las iglesias orientales y ortodoxas festejan el 6 de enero el nacimiento de Cristo.

  • El traje rojo de Santa Claus no viene de antiguas leyendas ni de antecedentes historicos, se le representaba de verde hasta que la publicidad de Coca-Cola popularizo al Santa Claus de rojo.

  • La tradición de los nacimientos la empezo san Francisco de Asis en 1223 en Greccio, Italia.

  • La costumbre de comer 12 uvas con las 12 campanadas de media noche es muy reciente, empezo en el 1er tercio del siglo XX.

  • La leyenda de los 3 reyes magos data del siglo VI, y en la iglesia ortodoxa representan a 12 reyes magos no a 3. Lo cierto es que en la biblia no se dice cuantos eran ni sus nombres ni se les llama reyes sino astrologos.

  • En otras tradiciones los reyes magos no son ni 3 ni 12 sino 2, 4, 6 o 60.

  • Baltazar fue blanco hasta el siglo XVI cuando se le cambio a negro por estrategia de la iglesia.

  • La tradición de que los reyes magos regalan juguetes a los niños comenzo en el siglo XIX.

  • Las tarjetas de navidad fueron inventadas en 1843 por Henry Cole, quien encargo a un pintor que dibujara una escena navideña que luego mando reproducir a una imprenta en tarjetas en las que escribio saludos y felicitaciones para enviarlas a parientes y amigos.

  • El origen del árbol de navidad se remonta al 2do o 3er milenio a.C. donde el árbol representaba la fecundidad de la tierra y los adornos compenzaban su follaje perdido durante el otoño y el invierno para atraer de nuevo el espiritu de la naturaleza.

  • El árbol sagrado del paganismo era el roble, la cristiandad lo sustituyo por el abeto basandose en algunas leyendas donde abetos crecian donde robles paganos eran derribados.

  • Una leyenda de los bretones (Celtas de Inglaterra) dice que el árbol de navidad fue descubierto por Persifal (caballero del rey Arturo) mientras buscaba el santo grial.

  • El árbol de navidad moderno comenzo en Alemania en el siglo XVI, llego a la mayoria de Europa hasta el siglo XIX y no se popularizo en el mundo hasta el primer cuarto del siglo XX.

  • En siglos anteriores en los paises nordicos los árboles eran adornados con caramelos y velas, las esferas de vidrio fueron un añadido italiano.

jueves, 22 de diciembre de 2011

Miér... Jueves de cine: El gato con botas

Empiezo por comentar que salen gatos y eso pone en entredicho mi imparcialidad. Comentado lo anterior prosigo con decir que vi Shreck 1, 2 y 3. Las dos primeras me gustaron, la tercera se me hizo meh y la cuarta ni la he visto y no hay ganas. La del gato, pues sale un gato y la escogió mi hermana, bueno. Entremos en materia...


El gato con botas nos cuenta sus orígenes mediante una aventura previa a su aparición en Shrek 2 sobre como Gato cae en desgracia y empieza a tratar de limpiar su nombre, e intercalando flashbacks de su más tierna infancia y juventud y así introduce a este universo de cuentos mezclados a Humpty Dumpy del cuento del mismo nombre y una gatita llama Kitty Patitas suaves de creación propia y voz de Salma Hayek que una vez más comparte créditos con Antonio Banderas.


Nuestros tres protagonistas tendrán que cooperar para cumplir el objetivo común de robar la gansa de los huevos de oro que esta en el castillo del gigante en el cielo que nos cuentan en Juanito y las habichuelas mágicas, y ese es el planteamiento de la historia para dar pie a una película dinámica, con escenas graciosas y más familiar aun que las películas de Shrek que tienen un poco más de bromas adultas que esta del gato con botas, y desde ahora aclaro que no hay cameos de personajes que no vienen a cuento (ja! que no vienen a cuento, cuentos, Sherk... ya se, ya se, es malo) y creo que fue mejor así para darle una identidad propia y que buscará méritos independientes.


La película es palomera y entretenida pero nada más, no levanta al nivel de frescura que tuvo Shrek en sus inicios ni hay una trama memorable y si un héroe es tan grande como su villano... entonces Gato es uno muy pequeño en sentido tanto figurado como literal, aunque funciona muy bien en solitario a diferencia de Burro. Creo que tuvo dos problemas esta cinta, tiene una historia en teoría buena a pesar de lo trillada pero esta muy masticada para el espectador, bien para niños pero le falta ese toque extra que muchas películas de animación tienen para gustar a los más grandes también, y además al ser precuela el  gato tenia que terminar como forajido y tenia que desaparecer el rastro de los personajes no vistos en Shrek y eso limitaba el posible final.


La animación es de alta calidad como es usual de Dreamworks, no la vi en 3D pero dicen que esta bien y me llamo la atención que la ambientación de escenarios de la película es muy rara, es como una mezcla de España, de donde toma estereotipos andaluces principalmente pero combinado con pueblos coloniales del norte de México, puesto en una zona árida como los westerns por momentos.


La vi en español y el doblaje es bueno pues Banderas y Salma hacen sus propios papeles en español y se nota que Banderas esta cómodo con el papel de Gato y Salma ya tiene experiencia con el como coprotagonista y su papel es de cierta manera similar a otros papeles live action que ha tenido con Banderas. Lo que no me gusto es la voz de Humpty y no porque lo hiciera mal, en este momento no recuerdo quien es el actor pero es que simplemente esa voz la escuchado muchas veces y me venían a la mente otros personajes con la misma voz.


La película esta regular, y bueno, si la ven no hace daño y si no la ven tampoco se pierden de gran cosa... Cya!


martes, 20 de diciembre de 2011

El Fan #1 de Zelda


La imagen que ven arriba es de una figura limitada de Link & Epona, de The Legend of Zelda, edición limitada, solo hay 500 en el mundo mundial y estará a la venta hasta el año que entra. Esta que ven la pusieron como premio Latamel y Atomix para un concurso donde por medio de un vídeo tratar de demostrar que eres el fan más fan de Zelda en este país y el ganador ha sido el amigo Kid y su vídeo fue este:



La información completa de la premiación y otros vídeos participantes pueden verlo en la página de Atomix, aquí.


Felicidades amigo.

sábado, 17 de diciembre de 2011

Gnoblis Week

Hola de nuevo mis estimad@s cero lectores y no me extraña puesto que mis ultimas entradas han sido de aburrida programación y los únicos comentarios que me dejan son de cosas sobre el firmware de teléfonos Android de los que de momento no tengo nada más que decir... y si, en la semana he vuelto a tener una semana laboral algo pesada consistente en resolver nuevas situaciones que me dejan mentalmente más agotado que cuando son semanas de talacha que deja mi mente libre y ansiosa de escribir de otros temas, no me malinterpreten, que ganas de volver al blog tuve solo que ánimos de hacerlo no, llegaba a casa con ganas de descansar, de hecho hoy sábado trabaje hasta las 7:30pm... la época decembrina ya saben. Y debido a eso tengo de nuevo algunas entradas atrasadas... que repetitivo me estoy volviendo con ese tema, debo hacer algo al respecto.


La caída del host ¿Alguien noto nuestra ausencia el pasado fin de semana? El pasado domingo y el lunes este blog no estuvo disponible. Bueno, tampoco la página de InGameVG pues nuestro host nos tiro el sitio. La explicación oficial es que paso porque el plugin que contaba las visitas a este blog al parecer hizo muchas consultas y les bajaba el rendimiento así que cuello... abajo nuestros sitios. Así que de momento este sitio esta sin plugins a excepción de uno que intercepta los intentos de comentarios spam. También se perdió la ultima entrada a esta página pero tenia respaldo de eso y bueno, ya estamos online de nuevo.


Comentaba que la razón dada en el párrafo anterior es la explicación oficial. La explicación extraoficial y probablemente la más correcta es que Robin le movió a la base de datos.


Recuentos videojueguiles. Ya que mencione a InGameVG, de momento por cuestiones laborales de la temporada estamos fuera de circulación... más o menos. Seguiremos poniendo contenidos aunque no transmitamos el programa en vivo como siempre, hasta enero que volvamos a la normalidad. ¿Ya vieron el debate del GOTY de este año? Los candidatos escogidos fueron Skyrim, Uncharted 3, Zelda SS, Portal 2 y Batman AC, quedaron fuera cosas como GeOW3 pero los que están consideramos que son dignos contendientes por méritos propios y si no les gustan culpen a la democracia, y hablando de democracia pasen a InGameVG a votar por su favorito para el GOTY 2011.


Además del GOTY les prepare con ayuda de mis compañeros Travis y Kid un especial de casi una hora en honor a los 10 años de Game Cube, consola con grandes juegos que cumplió su aniversario el pasado noviembre, pero como noviembre estuvo tan cargado terminamos haciendo este especial hasta ahora. Escúchenlo aquí: Especial 10mo aniversario de Game Cube.


Feliz fin de semana. Por fin, descansar en doRmingo... las dos ultimas semanas había trabajado el doRmingo y se siente un poco contra natura así que me siento bien de volver al asueto dominical esta semana.


Qué se la pasen bien y nos leemos luego aquí en este rincón del Internet. Cya!

martes, 13 de diciembre de 2011

JavaScript: Cerrar un popup desde la página madre

Típico, que estas programando una página web y necesitas una ventana popup para apoyar alguna función de la página principal, poner alguna advertencia o que el usuario seleccione algún dato que será pasado a la página principal… cosas comunes.


Pero esta vez me tope con un caso un poco diferente, resulta que necesitaba que fuese la página madre la que después de terminar un proceso propio cerrara al popup y… pues instrucciones para manipular a la página madre desde el popup hay muchas pero en sentido inverso no tantas. La forma más sencilla es apoyándose en una variable para poder mantener el control del popup y manipularlo de la siguiente manera usando JavaScript.


Si quieren probar un ejemplo sencillo con un par de páginas simples en su computadora bajen este ejemplo antes de continuar: DESCARGAR EJEMPLO.


Dentro del archivo, La página principal es javascript.html así que ábrala en su navegador porque será la pagina donde probaremos abrir y cerrar un popup y a leer un dato en la página principal desde un popup para lograr un efecto en esta página hija. Se verá algo parecido a la imagen de al lado.


La otra, javascript2.html será un popup llamado desde la primera página y lo usaremos para que lea un dato en que escribamos en la página madre.


Así vemos como un evento puede abrir el popup y el otro lo cierra, todo desde la misma ventana madre. Este es solo un ejemplo para que usted estimado lector tenga total control del proceso pero en cuestiones más practicas como la que yo comentaba, al poder cerrar el popup desde una función en la ventana madre puede invocarse desde algún otro método automático en el momento preciso para mi sin necesidad de intervención humana.


El código para las funciones de abrir y cerrar popup usadas en estos botones -y para obtener la resolución del monitor y centrar el popup en la pantalla como bonus- de ejemplo es el siguiente:

var popup = null; // Variable compartida entre las funciones
function abrir()
{
var height = (screen.height-66)/2;
var width = (screen.width-66)/2;
popup = window.open('loading.gif', 'popup',
'width=66,height=66,top='+height+',left='
+width+',resizable=no,scrollbars=no');
}
function cerrar()
{
popup.close(); // Cerrar la ventana
}

INCONVENIENTES: Pero hay un inconveniente con este método, resulta que solo funciona mientras la página original no se recargue, al hacer un postback se pierde el control del popup y ya no puede cerrarse desde la página madre lo cual reduce los escenarios donde este uso del javascript nos es útil, entonces hay que hacerle un ajuste extra para poder hacer que el popup se cierre cuando lo necesitamos.


Para lidiar con ese efecto podríamos dar alguna instrucción desde la página original… si supiera cual o como, si alguno sabe por favor dígamelo, y como no pude entonces podemos probar el camino inverso accediendo desde el popup a la página madre en busca de alguna señal que indique cuando debe cerrarse mediante window.opener que nos da la posibilidad de leer campos en la ventana principal. El código interesante de ese popup es que manda llamar a una función que lee cierto campo en la ventana principal y si encuentra un dato especifico se cierra así mismo. Si no lo encuentra entonces algunos segundos después va a volver a buscar. El código de la función sigue los principios de este ejemplo:

function timer()
{
// Leer el campo en la página madre
var caracter = opener.document.forms[0].texto.value;
if (caracter.length &gt; 0) // Si hay algo
{
alert('En la ventana madre escribio esto: '
+ caracter);
window.close(); // Cerrar este popup
}
else // Si no hay nada
{
alert('Escriba en la ventana antes de 5 segundos.');
setTimeout(timer, 5000); // buscar en 5 segundos
}
}

La idea es que setTimeout([nombre de la función], [tiempo en milisegundos]); nos permite buscar algún dato o variable en la página madre que nos va a indicar que ya es momento de que el popup se cierre, y como no lo puedo cerrar desde la página principal simplemente le dejamos una señal para que se cierre a si mismo. Para la versión de producción mía en lugar de usar un botón mejor invoco la función desde el metodo onload del body de la página, cuestión de adaptarse.

lunes, 5 de diciembre de 2011

El retorno de un héroe

Tengo un juego de Xbox 360, es Lost Odissey, un J-RPG exclusivo de esa consola desarrollado por Mistwalker que me llamo la atención desde hace años y que pronto podre jugar. Un detalle que me gusta de ese juego aun sin haber jugado todavía y que le puede gustar a cualquiera son las historias que incluye, relatos escritos por Kiyoshi Shigematsu compilados como 1000 años de sueños y antes ya publique el primero titulado La Partida de Hanna y ahora procedo a poner aquí otro relato titulado El Retorno de un Héroe. En lo personal, este es mi preferido.


El Retorno de un Héroe.


Se encuentra solo entre una multitud de hombres toscos, dando cuenta de su bebida en un rincón de la única taberna de la vieja ciudad. Un hombre solitario cruza la puerta de la taberna. Recubre sus enormes proporciones el atuendo de un guerrero. Su sucio uniforme sugiere que viene de lejos. La fatiga se le refleja en la cara, pero sus ojos tienen un brillo penetrante, la mirada de un luchador en acción.


El ruido de la taberna se silencia al momento. Todas las miradas del lugar se clavan en el soldado con respeto y gratitud. Por fin ha terminado la larga guerra contra el país vecino, y los hombres que han luchado en el frente vuelven a casa. Ese es el caso de este militar.


El soldado se sienta en la mesa de al lado de Kaim y engulle un trago de licor con la contundencia de un bebedor habitual, un hombre que bebe para matar su dolor.


Dos, tres, cuatro...


Otro cliente, el típico rufián de ciudad, se le acerca con una botella en la mano y una sonrisa obsequiosa.


Deja que te ofrezca un trago - dice el hombre -, como muestra de gratitud por tus heroicos esfuerzos por la patria.


Sin sonreír, el soldado deja que el hombre llene su copa.


¿Cómo ha sido estar en el frente? Apuesto a que realizaste muchas hazañas en el campo de batalla.


El soldado vacía su copa en silencio. El rufián se la vuelve a llenar y muestra una sonrisa aun más zalamera.


Ahora que somos amigos, ¿qué tal si me cuentas algunas historias de la guerra?. Tus brazos son grandes y fuertes, ¿a cuántos soldados enemigos matas...?


Sin mediar palabra, el soldado arroja el contenido de su copa a la cara. El rufián se pone hecho una furia y saca un cuchillo. En cuanto sale de la vaina, el puño de Kaim lo lanza volando por el aire. Ante la poderosa unión de Kaim y el soldado, el rufián sale corriendo mascullando maldiciones.


Los dos hombres lo ven huir y comparten una débil sonrisa. A Kaim no le hace falta hablar con el soldado para saber que vive en una profunda tristeza. Por su parte, el soldado, tras haber engañado a la muerte en repetidas ocasiones, es consciente de la sombra que acecha en la expresión de Kaim.


El barullo volvió a la taberna. Kaim y el soldado comparten unas bebidas.


Tengo una esposa y una hija que no he visto desde que me enrolé - dice el soldado- hace ya tres largos años.


Por primera vez se permite sonreír tímidamente mientras saca del bolsillo una foto de su mujer y su hija y se la enseña a Kaim: la esposa es una mujer de lozana frescura, la hija es aún muy joven.


Ellos son la razón por la que he sobrevivido. La idea de volver vivo a casa con ellos era lo que me daba fuerzas en el combate.


¿Tu hogar está lejos de aquí?


No, mi pueblo está justo tras el siguiente paso. Estoy seguro de que han oído que la guerra ha terminado y están deseando que vuelva.


Si él quisiera podría estar en casa esta noche. Está muy cerca.


Pero...- El soldado acaba el trago de licor y gruñe- Tengo miedo.


¿Miedo?, ¿De qué?


Quiero ver a mi esposa y a mi hija, pero tengo miedo de que me vean. No sé cuántos hombres habré matado en estos tres años. No tuve elección. Tuve que hacerlo para seguir vivo. Si quería volver con mi familia, no tenía otra opción salvo matar un soldado enemigo tras otro, y cada uno de ellos tenía una familia que había dejado en casa. Para sobrevivir en el combate, tenías que seguir matando para que no te mataran. En el frente no tenía tiempo para pensar en esas cosas. Estaba ocupado intentando sobrevivir. Aunque ahora lo veo, ahora que la guerra ha terminado. Hay tres años de pecados grabados en mi cara. La cara de un asesino. No quiero enseñar esta cara a mi mujer y a mi hija. El soldado saca una bolsa de piel de la que extrae una pequeña piedra. Le dice a Kaim que es una gema sin pulir, algo que encontró poco después de marchar al campo de batalla.


¿Una gema?- pregunta Kaim sin convencimiento -. La piedra de la mesa es de un negro apagado sin indicios del brillo que debería tener una gema.


Brillaba cuando la encontré. Estaba seguro de que a mi hija la encantaría cuando se la llevara a casa. Pero, poco a poco, la piedra perdió su brillo y se volvió oscura. Cada vez que mataba a un soldado enemigo, algo parecido a la mancha de su sangre aparecía en la superficie de la piedra. La piedra está manchada con los pecados que he cometido. La llamo mi “piedra de los pecados”.


No tienes porqué sentirte tan culpable. Tuviste que hacerlo para seguir vivo.


Lo sé -dice el soldado-. Lo sé. Pero aun así... Al igual que yo, los hombres que maté tenían pueblos a los que volver y familias que los esperaban allí.


El soldado hace una pausa antes de dirigirse de nuevo a Kaim:


Supongo que tú también tendrás familia. Kaim niega con la cabeza.


No -dice-. No tengo familia.


¿Un pueblo al menos?


No tengo hogar al que volver.


Un eterno viajero, ¿eh?


Pues sí. Ese soy yo.


El soldado sonríe un poco y muestra a Kaim una sonrisa amarga. Cuesta decir cuánto cree lo que Kaim le ha dicho. Desliza su “piedra de los pecados” en la bolsa de piel y le dice:


¿Sabes lo que creo? Si la piedra se vuelve más oscura cada vez que quita una vida, debería recuperar algo de su brillo cada vez que salve una vida.


En lugar de responder, Kaim apura las últimas gotas de su licor de su copa y se levanta de la mesa. El soldado permanece en su silla y Kaim, mirándole fijamente, le da un consejo:


Si tienes un lugar al que volver, deberías volver. Tan solo ve, por mucho que te abrume la culpa. Estoy seguro de que tu esposa y tu hija lo entenderán. No eres un criminal. Eres un héroe: luchaste con el corazón para seguir vivo.


Me alegro de haberte conocido - dice el soldado - . Necesitaba oír eso.


Le ofrece la mano derecha a Kaim, y éste se la estrecha.


Espero que tus viajes vayan bien - dice el soldado.


Los tuyos acabarán pronto - dice Kaim con una sonrisa dirigiéndose a la puerta.


Justo entonces el rufián se lanza contra Kaim desde detrás, pistola en mano.


¡Cuidado! - grita el soldado, lanzándose hacia Kaim. Conforme Kaim gira, el rufián apunta y grita:


¡A mí nadie me trata así, hijo de perra!


El soldado salta entre los dos hombres y recibe un balazo en el abdomen.


Y así, tal y como ansiaba hacer, el soldado ha salvado una vida. Irónicamente, el soldado ha dado su única vida por la de Kaim, un hombre que no puede envejecer ni morir.


Tumbado en el suelo, casi inconsciente, el soldado pone la bolsa de piel en la mano de Kaim.


Mira mi “piedra de los pecados”, por favor. Quizás... quizás - dice sonriendo débilmente - , haya recuperado algo de su brillo.


La sangre brota de su boca, ahogando la risa.


Kaim mira dentro de la bolsa y dice:


Ahora brilla. Está limpia.


¿De verdad? - jadea el soldado - . Bien. Mi hija se pondrá muy contenta...


Sonríe con satisfacción y extiende la mano en busca de la bolsa. Con cuidado, Kaim coloca la bolsa en la mano del hombre y cierra sus dedos sobre ella. El soldado exhala su último aliento y la bolsa cae al suelo. La cara del hombre muerto tiene una expresión de paz.


Sin embargo, la “piedra de los pecados” del hombre, que se ha deslizado de la bolsa, sigue negra como siempre.

sábado, 3 de diciembre de 2011

Dentro de la pokeball

¿Se han preguntado como viven sus pokemon dentro de las pokeball? ¿Por qué no se quieren dejar atrapar por una pokeball normal y funcionan mejor las otras? He aquí la respuesta.


jueves, 1 de diciembre de 2011

Gustitos

Esta semana me he podido dar algunos gustos personales, primero. Ponyo. Aquí vemos la película junto a Houdini.


Es una película que me gusto mucho y que sorpresivamente me encontré barata y bueno, venga para casa.


Lo segundo... tipico; buscas un libro por todas las librerías de la ciudad y no esta, y lo encuentras en el super. Como entrenar a tu dragon no es Skyrim.


Y hoy el tercero. Trabaje y no me pude ir a comer pero la caja chica pago este sushi.


Por que ¿Qué es la vida si uno no se da gustos de vez en cuando? Cya!