Autor en Google+
Saltar al contenido

Artículos, tutoriales, trucos, curiosidades, reflexiones y links sobre programación web ASP.NET Core, MVC, Blazor, SignalR, Entity Framework, C#, Azure, Javascript... y lo que venga ;)

15 años online

el blog de José M. Aguilar

Inicio El autor Contactar

Artículos, tutoriales, trucos, curiosidades, reflexiones y links sobre programación web
ASP.NET Core, MVC, Blazor, SignalR, Entity Framework, C#, Azure, Javascript...

¡Microsoft MVP!
martes, 5 de septiembre de 2006
Leyendo el blog http://google.dirson.com/index.php sobre noticias de Google en español, llego a una curiosa aplicación que esta compañía ha puesto en marcha, como otras, en fase beta: Google Image Labeler.

Se trata de un juego bastante entretenido, programado con AJAX a tope (como de costumbre en la casa), que está accesible a través de la dirección http://images.google.com/imagelabeler/, aunque de momento sólo en inglés. La mecánica es muy simple: el sistema selecciona al azar un usuario que en ese momento esté conectado, que será nuestro compañero de juego, y a partir de ese momento, irán apareciendo, tanto a él como a nosotros, imágenes que debemos describir sugiriendo etiquetas (labels) que las describirían; cuando alguna de las palabras que enviamos coincide con una de las aportadas por nuestro partner, obtendremos puntos y el sistema pasará a la siguiente imagen. Y así durante 90 segundos.

Esto no pasaría de ser una pequeña curiosidad sin demasiada relevancia, si no fuera por el verdadero objeto del sistema: llenar las bases de datos de información sobre las imágenes, y parece ser que con el único fin de entrenar sus sistemas expertos de reconocimiento automático, los que, según comentan, revolucionarán los motores de búsqueda de imágenes en un plazo relativamente breve.

La idea del etiquetado humano de imágenes no es nueva, ha sido y está siendo utilizada en otros proyectos como el ESP Game, donde a día de hoy se han recogido cerca de 18 millones de etiquetas que son utilizadas en su propio buscador. Sin embargo, esto presenta una importante limitación: la actualización. Cada vez que se registra una nueva imagen es necesario que alguien la etiquete, lo cual no siempre es factible.

Conscientes de este inconveniente, los chicos de Google han debido llegar a la conclusión de que la catalogación de imágenes para facilitar las búsquedas debe ser resuelta en su totalidad de forma automática, es decir, utilizando software. Por ello están adquiriendo compañías especializadas en tratamiento digital de imágenes, haciéndose de aplicaciones existentes y, a veces, desarrollando sus propios sistemas, con objeto de disponer de software capaz de reconocer patrones en imágenes, detectar elementos, textos (no olvidemos el famoso proyecto de OCR en el que también están trabajando), personas u otros objetos en imágenes y siempre sin intervención humana.

La originalidad está en utilizar las palabras obtenidas con el juego simplemente para hacer baterías de pruebas automatizadas que les permitan afinar este software. Genial, ¿no?

Habrá quien se pregunte que cómo de fiables pueden ser las etiquetas teniendo en cuenta la diversidad y anonimato de los jugadores/colaboradores. Y, sin duda, cabe cierto margen de error, aunque pensándolo un poco, el juego está ideado para minimizar estos problemas: la elección aleatoria del compañero o el puntuar (y almacenar) las palabras coincidentes son muestras de ello.

Estos contenidos se publican bajo una licencia de Creative Commons Licencia Reconocimiento-No comercial-Compartir bajo la misma licencia 3.0 España de Creative Commons

viernes, 25 de agosto de 2006

Joomla es uno de los CMS open source más usados en la actualidad debido a su sencillez y potencia para la creación de portales, sitios web dinámicos o aplicaciones basadas en Internet. En este post iré recogiendo "en tiempo real" los pasos que voy siguiendo para montar en un servidor un sitio basado en este gestor, de forma que pueda servir como guía para posteriores instalaciones.

Partimos de una distribución basada en Debian (Ubuntu), con Apache 2, PHP y MySQL instalados y funcionando de forma correcta.

25 de Agosto de 2006.
Diario de una instalación de Joomla.

16:39 - Inicio de actividades

Sin duda, lo primero que hay que hacer es documentarse. Pienso que no vendría mal una visita por el sitio web oficial de Joomla para ir tomando contacto. Un poco de lectura del típico qué es, para qué sirve, modelos de licencia, quiénes lo soportan, aunque la verdad es que me aburro pronto y prefiero pasar a la demo on-line donde se puede probar un portal entrando como usuario administrador (admin/admin). También es posible acceder a la parametrización y configuración de la plataforma añadiendo a la URL la ruta /administrator o pulsando sobre la correspondiente opción del menú.

En esta demo, salvo algunas limitaciones lógicas por motivos de seguridad, se permite tocar todo, y permite obtener una buena visión del potencial y capacidades de la herramienta.

17:18 - Comienzo de la instalación

Después del paseo anterior he decidido que, definitivamente, me lo voy a instalar. Google, que todo lo sabe, me dijo hace un rato que existe una comunidad hispana de Joomla! y allí he visto un enlace para descargar una versión de la plataforma localizada en español. Allá voy.

Se trata de un archivo .zip de poco menos de tres de megas, por lo que la descarga es prácticamente instantánea. Al abrir el archivo con FileRoller (el gestor de archivos comprimidos de Gnome) veo que se trata de una carpeta principal con archivos .php y varios subdirectorios. Uno de ellos, INSTALL.php me hace pensar que la instalación se realizará desde entorno web, una técnica muy de moda actualmente.

El servidor apache, según su instalación por defecto, asume que el directorio raíz del sitio http://localhost se en cuentra en la ruta física /var/www. No tengo intención de modificar la configuración de Apache, así que decido que mi portal Joomla se encontrará en un subdirectorio del raíz, por ejemplo, http://localhost/joomla. Debo crear, pues, este directorio dentro de la carpeta /var/www citada anteriormente.

Descomprimo los ficheros sobre mi flamante nueva carpeta con FileRoller (aunque también podría haberlo hecho desde un shell, ejecutando unzip [ruta del archivo .zip] desde el directorio destino). Justo después de terminar, ya es posible acceder a la URL local elegida para comenzar el proceso de instalación.

17:32 - Asistente de instalación, comprobaciones iniciales

La pantalla que aparece al acceder por primera vez con el navegador (recordemos: http://locahost/joomla) es el resultado de un análisis automático de los prerequisitos para la instalación del sistema, divididos en tres grupos:

  • Pre-instalación, que comprueba que la versión de PHP es correcta y dispone de soporte para ciertas tecnologías utilizadas, así como los permisos de escritura de datos de sesión y el archivo de configuración (configuration.php). En mi caso el archivo de configuración no puede ser escrito, lo cual debe ser un problema, dado el color rojo chillón elegido para informar de ello, aunque también indica que todavía la instalación puede continuar; sigamos, pues.
  • Ajustes recomendados, que hace referencia a la configuración de PHP. Como me aparece todo correcto, no le presto más atención.
  • Permisos de carpetas, donde tengo un pleno. Todo rojo. El instalador, además, indica que es necesario modificar los permisos de estas carpetas para que todo funcione bien, así que desde un shell hago un chmod 777 [carpeta] para cada una de ellas, con lo que otorgo permisos generales de lectura, escritura y ejecución. Uff, supongo que un experto en seguridad premiaría con algunas collejas esta falta de celo, pero bueno, qué diantres, estoy en mi casa (servidor) y hago lo que quiero ;-). Para los perezosos, ahí van los comandos empleados; he preferido hacerlo uno a uno para evitar una llamada a chmod de forma recursiva e indiscriminada.

    chmod 777 administrator/backups/
    chmod 777 administrator/components/
    chmod 777 administrator/modules/
    chmod 777 administrator/templates/
    chmod 777 cache/
    chmod 777 components/
    chmod 777 images/
    chmod 777 images/banners/
    chmod 777 images/stories/
    chmod 777 language/
    chmod 777 mambots/
    chmod 777 mambots/content/
    chmod 777 mambots/editors
    chmod 777 mambots/editors-xtd/
    chmod 777 mambots/search/
    chmod 777 mambots/system/
    chmod 777 media
    chmod 777 modules
    chmod 777 templates

Una pulsación sobre el botón "comprobar de nuevo", situado en la zona superior de la página, hace que se refresque el resultado del análisis, y se puede comprobar que todo está ya correcto, salvo el problema (obviable, de momento) del primer bloque de comprobaciones.

17:48 - Asistente de instalación, Licencia

Pulsando "Siguiente" pasamos a una página cuyo único objetivo es mostrar el texto de licencia GNU/GPL. Vaya, interesante es un rato, pero en estos momentos prefiero seguir instalando el software. Este tipo de contenidos, que estamos acostumbrados a encontrar cada vez que montamos un nuevo software, libre o propietario, son bastante largos y densos, y supongo que pocos son los que se paran ante ellos. En cualquier caso, seguro que todos conocemos el modelo GPL y estamos completamente de acuerdo con él, así que continuamos.

17:51 - Asistente de instalación, Paso 1 (MySQL)

Bueno, pues se va poniendo cada vez más interesante... Ha llegado el momento de indicar dónde y cómo se accede al servidor MySQL sobre el que recaerá la responsabilidad de almacenamiento de datos.

En el formulario que tenemos que rellear, dado que tenemos nuestra propia copia de MySQL en la máquina local, indicaremos que el servidor es "localhost". El nombre de usuario y contraseña no los he cambiado desde la instalación del motor, por lo que será "root" con clave en blanco (nueva colleja). Como nombre de la base de datos elegimos Joomla, por ser originales, y el resto de datos los dejamos como están.

Pulsando "siguiente" y aceptando una ventanilla de confirmación, el sistema creará la estructura sobre MySQL y mostrará el siguiente paso del asistente.

17:55 - Asistente de instalación, Paso 2 (Nombre)

Este es de los fáciles. Pongamos un nombre a nuestro sitio web... ummm... esto es siempre lo más difícil... además, seguro que todos nos preguntamos ¿se podrá cambiar más adelante?... estoooo.... venga, adjudicado, creatividad al poder, "Pruebas Joomla". :-D

17:58 - Asistente de instalación, Paso 3, (URL, administrador y otros)

Es momento de confirmar al sistema lo que él ya sabe, la URL de acceso y la ruta física de los archivos Joomla. Los dejamos tal y como están, introducimos el email y contraseña del administrador y seguimos adelante.

17:58 - Asistente de instalación, Paso 4 (Fin)

¡Parece que hemos acabado! El sistema nos felicita por la gran instalación realizada, nos recuerda que el usuario de acceso será "admin", y la contraseña la elegida en el paso anterior, y nos pide que realicemos las siguientes operaciones:

  1. Eliminar de forma manual el directorio de instalación. Como supongo que se refiere a la carpeta /var/www/joomla/installation, así lo hago.
  2. Crear un archivo llamado "configuration.php" e introduzca en él el texto que nos suministra en un cuadro. Ahora entiendo lo que significa la alerta del paso de pre-instalación. Cojo mi editor favorito, pego el texto indicado, y lo salvo en la carpeta raíz de Joomla.

Voilá. Esto está listo. En la parte superior hay dos enlaces: web y administración. El primero de ellos nos llevará a la parte pública del portal, mientras que el segundo nos permitirá acceder a la administración y configuración. Así, podremos ver que la instalación ha creado por nosotros una web con contenidos de ejemplo, que nos ayudará a hacernos con el entorno más rápidamente.

A partir de aquí, queda pelear con el área de administración y las plantillas (templates) hasta tener la versión definitiva de lo que será nuestro sitio web basado en este magnífico gestor de contenidos.

Feliz Joomling.

Estos contenidos se publican bajo una licencia de Creative Commons Licencia Reconocimiento-No comercial-Compartir bajo la misma licencia 3.0 España de Creative Commons

domingo, 20 de agosto de 2006
¡Bueno, pues ya estamos de vuelta! Salvo la obligatoria depresión debida al síndrome post-vacacional con el que probablemente nos bombardearán en los telediarios a partir de esta misma semana, sólo me quedan de estas vacaciones buenos recuerdos y la agridulce sensación de que han acabado las que, sin duda, han sido las mejores de mi vida.

Pero en fin, como es sabido que todo lo bueno acaba, lo mejor es tomarlo con filosofía y prepararnos para un año que seguro será duro, pero traerá alegrías personales y profesionales. Las pilas están cargadas, y preparadas para ello.

Nos vemos por aquí.

Estos contenidos se publican bajo una licencia de Creative Commons Licencia Reconocimiento-No comercial-Compartir bajo la misma licencia 3.0 España de Creative Commons

jueves, 27 de julio de 2006
Hace como mes y medio, a primeros de Junio, fue lanzada la última versión de Ubuntu, la 6.06 LTS (Dapper Drake). Desde entonces he esperado impaciente la oportunidad para instalarlo en una máquina y echarlo a correr, y hoy por fin he tenido ocasión de hacerlo. La máquina en cuestión es un portátil IBM ThinkPad con 512Mb de memoria RAM, lector de DVD, tarjeta WiFi PCMCIA (marca SMC), y un corazón Pentium III.

En primer lugar he descargado la imagen ISO desde la dirección http://releases.ubuntu.com/6.06/ubuntu-6.06-desktop-i386.iso; en mi primer intento lo descargué con eMule, aunque simplemente pude obtener una copia defectuosa que me llevó a desperdiciar tiempo, amén de algún CD tostado en vano. El único problema que trae de serie esta imagen es que el software que instala (p.e., OpenOffice) es inicialmente en inglés, aunque el sistema operativo venga en la lengua de Cervantes; supongo que en breve aparecerán distribuciones alternativas, donde todos los paquetes vendrán ya en nuestro idioma, pero mientras debemos instalar a posteriori las versiones localizadas de los mismos.

Una vez con la imagen ISO correcta grabada a fuego, ha sido introducirla en el lector del portátil, arrancar seleccionándolo como unidad inicial, y listo, todo sobre la seda. En pocos segundos ha aparecido un menú con varias opciones, inicialmente en inglés, aunque es posible cambiar esto pulsando la tecla F2 y cambiando a español. Seleccionando la opción "Iniciar Ubuntu" y esperando unos tres minutos, se cargará el sistema operativo, como es habitual montado sobre un disco RAM, apareciendo el escritorio Gnome.

Esta versión "live" ha sabido detectar perfectamente la placa madre, los dispositivos integrados (como el puerto de infrarrojos, la tarjeta de red Ethernet, o la de sonido), la tarjeta de red inalámbrica y hasta una llave USB que tenía introducida accidentalmente en uno de los puertos USB del equipo. A nivel de detección de hardware, simplemente perfecto. Ni un detalle a echarle en cara.

Para iniciar la instalación al disco duro, simplemente hay que pulsar un acceso directo que encontraremos en el escritorio, que iniciará el asistente. Tras algunas preguntas simples, como el idioma, la configuración de teclado y la zona horaria, y otras más complejas, como la distribución de particiones del disco, se inicia la instalación, propiamente dicha, del sistema. Ojo con el tema de las particiones, sobre todo si el ordenador tiene otro sistema operativo instalado, pues puede dar lugar a una pérdida irrecuperable de la información almacenada.

Unos quince minutos más tarde, y tras el necesario reinicio tenemos un Ubuntu en su punto, listo para ser degustado. Y de guarnición, decenas de aplicaciones de uso cotidiano, que harán que podamos podemos a trabajar de inmediato (navegación por internet, correo electrónico, mensajería instantánea, procesador de textos, hoja de cálculo, creador de presentaciones, editor gráfico, visores multimedia, grabadores de cd, juegos...).

¡Muy bien, sí señor! Si seguimos así, sin duda el software libre puede ser una alternativa al omnipotente y ubicuo (en sus respectivas primeras acepciones del diccionario de la Real Academia) Windows.

Y por cierto, (este párrafo ya lo estoy escribiendo desde mi nuevo Ubuntu :-)), es una maravilla, aunque esto esté ya inventado desde hace tiempo, ver cómo se actualiza muy frecuentemente de forma totalmente automática. De hecho, estas actualizaciones están aseguradas para esta versión durante tres y cinco años para las versiones desktop y servidor, respectivamente, de ahí las siglas LTS (Long Time Support) del nombre del producto.

Para finalizar, simplemente decir que hoy comienzo mis (esperadas) vacaciones. Estaré unos días en la costa de Málaga, otros en Huelva y algunos también me quedaré en casa. Eso sí, siempre con mi portátil y mi nuevo sistema operativo. A ver qué tal.

Felices vacaciones.

Estos contenidos se publican bajo una licencia de Creative Commons Licencia Reconocimiento-No comercial-Compartir bajo la misma licencia 3.0 España de Creative Commons

miércoles, 12 de julio de 2006
El último día vimos etiquetas relacionadas con enlaces, listas, incrustación de objetos, controles de formularios e incluso tags destinados a modificar la presentación de las páginas.

En esta última entrega completaremos la referencia completa de etiquetas XHTML.

Creación de tablas

A diferencia de lo que ocurre con HTML, en XHTML es una mala idea utilizar tablas para maquetar presentaciones. No olvidemos que en este punto nos encontramos describiendo el contenido, no cómo debe visualizarse en pantalla. De hecho, deberíamos acostumbrarnos a pensar en las tablas como una forma de mostrar exclusivamente datos tabulares, como puede ser la tabla de clasificación de la liga de fútbol, o un listado de movimientos bancarios.

Para ello, XHTML nos brinda los siguientes tags, de los cuales algunos son ya bastante habituales:


  • caption permite definir el título de la tabla, un pequeño texto sobre su contenido.
  • col define atributos de una columna contenida en un grupo creado mediante el tag <colgroup>.
  • colgroup está pensado para definir grupos de columnas sobre los que se podrán aplicar atributos de forma conjunta. En su interior deberá existir un elemento <col> por cada columna que lo componga.
  • table, que indica el comienzo y fin de la tabla.
  • tbody, permite marcar el cuerpo de la tabla, es decir, indicar dónde se encuentran los datos de sus filas.
  • td es el tag clásico de definición de una celda de la tabla.
  • tfoot como en el caso de tbody, indica la sección del pie de la tabla.
  • th es como td, pero se utiliza en las celdas que son encabezado de columnas.
  • thead contiene el encabezado de la tabla.
  • tr permite señalar el comienzo y fin de cada fila. En su interior habrá tantos <td> como columnas tenga la tabla.

Inserción de imágenes y mapas de imagen

  • img permite la inserción de imágenes, como en HTML tradicional. Ojo con el cierre del tag, que es necesario como en todo documento XML.
  • map y area permiten, respectivamente, la inserción de imágenes mapeadas, y la definición de áreas sensibles.

Metainformación

En algún otro post he comentado que la metainformación se define como "información sobre la información". En el contexto que nos ocupa, se trata de la información introducida en la página web que describe el contenido que podremos encontrar en ésta. Por ejemplo, esta información es extremadamente útil para las técnicas SEO, pues permiten que los buscadores conozcan de qué trata el contenido, las palabras clave, el autor, etc. El único tag disponible es bien conocido por todos:

  • meta, define información sobre los contenidos de la página.

Scripting

Con XHTML también es posible utilizar scripts. De hecho, es un entorno perfecto para el desarrollo de aplicaciones AJAX. Encontramos en esta categoría dos etiquetas:

  • script que permite alojar código de script en el interior de una página XHTML.
  • noscript se utiliza para definir qué contenidos se utilizarán o visualizarán cuando el dispositivo cliente no disponga de capacidades de ejecución de estos elementos.

Hojas de estilo en cascada

  • style permite definir en el encabezado del documento (<head>) las pautas de estilo que serán utilizadas para representar visualmente el contenido de la página.

Relación con otros documentos

  • link relaciona el documento XHTML actual con otros. Es habitual utilizarlo para cargar hojas de estilo externas de la siguiente forma:

<link rel="stylesheet" type="text/css" href="theme.css" />

Base del documento

  • base indica al cliente la dirección base que deberá ser aplicada para todos los enlaces relativos del documento. Y cuando digo todos, digo todos. Ojo a esto, que si se cambia la base de una página XHTML es posible que haya que revisar todas las rutas que se hayan utilizado (hojas de estilo, links, scripts, imágenes...)

Bueno, con esto ya hay suficiente para ponerse a trabajar. Seguiremos informando.

Estos contenidos se publican bajo una licencia de Creative Commons Licencia Reconocimiento-No comercial-Compartir bajo la misma licencia 3.0 España de Creative Commons

miércoles, 5 de julio de 2006
Hace unos días publiqué una primera lista de tags permitidos en XHTML, recogidos en dos grupos; el primero de ellos incluía las etiquetas que permitían estructurar un documento según el estándar, y añadir algo de información adicional, mientras que el segundo facilitaba el enriquecimiento de los contenidos mediante la inclusión de marcas con cierto significado semántico.

Hoy vamos a continuar en esta línea.

Enlaces hipertexto

  • a, el tag de toda la vida, que ha sufrido pocas variaciones, aparte del consabido cierre obligatorio de la etiqueta en todos los casos, hasta en el establecimiento de anclas.

Composición de listas

  • dl indica una lista de definiciones. En su interior habrá un par dt y dd por cada término a definir, el primero para el término y el segundo para su definición.
  • dd indica la definición del término apuntado por el <dt> correspondiente.
  • dt, que refleja el término a ser definido en el siguiente <dt>
  • ol (ordered list) permite especificar que su contenido estará compuesto por líneas (creadas mediante el tag <li>) que serán numeradas y ordenadas conforme se vayan añadiendo a la lista.
  • ul se usa para incluir listas desordenadas. Una lista desordenada es una serie de elementos consecutivos entre los que no se establece ningún tipo de relación de dependencia en función de su posición.
  • li, que se utiliza para indicar cada elemento de las listas, sean ordenadas o desordenadas.

Inclusión de objetos

  • object permite incluir objetos o plugins en las páginas, como pueden ser applets o animaciones Flash.
  • param, se utiliza para especificar los parámetros a enviar al objeto.

Etiquetas de presentación

Hace ya algunos posts, hacía hincapié en la absoluta separación de contenidos y visualización en una página XHTML. Aunque esto es cierto, existen una serie de tags que permiten modificar ligeramente la presentación desde XHTML sin tener que recurrir a CSS:

  • b, como siempre, para poner en negrilla.
  • big, hace que el texto sea presentado en un tamaño de fuente mayor que el utilizado en ese momento.
  • hr, que permite incluir una separación vertical en el documento, normalmente con una línea horizontal de lado a lado, aunque este comportamiento puede modificarse mediante las hojas de estilo.
  • i, para que el contenido sea formateado en itálica o cursiva.
  • small, reduce el tamaño de la fuente utilizada para representar su contenido.
  • sub, permite incluir subíndices.
  • sup, lo mismo, pero con superíndices.
  • tt fuerza la utilización de caracteres en modo teletipo, con caracteres de ancho fijo.

Etiquetas de edición

Estos tags permiten enriquecer el contenido con marcas relativas a la supresión o inserción de información. Por ejemplo, serían útiles para indicar, tras una revisión, qué partes del texto han sido eliminadas o cuáles han sido insertadas por el revisor. Las etiquetas son las siguientes:

  • del, que marca el texto eliminado o a eliminar.
  • ins, que indica el texto nuevo.

Texto bidireccional

La inclusión de bidireccionalidad hace posible que una página pueda ser visualizada correctamente por personas cuya escritura se realiza en un sentido distinto a nuestro sistema habitual (por ejemplo, en países árabes, se lee de derecha a izquierda).

  • bdo permite indicar el comienzo y finalización de un bloque de texto que podrá ser representado usando una direccionalidad distinta a la establecida en el momento.

Por ejemplo, podemos ver cómo queda un famoso palíndromo de Julio Cortázar "Átale, demoníaco Caín, o me delata" al presentarlo modificando la direccionalidad:

"Átale, demoníaco Caín, o me delata"

¡Pues era verdad esto de los palíndromos, se lee igual al derecho y al revés! El código fuente para conseguir esto ha sido:

<bdo dir="rtl"><em>"Átale, demoníaco Caín, o me delata"</em></bdo>

Formularios

  • button, que permite incluir un botón.
  • fieldset permite agrupar un conjunto de campos de un formulario bajo un título común, especificado mediante el tag <legend>.
  • form, es el elemento raíz de todo formulario.
  • input permite incluir distintos tipos de control de entrada datos. Cuidado con los cierres, que no estamos acostumbrados a hacerlo aquí.
  • label es útil para asociar descripciones textuales a cada control de entrada.
  • legend, se utiliza para dar un título a un fieldset.
  • select permite crear un control de selección basado en desplegable o lista de selección.
  • option indica cada elemento disponible en un control de tipo select, descrito anteriormente.
  • optgroup, facilita la agrupación de elementos <option> para crear efectos como el siguiente:
  • textarea, que, como el de toda la vida, permite la entrada de textos multilínea.

El próximo día continuaremos con los elementos de tabla, imágenes y algunas cosillas más.

Estos contenidos se publican bajo una licencia de Creative Commons Licencia Reconocimiento-No comercial-Compartir bajo la misma licencia 3.0 España de Creative Commons