Image
Calcular contenedor de texto segun lineas
Calcular contenedor de texto segun lineas

Tutorial para calcular contenedor de texto segun lineas. Hoy explicaremos cómo calcular el tamaño de un contenedor que contiene texto, y sólo queremos que se visualicen unas líneas determinadas.

 

Image
Calcular contenedor de texto segun lineas

En este caso, tenemos varias tarjetas del mismo estilo, y quedaría mal que en cada una aparecieran más o menos líneas, por lo que vamos a hacer lo siguiente:

Inspeccionamos el párrafo, y en el inspector (el de chrome por ejemplo) buscamos qué tamaño de letra tiene, en nuestro caso vemos que tiene un 0.85rem (13.6 píxeles).

Después buscamos en el inspector la propiedad line-height, para los que no lo sepan consiste en establecer la altura de cada línea que forma el contenido de texto de un elemento, por lo que se emplea para controlar el interlineado del texto.

Nuestro párrafo tiene un line-height de 24 píxeles.

Image
Calcular contenedor de texto segun lineas

 

Image
Calcular contenedor de texto segun lineas

Una vez que tenemos el tamaño de letra y el line-height, los multiplicamos entre ellos y así averiguaremos el alto (height) que debe tener nuestro contenedor.

0.85 x 24=20.4 píxeles

Este sería el cálculo para una sola línea, pero en este caso queremos que nos aparezcan dos, por lo tanto multiplicamos por dos nuestro resultado:

20.4 x 2=40.8 píxeles

Hay que tener en cuenta que debemos sumar si el contenedor tuviera algún borde, padding o algo para que el cálculo sea lo más exacto posible, en nuestro caso no tenemos nada así que lo dejaremos así.

Image
Calcular contenedor de texto segun lineas

Vemos que seguimos visualizando más de dos líneas, por lo que añadiremos a nuestro contenedor la propiedad overflow: hidden, así, lo que sobrepase los píxeles que hemos marcado de alto ya no lo veremos y quedará oculto.

Image
Calcular contenedor de texto segun lineas

Ya tendríamos nuestro contenedor a la medida necesaria y todas las tarjetas ocuparían lo mismo.

Image
Calcular contenedor de texto segun lineas

Y esto ha sido el tutorial para calcular el tamaño de un contenedor de texto segun el numero de lineas

Si necesitas más ayuda, visita este enlace o contacta con un desarrollador.

Image
portada pageruler
Herramientas indispensables para diseño web Page ruler

Herramientas indispensables para diseño web Page ruler, tu regla para medir pixeles en la pantalla del ordenador

Herramientas indispensables para diseño web Page ruler. Muchas veces queremos saber cuanto mide un elemento de una pagina web, proyecto etc. Como por ejemplo una imagen

Muchas extensiones de navegador te permiten medir en pantalla mediante una sencilla regla y averiguar rápidamente cuanto mide en píxeles un elemento web. La extensión más utilizada se llama Pageruler que crea una regla para obtener dimensiones y posicionamiento de píxeles, y además mide elementos en cualquier página web.

¿Qué es Page ruler?


Page Ruler es una extensión gratuita para navegadores  web Firefox y Chrome que muestra en pixeles la medida de los elementos medidos.

Características


•    Dibuja una regla en cualquier página y permite ver el ancho, la altura y la posición superior, inferior, izquierda y derecha.
•    Arrastra los bordes de la regla para cambiar su tamaño.
•    Usa las teclas de flecha para mover y cambiar el tamaño de la regla.
•    Muestra guías que se extienden desde los bordes de la regla.
•    Actualiza manualmente el tamaño y la posición de la regla desde la barra de herramientas para realizar cambios de precisión.
•    Habilita el “Modo de elemento” para delinear elementos en la página mientras mueves el ratón sobre ellos.
•    Navega a través de elementos de padres, hijos y hermanos de cualquier elemento medido.


Cómo utilizar la extensión Page ruler

Empezamos instalando la extensión en tu navegador y después haz clic en el icono que está al lado de la barra de direcciones.

Image
Herramientas indispensables para diseño web Page ruler

 
A continuación  puedes usar la medición libre arrastrando el ratón por la pantalla.

También puedes utilizar el modo de detección del elemento en la parte superior izquierda para que detecte automáticamente cuánto mide, por ejemplo un campo de registro de un formulario.

Image
Herramientas indispensables para diseño web Page ruler

Y estas son las caracteristicas y virtudes de Page ruler como herramienta indispensable para el diseño web Drupal

Si necesitas más ayuda, visita este enlace o contacta con un desarrollador.

Image
Eliminar cabecera y añadir un before
Eliminar cabecera y añadir un before

Eliminar cabecera y añadir un before, me ha parecido interesante compartir esto, con un ejemplo práctico, vamos a ver como en el formulario de inscripción a una oferta de trabajo de una web, nos encontramos con que en la parte superior aparece una información que al cliente no le interesa, en este caso concreto un texto, pero podria aplicarse tambien en el caso de una imagen o un simbolo.

Image
Eliminar cabecera y añadir un before

Para ello, desde el navegador inspeccionamos el texto con el botón derecho del ratón, y le añadimos el comando display:none.

Este comando hace que el texto se oculte, y además hace también que el espacio dónde estaba disminuya.

Image
Eliminar cabecera y añadir un before

Una vez hecho ésto, volvemos a inspeccionar la zona que nos ha quedado (de la misma manera que antes, clic derecho - inspeccionar en el navegador), y le añadimos al div un padding 0.

Por último, queremos añadir una "x" más grande, ya que la actual es muy pequeña y puede pasar desapercibida, para ello, a la que tenemos actualmente, le ponemos un display none (así la eliminamos) y después añadimos la que el cliente nos requiere colocándole un before al botón.

Image
Eliminar cabecera y añadir un before
Image
Eliminar cabecera y añadir un before
Image
Eliminar cabecera y añadir un before

Si os fijais en el codigo mostrado arriba, vereis que también hemos posicionado nuestro before para que quede en uno de los laterales.

Image
Eliminar cabecera y añadir un before

De esta manera hemos conseguido ocultar el texto que no queriamos mostrar a requirimiento de cliente y cambiar el aspa de cierre que existia por una con mejor visualizacion y posicionada en su lugar natural.

Y esto ha sido el tutorial de como eliminar cabecera y añadir un before en Drupal

Si necesitas más ayuda, visita este enlace o contacta con un desarrollador.

Image
whatfont
Herramientas indispensables para diseño web WhatFont

Herramientas indispensables para diseño web WhatFont

Herramientas indispensables para diseño web WhatFont, la forma más fácil de identificar fuentes en páginas web.

Cuantas veces has querido saber que fuente esta utilizando una pagina web, una publicación, un post. Que tamaño de letra tiene un encabezado. Que grueso de letra tiene un título. WhatFont es una extensión de Chrome que nos ayuda con esta función de una forma muy rápida y sencilla.

Image
Herramientas indispensables para diseño web WhatFont

Tan solo con un clic nos proporcionara toda la información que necesitamos sobre esa fuente.

Primero nos muestra de forma abreviada el nombre de la fuente y su grosor en la primera línea de la ventana informativa. A continuación, nos mostrara la familia completa de la fuente, el estilo, el grosor, el tamaño en pixeles, la altura de la línea en pixeles, el color en código hexadecimal y un ejemplo de todas las letras en mayúsculas y minúsculas de la misma.

 

Image
Herramientas indispensables para diseño web WhatFont

Puedes darle clic a otra fuente y abrirá otro pequeño pop-up con la información de esta ultima sin perder el pop-up de la fuente anterior. Como puedes comprobar es sencillísimo conocer las fuentes que utiliza una pagina web utilizando la extensión para Chrome WhatFont.


Existen muchas otras extensiones similares, Firebug y Webkit Inspector son bastante fáciles de usar para los desarrolladores. Sin embargo, para otros, esto no debería ser necesario.. Además, si conoces CSS no te hará falta WhatFont. Pero incluso en este caso te ayudara a ahorrar tiempo en tus proyectos.

Es así de simple y elegante.

Para usar whatfont es tan sencillo como buscar la aplicación en las extensiones para Chrome en la barra de tareas de tu buscador, añadirla a Chrome y fijarla en la barra de extensiones.
También puedes pulsar aquí para ir directamente a la ventada de descarga.

Y estas son las caracteristicas y virtudes de WhatFont como herramienta indispensable para el diseño web Drupal

Si necesitas más ayuda, visita este enlace o contacta con un desarrollador.

Image
Composer, uso y aplicación de este proceso en Drupal
Composer, uso y aplicación de este proceso en Drupal

Este proceso ha sido y es muy habitual en muchos casos pero un gestor de dependencias nos facilita mucho esta tarea y además soluciona un problema muy común y es el de la gestión de versiones, ya que si lo hacemos manualmente, tenemos que periódicamente revisar que ese software o librerías que nos descargamos, no haya tenido una actualización, porque en tal caso, tendríamos que realizar el proceso manualmente. Composer nos facilita la vida mediante un proceso que simplifica estas tareas.

Lo primero que debemos tener es instalado el Composer en nuestro sistema, y eso requiere un proceso que depende del sistema sobre el que deseemos instalarlo, si es en Windows, en Linux, Mac, etc. Dejo la url desde donde podrás seguir los pasos fácilmente. https://getcomposer.org/doc/00-intro.md

Una vez instalado el programa, abre un terminal y ejecuta composer --version o simplemente composer para verificar que te responde. Si lo has instalado de modo global, puedes probarlo desde cualquier parte del sistema.

Para poder trabajar con composer en nuestro proyecto, nos dirigimos a la carpeta en que lo tenemos, y podemos crear nuestro entorno Composer automáticamente o manualmente.

De modo automático, ejecutamos el comando composer init. Lo primero que nos pedirá es que introduzcamos el nombre del proyecto, el cual se compone de vendor u organización, seguido una barra, y a continuación el nombre del proyecto. Por ejemplo micomposer/nuevaprueba.

Nos pedirá una descripción.

Image
Welcome to the composer config generator

A continuación nos pedirá que introduzcamos una descripción.

Image
Description

Nos pedirá el autor.

Image
Author

Nos pedirá algo un poco extraño, que es la estabilidad mínima, en este caso si estamos trabajando en modo desarrollo introducimos dev para que nos descargue versiones de desarrollo en las dependencias. Si pulsamos enter directamente nos bajará sólo las versiones estables.

Image
Minimum Stability

A continuación el tipo, en nuestro caso va a ser un proyecto.

Image
Package Type

En el tipo de licencia podemos poner MIT que es la licencia más usada en open source. Si no fuera open source pondríamos propietary.

Image
License

En este punto podemos ya empezar a incluir dependencies de manera interactiva. Nos pregunta si vamos a necesitar alguna y para ello enter en yes.

Image
Dependencies

Nos pedirá que introduzcamos un paquete y como ejemplo introducimos ckeditor. Puede salirnos un conjunto de opciones. Pulsamos el número correspondiente a la opción de paquete ckeditor que queramos instalar como dependencia.

Image
Search package

Nos permitirá indicar una versión específica pero si no queremos indicar una y que se instale la última pulsamos enter.

Image
Version

Nos indicará la versión que se va a instalar, en este caso la dev-master y nos pedirá si queremos añadir otra dependencia.

Image
Dev-master version

Como no voy a instalar más dependencias, pulso enter, y nos preguntará que vamos a necesitar alguna dependencia específica para el desarrollo. Como no la vamos a necesitar escribo no y pulsamos enter.

Image
require-dev

Nos preguntará si queremos aplicar la estandarización PSR-4 de clases, en nuestro caso le vamos a decir que no.

Image
PSR-4

Me sale el resumen para confirmar del proyecto Composer pulsamos directamente enter para confirmar.

Image
Resumen

Nos pedirá si queremos intalar las dependencias indicadas en ese momento y le decimos que sí.

Image
Instalación de dependencias

De este modo ya tendríamos configurado Composer para gestionar nuestras dependencias.

Los componentes que Composer nos puede gestionar se encuentran en la página https://packagist.org/, en ella podemos realizar una búsqueda y encontrar una enorme cantidad de librerías y dependencias.

Podemos crear la configuración de nuestro proyecto Composer manualmente del siguiente modo.

Para poder gestionar composer necesita un fichero llamado composer.json, en cual introducimos los paquetes que deseamos que Composer nos gestione. El fichero tiene que estar escrito en json por lo que al editarlo, lo primero que tenemos que hacer es abrir y cerrar llaves.

En la primera parte introducimos un conjunto de valores que son opcionales y que se introducen en estructura campo-valor, de la siguiente manera.

{

  “name”: “micomposer/prueba-composer”

}

La primera parte del nombre, antes de la barra es el vendor y a continuación el nombre del proyecto.

El resto de datos opcionales es muy amplio y puede comprender, no solo el nombre, sino la versión, el tipo , la licencia, la descripción, etc. No obstante, el Composer necesita el campo require, que es el que guarda las dependencias que nosotros le digamos. Es un objeto que guarda todas las dependencias en modo clave valor.

{

  “name”: “micomposer/prueba-composer”,

  “require”: {

   

  }

}

Cuando entramos en alguno de los proyectos en la web packagist, nos indicará como tenemos que ponerlos. Por ejemplo:

Image
Packagist

Kint es una librería que nos permite debuguear o mostrar las variables que tengamos en nuestro programa de manera más amigable. Drupal lo suele utilizar con el módulo Devel, pero ese es otro tema. Si pulsamos la primera opción “kint-php/kint”, veremos la siguiente pantalla https://packagist.org/packages/kint-php/kint

Veremos las distintas versiones y observaremos que lo que tenemos que poner es la clave valor, la primera el nombre kint-php/kint, y a continuación la versión, separado por dos puntos y entre comillas como vemos a continuación.

{

  “name”: “micomposer/prueba-composer”,

  “require”: {

    “kint-php/kint”: “dev-master”,

  }

}

La versión requiere conocer las opciones ya que podemos controlar qué versiones queremos instalar como comodines y signos.

Si ponemos, por ejemplo la versión “5.2.*”, estaremos indicando a Composer que nos instale cualquier versión superior a 5.2 e inferior a 5.3. si ponemos una versión sin comodines le estaremos indicando que nos instale esa versión en particular y ninguna otra.

Si queremos que se instale una versión igual o superior utilizaremos el sistema >=5.2.

Podemos introducir un intervalo de versiones como 5.2 - 6.8, que es equivalente a >=5.2 <6.8.

Puedes encontrar todas las opciones en la página https://getcomposer.org/doc/articles/versions.md

En nuestro caso vamos a utilizar la versión última indicada en la página que es la dev-master que corresponde a la última rama de desarrollo.

Algo importante a tener en cuenta a la hora de generar el fichero es que tiene que estar codificado en UT8 a secas.

Guardamos el fichero y abrimos un terminal. Nos dirigimos a la carpeta donde hemos creado el composer.json y ejecutamos el comando composer install.

Image
Composer install

Observaremos que nos ha creado una carpeta vendor en la que introduce las dependencias.

Image
Dependencias

Vemos que ha instalado la carpeta kint-php con la versión que le hemos indicado, y una carpeta composer con las librerías que necesita el programa.

También podemos ver el fichero autoload.php que contiene código para la carga automática de todas las librerías que gestionemos con composer.

En nuestro index.php cargamos el autoload con require y metemos un array o variable en la función d().

<html>

<head></head>

<body>

<?php

. require “vendor/autoload.php”;

$miarray = [‘María’, ‘Pedro’, 43, TRUE, 786,6];

d($miarray);

?>

</body>

</html>

El resultado es el que sigue:

Image
Array

La librería nos facilita el trabajo de visualizar las variables.

Si nosotros queremos añadir nuevas librerías ya no podemos hacer un install porque ya está instalado, tendríamos que modificar el composer.json y añadir la nueva librería, y ejecutar composer update.

Una librería muy utilizada en drupal es ckeditor, para editar texto. Buscamos en la web packgist.org, y cambiamos el fichero composer.json introduciendo la siguiente línea al apartado require.

“ckeditor/ckeditor”: “4.16.1”

Recordemos que la última linea del array no tiene coma pero la anterior si.

Guardamos e introducimos en el terminal el comando composer update y tendremos el siguiente resultado.

Image
Composer update

Además de instalarnos la nueva librería, Composer comprobará si alguna de las existentes tiene alguna actualización pendiente, y la instalará siempre y cuando lo tengamos así estipulado en los requisitos de las versiones que hablamos antes.

Observamos la carpeta vendor y tenemos la nueva carpeta ckeditor.

Image
Nueva carpeta ckeditor

Una característica importante a tener en cuenta es que la librería que nos vamos a descargar requiere otras librerías como dependencias, Composer instalará aquellas, sin que nosotros tengamos que especificarlo.

Es posible que deseemos eliminar una librería, en ese caso tenemos que borrar la librería del fichero composer.json, guardar y ejecutar el comando composer update. De ese modo, Composer se encarga de eliminar automáticamente la librería.

Hasta aquí hemos visto el uso de Composer, de modo básico pero que nos dará un plus de profesionalidad. Espero con ello haber podido ayudar o al menos aclarar a quien lo necesite esta herramienta esencial en el desarrollo con Drupal.

Image
Crear una tabla de bbdd en la instalación de un módulo en Drupal
Crear una tabla de bbdd en la instalación de un módulo en Drupal

En el desarrollo de un módulo en Drupal, una de las cosas que más nos puede interesar es, que en la instalación de nuestro módulo, se pueda generar una tabla donde nuestra aplicación pueda tratar datos.

Sobre la relación de Drupal y las bases de datos

Drupal utiliza un sistema que permite llevar a cabo dicha operación independientemente del motor de base de datos con el que esté trabajando llamado Database Abstraction Layer que traduce el lenguaje de Drupal para el tratamiento de las bases de datos al lenguaje del motor de base de datos. De modo que cualquier operación que desarrollemos con base de datos en Drupal, podrá funcionar en cualquier motor de base de datos en el que instalemos Drupal.

Entendamos motor de base de datos como sistema que tengamos instalado en el servidor, como MariaDB, MySQL, PotgreSQL, etc.

Suponiendo que tenemos creado un primer módulo, en caso contrario podéis encontrar un interesante tutorial con los primeros pasos a seguir en este mismo portal, tenemos que tener en cuenta que podemos, en la instalación del módulo, incluir un fichero de instalación que establezca los primeros pasos para la implantación del módulo y entre ellos el de la creación de nuestras tablas en bases de datos.

Pasos previos a la creación del módulo

Recordemos que los ficheros de nuestro módulo tiene que estar en una carpeta del mismo nombre dentro de la carpeta custom de la carpeta modules.

/var/www/html/midrupal/web/modules/custom/misdatos

En dicha carpeta tenemos creado el fichero misdatos.info.yml, en el cual introducimos los damos básicos que Drupal necesita para saber qué características tiene el módulo como el nombre, el tipo, una descripción, etc. A continuación vemos los datos que yo he introducido.

name: Mis datos
type: module
description: 'Modulo de base de datos'
package: Mis modulos
core_version_requirement: ^9

Excepto package que no lo es pero permite tener organizado nuestro módulo en grupos, el resto son datos obligatorios.

Ahora entre todos los módulos podemos encontrar el nuestro en un grupo llamado “Mis módulos”.

Sería la información mínima, pero podemos ampliarlo poniendo la versión del módulo.

version: 1.0

Ocultar el módulo a miradas indiscretas con el parámetro hidden, de modo que no aparecerá en el listado de módulos.

hidden: TRUE

También podemos indicar una ruta de la página de configuración del módulo, para lo cual tendríamos que poner el nombre de sistema de la ruta de dicha página.

configure: misdatos.admin

Puedes encontrar información completa sobre la configuración del fichero info en el enlace https://www.drupal.org/node/2000204

El módulo en ese estado, podemos activarlo pero no va a hacer nada aún. Realmente, Drupal sabe que existe pero nada más.

Durante la instalación del módulo

Para que módulo haga algo en la instalación tenemos que incluir un fichero llamado misdatos.install. Dicho fichero es un script de php que contiene una función hook_install()

Para los que no lo sepan, un hook o gancho es una función que llama a una función preestablecida que busca Drupal en su ejecución, y si existe, ejecuta sus instrucción. Veamos cómo funciona.

Para hacer funcionar el hook_install(), tenemos que cambiarle el nombre y  sustituir hook por el nombre de nuestro módulo de modo que la función se llamaría misdatos_install().

Lo primero que tener ya escrito en nuestro fichero es:

<?php

function misdatos_install(){

}

Es conveniente al programar en Drupal acostumbrarse a seguir las buenas prácticas establecidas por la comunidad, y una cosa que se ha establecido, ha sido la de documentar correctamente lo que se programa. De modo que en este caso tenemos que introducir un comentario en la parte superior del fichero con la siguiente estructura.

/**
*@file
*Descripción de la función del script en inglés
*/

@file, es una directiva que describe la función del fichero y que afecta a la documentación automática de Drupal. Bueno, es un tema para hablar mucho pero no es que no trae aquí de momento.

Nuestro fichero tiene ahora este aspecto.

<?php

/**
*@file
*Descripción de la función del script en inglés
*/

function misdatos_install(){

}

El siguiente paso es llamar del mismo modo a la función gancho, o hook que permite la creación de tablas y este se llama hook_schema(). Igual que antes, modificamos el nombre por misdatos_schema().

Tenemos que tener en cuenta que para que el hook_install pueda trabajar correctamente con la tabla que creemos, esta tiene que estar generada antes de que se ejecute la instalación, por ello tenemos que poner la función que crea las tablas antes de todo.
 

<?php

/**
*@file
*Descripción de la función del script en inglés
*/

function misdatos_schema(){

}

function misdatos_install(){

}

Encima de cada función ponemos la misma estructura de comentario pero sin la directiva @file.

<?php

/**
 *@file
 *Descripción de la función del script en inglés
 */

/**
 *  Descripción de la función en inglés
 */
function misdatos_schema(){

}

/**
 *  Descripción de la función en inglés
 */
function misdatos_install(){

}

En la función esquema podemos crear las tablas que necesitemos. Lo que tenemos que crear dentro de la función misdatos_schema() es un array $schema[]. Cada campo del array tiene el nombre de la tabla que creemos $schema[‘tabla_uno’]. Dentro de cada campo introducimos una array que contiene las características de cada campo de la tabla. Veamos un ejemplo:

$schema[‘tabla_uno’] = [
  ‘description’ => ‘Cadena de texto que describe la tabla’,
  ‘fields’ => [ // Estructura de campos que define una tabla
  ],
  'primary key' => [ // Indica los campos que son clave primaria de la tabla ],
  ‘indexes’ => [ // array que contiene los indices de la tabla ],
];

Es conveniente tener algo de idea respecto al funcionamiento de las bases de datos.

El campo fields, almacena un array con la estructura de campos de la tabla. Podemos poner un ejemplo del módulo book.
 

$schema['book'] = [
 'description' => 'Stores book outline information. Uniquely defines the location of each node in the book outline',
   'fields' => [
     'nid' => [
       'type' => 'int',
       'unsigned' => TRUE,
       'not null' => TRUE,
       'default' => 0,
       'description' => "The book page's {node}.nid.",
     ],
 
… //
 
   'primary key' => ['fid', 'type', 'id', 'module'],
   'indexes' => [
     'type_id' => ['type', 'id'],
     'fid_count' => ['fid', 'count'],
     'fid_module' => ['fid', 'module'],
   ],
]; // Cerramos el array
return $schema;
}

El primer campo es el campo nid, de tipo (type) int, unsigned, no null, con valor por defecto (default) cero y una cadena de descrición (description).

En el módulo file podemos encontrar en su fichero de instalación el campo ‘type’, que guarda una cadena ascii (varchar_ascii) con una longitud máxima de 64,...
 

'type' => [
       'description' => 'The name of the object type in which the file is used.',
       'type' => 'varchar_ascii',
       'length' => 64,
       'not null' => TRUE,
       'default' => '',
     ],

Puedes encontrar más información sobre la estructura de $schema en la url https://api.drupal.org/api/drupal/core!lib!Drupal!Core!Database!database.api.php/group/schemaapi/9.1.x

Finalmente, dentro de la función sacamos el resultado con un return $schema, que lo devuelve.

Nosotros seguimos con nuestro ejemplo y vamos a crear nuestro primer campo en nuestra primera tabla y el fichero queda así.

<?php

/**
 *@file My first bbdd module
 */

/**
 *Implements hook_schema
 */
function misdatos_schema(){

  $schema['tabla_uno'] = [
    'description' => 'Mi primera tabla',
    'fields' => [ 
      'campo_primero' => [
        'description' => 'Descripción de mi campo',
        'type' => 'int',
        ],
     ],
  ];
return $schema;
}

Guardamos el fichero e instalamos el módulo. En la interfaz no veremos nada pero si entramos en MySQL y consultamos las tablas de la base de datos de Drupal, entre ellas encontraremos la nuestra. Vacía pero será nuestra primera tabla en la base de datos.

Image
módulo en drupal