jueves, 18 de septiembre de 2014

WP - Diseño web - Ventana DIV simple 1


¡Hola nuevamente! Tenía un rato de no escribir por acá, pero es que han sucedido varias cosas en los últimos meses... mis disculpas por ello. En realidad desde hace algún tiempo quería mostrar una forma de hacer ventanas con DIV, basándome en el diseño que utilizamos para nuestro proyecto de graduación. Luego de organizar un poco mis ideas, decidí hacer  una serie de posts en donde explicara como hacer una ventana DIV, e ir mejorando el diseño en cada uno de ellos. Este es el primer post de la serie.

En esta ocasión quiero mostrar una forma sencilla de crear una ventana modal a partir de elementos DIV dentro de una página web. Una ventana modal consiste en una ventana que mantiene el foco respecto a las demás en una aplicación o sistema. En este caso, la ventana modal mantendrá el foco con respecto al resto de la página web.

Por el momento, la estructura de la ventana modal consistirá en dos elementos DIV. El primero de ellos será la ventana en sí. El segundo servirá para cubrir toda la página web, oscureciéndola, dando así la apariencia de que el resto de la página web está deshabilitada. Además, al estar encima del resto de elementos de la página, impedirá que los usuarios puedan hacer clic sobre éstos, dando el efecto de modalidad. Este DIV será conocido como DIV de fondo en el resto de este post. Está de más mencionar que el único DIV que estará sobre este fondo será el DIV de la ventana modal.

Partes de ventana DIV.
Partes de ventana DIV.

Esta ventana modal será manejada como una "clase" Javascript, con el objetivo de que más adelante podamos manejar múltiples ventanas modales dentro de una misma página web, como objetos. Por otra parte, el diseño completo de la ventana se manejará por separado, desde un archivo CSS.

Primeramente, esta es la definición de la clase VentanaDiv, contenida en el archivo ventanadiv.js:

function VentanaDiv(idventana, idfondo) {
  //Obteniendo las referencias a los DIV que utilizaremos
  this.ventana = window.document.getElementById(idventana);
  this.fondo = window.document.getElementById(idfondo);

  //Creando funciones para manipular la ventana
  this.mostrar
    = function() {
        this.fondo.style.visibility = 'visible';
        this.ventana.style.visibility = 'visible';
      };
  this.ocultar
    = function() {
        this.fondo.style.visibility = 'hidden';
        this.ventana.style.visibility = 'hidden';
      };
}
 Como puede observarse, en la primera parte de esta clase se obtienen las referencias a los DIV que se utilizarán para la ventana. Esto implica que los DIV deben existir ya dentro de la estructura DOM de la página web. Las referencias a los objetos se guardan en variables con ámbito global dentro de la clase, y se utilizan para mostrar u ocultar los DIV, en las funciones mostrar() y ocultar(), respectivamente. Éstos métodos han sido definidos dentro de la misma función constructor, y como puede observarse, lo único que hacen es mostrar u ocultar los DIV.

Luego, tenemos la hoja de estilos CSS, que define la forma en que se mostrarán los DIV dentro del sitio web:


/* Clase CSS que define el fondo oscuro */
div.fondoventana
{
    /* Para que el DIV aparezca oculto inicialmente */
    visibility:hidden;

    /* Para que el DIV cubra toda el área de la página web */
    position:fixed;
    top:0px;
    left:0px;
    width:100%;
    height:100%;

    /* Fondo negro con opacidad del 60%, que da un efecto de transparencia */
    background-color:#000000;
    /* Opacidad para Internet Explorer */
    filter:alpha(opacity=60);
    /* Opacidad en CSS3 estándar */
    opacity:0.6;

    /* Este índice debe ser mayor que el del resto de los demás elementos de la página web, para que aparezca sobre ellos */
    z-index:9;
}

/* Clase CSS que define el formato de la ventana */
div.ventana
{
    /* Para que el DIV aparezca oculto inicialmente */
    visibility:hidden;

    /* Para que la ventana aparezca centrada en la página web, con un tamaño de 300x160 píxeles */
    position:fixed;
    left:50%;
    margin-left:-150px;
    top:50%;
    margin-top:-80px;
    width: 300px;
    height:160px;

    /* Borde gris de la ventana */
    border-width:5px;
    border-color:#999999;
    border-style:solid;

    /* Color de la ventana */
    background-color:#FFFFFF;

    /* Espacio de 10 píxeles desde el borde de la ventana hasta el texto interno */
    padding:10px;

    /* Este índice debe ser mayor que el del fondo, para que la ventana esté sobre él */
    z-index:10;
}
Como puede observarse, se han definido dos clases CSS, una de ellas para el DIV fondo y otra para el DIV ventana. Se han usado clases con el objetivo de que las características definidas en la hoja de estilo puedan utilizarse en varios elementos de la página web, en caso de que quiera tenerse más de una ventana en ella.

Por otra parte, en este ejemplo sencillo las propiedades principales de la ventana ya están predefinidas: la ubicación, color, tamaño e índices verticales de los DIV ventana y fondo. Nótese que el índice z del fondo debe ser superior al de los demás elementos de la página, para poder aparecer sobre ellos y cubrirlos. El único elemento con índice z superior es el del DIV de la ventana, ya que debe aparecer por encima del fondo.

Cabe mencionar también que las posiciones de ambos DIV son fijas (position:fixed;). Esto se debe a que su posición debe estar fija con respecto a la ventana que lo contiene, y no debe afectar las posiciones de los demás elementos de la página. El DIV de fondo estará extendido en toda la ventana del explorador web, y el DIV ventana estará centrado. También debe observarse que la propiedad visibility:hidden sirve para indicar que ambos DIV estarán ocultos al abrirse la página web.

Algo que considero importante mencionar es que las características CSS aplicadas a un elemento de la página web se heredan a sus hijos. Por ello, podemos colocar cualquier cosa dentro del DIV de la ventana, confiando que esto se ocultará y mostrará cuando la ventana lo haga (a menos, claro, que estableciéramos características especiales para estos elementos).

Finalmente, se tiene el código fuente de la ṕágina web:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html><html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
    <title>Ventana DIV 1 - Ventana DIV simple</title>

    <!-- Importando archivos CSS y Javascript - Inicio -->
    <link rel="stylesheet" type="text/css" href="ventanadiv.css" />
    <script language="javascript" type="text/javascript" src="ventanadiv.js" ></script>
    <!-- Importando archivos CSS y Javascript - Fin -->
  </head>
  <body>
    <!-- Contenido de la página web - Inicio -->
    <h1>Ejemplo de ventana DIV 1</h1>
    <br />
    <a href="#" onclick="ventana.mostrar()">Haga click aquí para mostrar la ventana</a>
    <!-- Contenido de la página web - Fin -->

    <!-- DIV de fondo - Inicio -->
    <div id="divfondo"></div>
    <!-- DIV de fondo - Fin -->

    <!-- DIV de ventana - Inicio -->
    <div id="divventana">
      <p>
        <center><h3>Ventana modal</h3></center>
        <br />Bienvenido a mi primera ventana modal web.
      </p>
      <p><center><a href="#" onclick="ventana.ocultar()" >Cerrar</a></center></p>
    </div>
    <!-- DIV de ventana - Fin -->
  </body>
  <script type="text/javascript" >
    //Creación de la ventana
    var ventana = new VentanaDiv("divventana", "divfondo");
  </script>
</html>
Primeramente es necesario incluir los archivos CSS y Javascript que hemos creado especialmente para las ventanas, en el encabezado del documento. Luego de ello, en el cuerpo de la página web se ha colocado el contenido a mostrar, y después de este, los DIV de fondo y ventana. En realidad, en este diseño sencillo no importa donde se coloquen estos DIV, ya que como se dijo anteriormente, al inicio ambos estarán ocultos, y luego se mostrarán de forma fija en la ventana, por lo que no afectarán la ubicación de los demás elementos, al menos de forma visible para el usuario.

Algo muy importante que hay que recalcar es el script ubicado al final del documento. Este script es el encargado de crear el objeto VentanaDiv a partir de la clase Javascript, y que permite el funcionamiento de ésta. Se ha ubicado al final del documento debido a que la estructura DOM del sitio web se va creando conforme al orden de los elementos en el documento HTML (es decir, de izquierda a derecha y de arriba hacia abajo), y es necesario que los DIV ya existan para que el constructor de la clase VentanaDiv pueda obtener sus referencias. Por ello es de suma importancia que este script se ubique después de los DIV en el documento HTML.

Hay que notar que aunque la variable ventana se declara e instancia al final del documento, su ámbito (por así decirlo) abarca todo el documento, una vez que su declaración ha sido procesada. Por ello puede observarse que se hace referencia a ella en los dos hipervínculos que están en el cuerpo de la página web. Éstos hipervínculos no referencian a ninguna página web (por ello solo tienen el # en su propiedad HREF), sino que en el evento onclick de estos se han colocado las invocaciones a los métodos mostrar() y ocultar() de la ventana DIV, para ejecutarlos al momento de dar clic derecho sobre ellos. Esta de más decir que el hipervínculo que invoca al método mostrar()se ubica en el cuerpo visible de la página web, mientras que el hipervínculo que ejecuta el método ocultar() se ubica dentro de la ventana DIV.

Y voilá, tenemos nuestra primera ventana DIV en funcionamiento.
Ventana DIV en funcionamiento.
Ventana DIV en funcionamiento.
Esto es todo por hoy. En los siguientes artículos mostraré como crear métodos para permitir establecer el tamaño de la ventana mediante código javascript, así como incluir un botón de cierre y efecto de sombra para ésta.
Que Dios les bendiga.

Referencias


Publicado originalmente el 18/08/2012, en http://itsouvenirs.wordpress.com/2012/08/18/diseno-web-ventana-div-simple-1/.

miércoles, 17 de septiembre de 2014

WP - Consejos de programación 1 - Don’t be WET, stay DRY

En esta ocasión quiero iniciar una serie de consejos de programación que considero importantes a nivel de eficiencia, orden y -por que no decirlo – estética. Estos consejos se basan en algunas prácticas que he observado durante los pocos años de mi carrera. Algunas de esas prácticas son buenas, mientras que otras son las que quisiera evitar. También se basan en cosas interesantes que he encontrado en uno que otro artículo por el Internet (de esos artículos donde la gente gustan hablar de temas con acrónimos de 3 o 4 letras).

Iniciaré la serie compartiendo algo acerca del principio de desarrollo de software conocido como DRY (inglés: seco), que significa Don’t Repeat Yourself. Creo que ya saben más o menos por donde va la cosa, pero antes de definir el término, haré una pequeña introducción.

Introducción

Algo que he visto muchas veces es que cuando se quieren añadir nuevos elementos a una aplicación (ventanas, controles de usuario, funciones), y estos son muy similares a elementos ya existentes, lo que hacen los programadores es copiar y pegar el código fuente correspondiente a dichos elementos, y hacer las modificaciones en la copia de acuerdo a los nuevos requerimientos. Esta técnica es vulgarmente conocida en nuestro medio como “copy-paste”, y también es aplicable a la técnica que usan los estudiantes cuando buscan sus tareas en Wikipedia, El Rincón del Vago, Taringa, o Yahoo respuestas, en el peor de los casos (aceptémoslo, todos hemos aplicado esta técnica alguna vez, jejeje…)

Considero que esta una práctica muy arraigada debido a que esto se considera la forma más rápida de incluir nuevos elementos en una aplicación. Pero si se analiza cuidadosamente, al final no resulta ser la forma más rápida, porque:
  • Al crear un nuevo elemento a partir de la copia de uno ya existente, implica que es necesario cambiar parte del código fuente, para cambiar o añadir la funcionalidad deseada. También hay que tener particular cuidado con aquellos parámetros que han sido “quemados” (hard-coded) dentro de la aplicación.
  • El resultado es una aplicación con una gran cantidad de código fuente, lo que también deriva en la existencia de varios archivos desorganizados y desperdigados en la carpeta que contiene el proyecto.
  • Si se requiere cambiar una funcionalidad principal que se ha repetido en todos los elementos copiados, esta modificación debe hacerse en cada uno de ellos.

Definición de DRY y WET

Basta de hacer catarsis, procederé a definir los conceptos más formalmente. En la “ingeniería de software”, el término DRY, o “Don’t Repeat Yourself”, se refiere a reducir la repetición de información de cualquier tipo. El principio DRY dicta: “Cada pieza de conocimiento debe tener una representación única, no ambigua y autoritaria dentro de un sistema”. El término fue acuñado por Andy Hunt y Dave Thomas en su libro “The Pragmatic Programmer”. Eric Raymond hace referencia a un término equivalente, llamado SPOT (“Single Point Of Truth”) en su libro “The Art Of Unix Programming”. Cabe destacar que el término no se limita a código fuente ni datos, sino a un sistema cualquiera. Tampoco se refiere necesariamente a no repetir código fuente en un sistema informático, sino que este tenga una fuente única dentro del sistema.

El término contrario a este es WET (inglés: mojado), al cual se le han dado muchos significados: “We Enjoy Typing”, “Write Everything Twice”, “We Edit Terribly”, etc. Obviamente, significa que existen “piezas de conocimiento” con múltiples representaciones, que podría traducirse como tener la misma información repetida varias veces.

Ventajas de DRY

Ustedes se preguntarán por qué tomarse la molestia de aplicar este principio, si han vivido felizmente con la técnica de copy-paste por mucho tiempo, a tal punto que ya tienen práctica con la mano izquierda para hacer las secuencias de teclas Ctrl+C y Ctrl+V. Pues bueno, las ventajas que yo he observado de primera mano en las aplicaciones que he visto son las siguientes:
  • Toda elemento (función, método, procedimiento, clase) e información dentro de la aplicación posee un origen único, por lo que si se requiere modificar la funcionalidad principal de alguno de ellos, debe hacerse en un solo punto.
  • La cantidad de código fuente se reduce.
  • El desglose de funcionalidades permite el manejo de múltiples capas. Esto también permite una organización más clara de los archivos de código fuente.
  • El trabajo de añadir nuevos elementos basados en elementos anteriores se reduce, ya que no implicará copiar y modificar código fuente para satisfacer los nuevos requerimientos, sino más bien reutilizar elementos y funcionalidades ya existentes. En el mejor de los casos, solo será necesario invocar los elementos ya existentes, con parámetros distintos, para obtener los resultados requeridos.

Desventajas de DRY

A pesar de todo, y como todo en esta vida, DRY posee algunas desventajas que hay que tener en cuenta:
  • Muchas veces se requerirá de análisis profundo para encontrar una forma aceptable de centralizar todos los elementos de un sistema. La construcción de este kernel para la aplicación puede tomar algo de tiempo.
  • En algunos casos, la solución centralizada será menos eficiente en tiempo de ejecución que la solución repetitiva. Un buen ejemplo de ello es cuando una consulta muy utilizada en una base de datos relacional (digamos de SQL Server) se coloca en una función de usuario para poderla usar varias veces. La función por si sola puede ser eficiente, pero al intentar utilizarla dentro de otras consultas, puede ser más lento y pesado que si la consulta no hiciera uso de ella.
  • Dejar de lado el hábito de copy-paste, jejeje…

Cómo implementar el principio DRY

Dicho lo anterior, ahora os describiré algunas técnicas que os pueden ayudar a implementar el concepto de DRY en vuestros programillas:
  • Refinamiento del sistema en partes individuales con funcionalidades específicas y diferenciadas (técnicas top-down y bottom-up). Como me decían en la materia Programación Estructurada, “hay que reducir el problema en problemas más pequeños” (o algo así).
  • Agrupar elementos y funcionalidades similares, a  nivel de archivos y directorios, así como a nivel de código fuente.
  • Si se observa que una funcionalidad o elemento se repite más de una vez, o bien que es son muy parecidos a otra funcionalidad o elemento existente, entonces centralizarlos en un solo lugar. Por ejemplo, en la programación orientada a objetos, si se tienen por ejemplo las clases Profesor y Estudiante con propiedades y métodos similares, lo mejor sería que los elementos comunes los heredaran de una clase padre (Persona, por ejemplo).
  • En el caso de programación orientada a objectos, hacer uso de la herencia, clases abstractas, interfaces, y otros elementos que nos permiten centralizar la funcionalidad e información en clases, y hacer uso extensivo de ellas.
  • Hacer uso de Frameworks, los cuáles brindan funcionalidades comunes a toda aplicación. También incluyen generadores de código fuente, que construyen automáticamente elementos de uso común en base a características específicas. Ejemplo de ello es el Generador de Formularios del Framework para PHP llamado Symfony, que genera formularios web a partir de la definición del modelo de una base de datos.

¿Generadores de código fuente?

En este momento podría surgir la duda de por qué usar un generador de código fuente, si estos podrían generar código repetitivo. Si bien esto es cierto, no se salen del principio de DRY, ya que en realidad el código fuente generado automáticamente ha sido construido a partir de un mismo origen: el generador de código fuente. Esto implica que si se hace uso del mismo generador, este construirá el mismo código fuente en cualquier momento si se proporcionan las mismas condiciones para su generación.

Observaciones finales

El principio DRY nos presenta facilidades y ventajas con respecto a WET, ya que a la larga pueden facilitarnos el trabajo al reducir el tiempo de programación reutilizando elementos y funcionalidades ya existentes. Sin embargo, el llevar un sistema a una estructura DRY puede llevar tiempo de análisis, y muchas veces no será perfecto. Pero a pesar de esta desventaja, considero que vale la pena hacer el intento, ya que a la larga nos facilitará el trabajo a nosotros mismos quienes desarrollamos una aplicación, así como a los colegas que se encargarán de extender nuestro sistema informático en un futuro.

Los invito a escribir sus comentarios y opiniones acerca de este tema.



Publicado originalmente el 16/08/2012, en http://itsouvenirs.wordpress.com/2012/08/16/consejos-de-programacion-1-dont-be-wet-stay-dry/.

WP - Cinnamon 1.3.1 en Fedora 16

En esta ocasión mostraré como instalar Cinnamon en Fedora 16, que es una variante de escritorio desarrollada originalmente para Linux Mint, y basada en Gnome 3 y Mutter como decorador de ventanas. Cabe mencionar que la versión Live de Fedora 16 viene con Gnome 3 como escritorio por defecto, el cual, en lo personal, me parece bastante creativo y un poco más eficiente que las primeras versiones de Unity de Ubuntu.

Para instalar Cinnamon, lo primero que debe hacerse es añadir el repositorio de éste para Fedora, en YUM. Puede hacerse desde la línea de comandos así:

$ su
# curl http://repos.fedorapeople.org/repos/leigh123linux/cinnamon/fedora-cinnamon.repo -o /etc/yum.repos.d/fedora-cinnamon.repo

Luego, para proceder a su instalación, ejecutamos:

# yum install cinnamon

Finalmente, solo basta cerrar nuestra sesión y volver a ingresar, eligiendo ahora a Cinnamon como escritorio. Para ello se da click en el botón sesión, y se selecciona el escritorio a utilizar.

Selección de escritorio Cinnamon durante el inicio de sesión.
Vista del escritorio Cinnamon en Fedora 16.


Publicado originalmente el 27/03/2012, en http://itsouvenirs.wordpress.com/2012/03/27/cinnamon-1-3-1-en-fedora-16/.

martes, 16 de septiembre de 2014

WP - Habilitar tarjeta Broadcom Wireless en Fedora 16

Luego de instalar Fedora 16 en mi computadora, una DELL Inspiron 1525, me encontré con el inconveniente de que la tarjeta de red inalámbrica no funcionaba, debido a que el sistema operativo no incluye ni provee controladores para esta tarjeta de red. Esto se debe a la filosofía de Fedora, de proporcionar solamente software libre, y hasta el momento los controladores que existen para esta tarjeta de red son propietarios.

Sin embargo, existe una alternativa: paquetes kmod o akmod, que son módulos de kernel para controladores. Éstos pueden obtenerse vía internet (conectando la computadora con un cable de red, claro está), desde el repositorio RPMFUSION. La otra opción es descargar los paquetes desde el sitio web http://mirror.liberty.edu/pub/rpmfusion/nonfree/fedora/releases/16/Everything/x86_64/os/

Si se decide utilizar el repositorio RPMFUSION vía Internet, es necesario incluir el repositorio correspondiente en YUM, así:

$ su
# yum localinstall --nogpgcheck http://download1.rpmfusion.org/free/fedora/rpmfusion-free-release-stable.noarch.rpm http://download1.rpmfusion.org/nonfree/fedora/rpmfusion-nonfree-release-stable.noarch.rpm
# yum update

Luego de ello, tenemos la opción de usar paquetes kmod o akmod. Los kmod son paquetes precompilados que sirven como interfaz entre el kernel y los controladores, propios de una versión de kernel específica. Los akmod son paquetes que compilan kmod "al vuelo", al momento de iniciar el sistema operativo, de acuerdo al kernel que se esté utilizando.

Si se desean usar kmod, primeramente debemos obtener la lista de módulos disponibles, de acuerdo a la versión del kernel que se posea:

# yum list kmod-wl-\*

Los módulos poseen en medio de su nombre la versión del kernel a la que corresponden. Si por ejemplo se desea el kmod para el kernel 3.2.9, entonces se debe proceder a instalar el paquete kmod-wl-3.2.9-1.fc16.i686.i686, así:

# yum install kmod-wl-3.2.9-1.fc16.i686.i686

Si, por otra parte, se desea instalar un akmod, procedemos a instalar la versión más reciente, de la siguiente forma:

# yum install akmod-wl

Finalmente (independientemente de si elegió usar kmod o akmod), procedemos a instalar el controlador correspondiente a la tarjeta de red, en su versión más reciente:

# yum install broadcom-wl

Luego reiniciamos la computadora, para que el módulo respectivo sea cargado en el kernel en ejecución, luego de lo cual ya debería funcionar adecuadamente nuestra tarjeta de red Broadcom, detectando las redes disponibles en la zona.

Instalación sin conexión a Internet

El título no es del todo cierto, ya que es necesario descargar los paquetes correspondientes desde el sitio web http://mirror.liberty.edu/pub/rpmfusion/nonfree/fedora/releases/16/Everything/x86_64/os/ Debe buscarse y descargarse el paquete kmod-wl en la versión correspondiente al kernel que se utiliza, o la versión akmod-wl más reciente, según la alternativa. También es necesario descargar la versión más reciente o más apropiada del controlador broadcom-wl. Luego, se proceden a instalar los paquetes con permisos de administrador, y se reinicia la computadora, para activarlos, y poder hacer uso de la tarjeta de red inalámbrica.

Referencias


Enlaces de interés


Publicado originalmente el 10/03/2012, en http://itsouvenirs.wordpress.com/2012/03/10/habilitar-tarjeta-broadcom-en-fedora-16/.

viernes, 12 de septiembre de 2014

Cambiar tiempo de espera para ejecución de comandos en NHibernate vía código

Las consultas ejecutadas con NHibernate tienen un tiempo de espera predeterminado de 30 segundos. Sin embargo puede que este tiempo no sea suficiente para ejecutar algunos comandos o consultas complejas.

Para cambiar el tiempo de espera a nivel global a través de la configuración NHibernate vía código, se puede establecer el valor de la propiedad command_timeout al momento de configurar la fábrica de sesiones, de la siguiente manera:

NHibernate.Cfg.Configuration configuracion;

// Inicialización de configuración de NHibernate
// ...

// Estableciendo nuevo tiempo de espera (como cadena, en segundos)
configuracion.SetProperty(NHibernate.Cfg.Environment.CommandTimeout, "150");

// Creando fábrica de sesiones
ISessionFactory fabricaSesiones = configuracion.BuildSessionFactory();

Con esto se configura la fábrica de sesiones para que cada vez que ejecute comandos sobre la base de datos utilice el tiempo de espera especificado. El tiempo de espera se indica en segundos, ya que de acuerdo a la documentación es el que se asigna por defecto a los IDbCommand generados por NHibernate para las operaciones en la base de datos, y el tiempo de espera para estos se especifica en segundos.

De momento solo lo he probado en NHibernate 3, específicamente la versión 3.3.1.4000, por lo que no estoy seguro si existe en versiones previas, aunque es muy probable.
Con la tecnología de Blogger.