programadores drupal

Drupal: rendimiento

Drupal es fantástico, es rápido levantar una aplicación con él, es muy muy flexible... casi como un framework de programación en si mismo... Quien diga que no se puede hacer algo en Drupal es simplemente porque no conoce la herramienta o porque no sabe programar sobre ella.

El problema? Es muy pesado... Esta es la única razón por la que algunos proyectos los estoy haciendo en Symfony :-(.

Se que se puede optimizar, montar un proxy cache, tirar de servidores ligeros como httplight, cherokee, ... pero si aplicas esos conocimientos sobre un script o un framework de programación puro, obviamente la aplicación irá mucho más rápida, será mucho "menos pesada" que la montada sobre Drupal.

En general, si puedes elegir, tienes presupuesto y recursos y el proyecto es "grande", atacalo con Symfony, Cakephp, RubyonRails (fantástico), ... En caso contrario, Drupal me ha salvado la vida en muchas ocasiones :-).

Hace unos años, allá por mis últimos años de universidad, un profesor al que aprecio estaba trabajando sobre un proyecto en el que trataban de realizar mediciones tan exactas como el tiempo que tarda en cargarse una etiqueta html, una img, .... sensible? Lo siguiente.

Con windows aquello era un baile, mediciones que debían ser de milisegundos variaban dependiendo de cuando las lanzaras hasta en segundos... solución? Me puse manos a la obra, instalamos una distribución de Linux con un kernel compilado a medida sin a penas módulos... y volvió a realizar las mediciones.

Windows tiene mucha "basura" corriendo en segundo plano. Cosas que usas a diario, otras no tan a diario... Ojalá Drupal fuera como Linux :-(.

Drupal: available variables in a concrete place, web, ...

Tipycal scenario. Imagine you need to know which variables yo need in a concret place of your site, say /blog, a node or a view. Very easy, simple add a block, for example at your foot if available in your theme, with php input availabe, and this code:

<?php  print '<pre>';  var_dump(get_defined_vars());  print '</pre>';?>

Now, make it only available for your role, for example, and place it where you prefer (foot for example).

Meta tags and custom title in views

Has ever need to insert a custom title in your drupal views? Or need to use meta tags in this so important for your project, views results?

A extremeley flexible solution can go throug creating your own custom views templateviews-view.tpl.php (or views-view--NAME-OF-VIEW.tpl.php). Then you can use the Drupal api to insert whatever you want, title, meta tags, ...

Example:

<code>drupal_set_title('bodas');

</code>

or even more flexible:

<code>if(arg(1)) drupal_set_title('bodas en '. arg(1));

else drupal_set_title('bodas');

</code>

And more "magic", meta tags in views:

<code>drupal_set_html_head('<meta name="keywords" content="bodas, '.arg(1).','.arg(2).'" />');

if(arg(1)) drupal_set_html_head('<meta name="description" content="listado de empresas de bodas" />');

else drupal_set_html_head('<meta name="description" content="listado de empresas de bodas en '.arg(1).'" />');

</code>

That was my friday tip :-).

More tips link: http://foreverheavy.com/10-quick-and-dirty-drupal-tips/

 

Drupal: Imagen por defecto en views / field_image

En multitud de ocasiones el no conocer la plataforma sobre la que estás trabajando te puede ocasionar el que des vueltas y más vueltas y que incluso acabes haciendo una "chapuza" en lo que debería ser algo "elegante" y limpio. La diferencia entre un junior y un senior reside, entre otras cosas, aquí, en el tiempo que te lleva montar una cosa y en cómo lo has implementado (no sólo que funcione sino que además, las tripas del "bicho" sean elegantes).

Drupal no es una excepción, como con cualquier framework. Imaginemos el escenario, tratamos de publicar un texto en Views con una imagen, devuelta también por un field. Si no hay imagen el requisito es que se muestre una imagen por defecto tipo "noimage". La primera intención es recurrir a un Custom field o un PHP field y tratar con un if() averiguar si el field image tiene o no contenido...

Con lo fácil que en realidad puede hacerse :-).

Simplemente, en el propio image_field, marcamos la opción "Empty text", y aquí añadimos el código que queremos que se devuelva en caso de no haber imagen publicada en ese nodo. Por ejemplo:

ROUTE-TO/noimage.png

Facil, verdad? Ahora desde un customfield efecutamos la magia:

<div class="imgempresa"><img width=80px src="[field_imagen_fid]"></div> <div class="txtempresa">[title]<br> [body] [tid]</div>

En field_imagen_fid tenemos la ruta al fichero, si contiene una imagen será la ruta estándar a dicho fichero. En caso contrario, la ruta al fichero que le hayamos dado nosotros en el campo "empty text" del field image.

De nada ;-)

Optimizando Drupal, mysql y apache

La labor de un buen programador web no es simplemente tirar lineas de código sin más, y despreocuparse del resto de aspectos. Un buen programador web debe saber escribir buenas aplicaciones, que funcionen como se espera, lo más libres de errores posible... pero también debe ser capaz de que estén optimizadas lo mejor posible para aprovechar al máximo los recursos que tienen en su entorno.

Aprovechar al máximo quiere decir gastar lo menos posible, y si podemos usar un 50% de los recursos, por mucho que andemos sobrados, mejor que mejor. Básicamente lo notaremos y lo agradeceremos infinitamente cuando tengamos un pico de tráfico de usuarios o cualquier otra incidencia similar.

Los logs son fantásticos para detectar posibles incidencias y secciones que estén funcionando de manera incorrecta. La otra gran herramienta que tenemos, en el caso de Drupal, es la de los módulos como Boost que nos permiten optimizar su rendimiento.

Otra herramienta de la que debemos hacer uso en casos más extremos es la de cambiar la "mole" que supone Apache, por un servidor algo más ligero y coherente en el uso de recursos, como Ngnix, lighttp o Cherokee.

La siguiente alternativa u opción es la de tirar de caches y servidores de este tipo, que se encargan de almacenar una versión de las páginas, servir ellos mismos las peticiones de información y liberar de carga al servidor web.

De cualquier modo, antes de meternos en este tipo de jardines, lo suyo es optimizar al máximo los ficheros de apache (apache2.conf), mysql (my.conf) y el propio Boost.

Personalmente, para el 90% de las páginas cuyo tráfico es mayormente de usuarios anónimos la tercera opción es la más recomendada en el módulo boost, la de "(Not Recommended) Set Boost & Core (if enabled) cache for each page".

Aunque pone "not recommended", es cierto que si continuas leyendo verás que habla precisamente de que si tu tipo de usuario es mayormente anónimo esta opción es bastante más agresiva a la hora de optimizar el rendimiento del servidor.

En próximos artículos más trucos y detalles sobre optimización de servidores enfocados especialmente en el rendimiento de Drupal.

Enlaces relacionados:

 

Cambiar de usuario en Drupal

Cuando estás programando una aplicación surgen fallos, errores y un montón de warnings e incidencias que en ocasiones los usuarios, o no son capaces de darnos toda la información, o simplemente necesitamos acceder con su usuario para recopilar más información.

Muy sencillo, sin tener que cambiar su password ni "violar" su cuenta, podemos usar el siguiente truco via "coding":

http://drupal.org/node/218104

o bien, más sencillo aún quizá, usar uno de estos módulos:

Crear una web social

Hay un montón de herramientas tipo CMS (gestores de contenido) que te permiten crear una red social con unos simples pasos. Sin embargo, cualquier solución que busques siempre va a tener unas u otras limitaciones, ya sea por licencias, aspecto, posibilidades de ampliación, etc...

La opción que más flexibilidad y posibilidades de ampliación a futuro nos asegura son, o bien usar un framework tipo Symfony, CakePHP o Ruby on Rails, por poner unos ejemplos. Si el presupuesto es reducido (siempre lo es) no vamos a poder partir de cero, con lo que la opción recomendada sería usar Drupal. No vamos a perder nada de flexibilidad, tendremos una web social lista en a penas unas jornadas de trabajo y con suficientes conocimientos de programación no tendremos ningún problema a la hora de añadir y/o ampliar casi cualquier característica que se nos ocurra.

Aquí tenemos un listado de módulos que podemos usar para partir de una base:

http://drupal.org/node/206724

y aquí una comparativa entre dos módulos imprescindibles para toda red social, User Relationships y Friendlist:

http://groups.drupal.org/node/14625

Ahora bien, como con cualquier CMS, simplemente instalando unos cuantos módulos no va a ser suficiente para tener un proyecto medianamente complejo que satisfaga el 100% de nuestras necesidades y/o requerimientos.

Aquí es donde entra en juego nuestra pequeña navaja suiza que es la programación en Drupal.

Durante las próximas semanas entraremos en detalle en cómo podemos elevar al 200% la potencia de Drupal aplicada al desarrollo y programación de redes sociales, incluso aplicaremos algunos ejemplos reales, sacados de casos concretos de clientes para los que hemos desarrollado redes sociales o incluso para proyectos propios de redes sociales.

Estás interesado en crear una red social? Tenemos experiencia en la creación de redes y webs sociales en Drupal, en sectores tan distintos como las bodas (mundo nupcial), los viajes o el deporte. Si estás interesado no dudes en contactar con nosotros, seguro que podemos encontrar la solución social que buscas al coste óptimo que estás buscando.

Reordenar un array con indices desordenados en php (drupal)

En Drupal es muy muy normal obtener algunas consultas de arrays de este tipo:

Array ( [1320] => stdClass Object ( [tid] => 1320 [vid] => 14 [name] => que ver [description] => [weight] => 0 [language] => [trid] => 0 ) [109] => stdClass Object ( [tid] => 109 [vid] => 5 [name] => Corfu [description] => [weight] => 0 [language] => [trid] => 0 ) ) corfu/que-ver-en-corfu/museo-arqueologicos-de-corfu

Fijaos el problema. La consulta con print_r de php ha devuelto un array de dos dimensiones o más... pero sus indices están desordenados. El primer elemento es el 1320, el segundo el 109, y así sucesivamente... En otra consulta a otro elemento los índices no tendrían necesariamente estos indices, con lo que no nos vale usar siempre el mismo número como seguro que ya estábais pensando ;-).

Este tipo de arrays se ven mucho en las taxonomias de drupal, donde el indice ha heredado el indice que la taxonomia tiene en su vocabulario correspondiente.

Bueno, el caso es que la solución es muy sencilla usando array_slice, fijaos:

$output = array_slice($nodocrucero->taxonomy, 0, 2);

$tid = $output[0]->tid;

donde tid, o mas bien print_r($tid); nos devolvería lo siguiente:

Array ( [0] => stdClass Object ( [tid] => 1320 [vid] => 14 [name] => que ver [description] => [weight] => 0 [language] => [trid] => 0 ) [1] => stdClass Object ( [tid] => 109 [vid] => 5 [name] => Corfu [description] => [weight] => 0 [language] => [trid] => 0 ) )

Fijaos, es el mismo array, pero ahora vemos claramente como el indice empieza en 0 y lista el resto de elementos sin ningún problema.

En la orden array_slice hemos pasado 0,2 como argumentos porque sabíamos que tenía únicamente dos elementos y queríamos que comenzara a contarlo en 0, pero podríamos usar indices distintos, mayor que 2 por ejemplo si tenemos arrays de mayor tamaño (el que sea, sin problemas).

 

Comparar y buscar perfiles de usuarios en Drupal

Drupal tiene varios módulos bastante buenos que permiten crear perfiles de usuarios a base de crear nodos (o contenidos) y asociarlos a tu perfil.

El módulo que se suele usar para esto en Drupal 6 en Content Profile, aunque en Drupal 7 ha cambiado un poco la cosa, es algo más compleja a primera vista, pero en general los cambios son a mejor mediante el uso de "Entities" y el módulo Profile2.

Puedes montarte, por poner un ejemplo inocente, una red social en la que los usuarios tienen su propio muro, información de su perfil, gustos, viajes hechos, el vino que les gusta, fecha de nacimento, ... lo que se os ocurra.

Genial, verdad? Ahora imaginaros que en esa red social "imaginaria" vamos a querer cruzar datos para, "por ejemplo", buscar amigos. Muy útil en una red social, verdad? Verdad que sería interesante no sólo mostrar usuarios sin más, sino mostrar únicamente aquellos usuarios que tengan coincidencias con tu perfil?

Con Drupal y el módulo views pueden hacerse maravillas sin tener que tocar una sólo linea de mysql y/o php... ahora bien, si queremos hacer algo más complejo, como lo es precisamente el cruzar datos de un perfil y encontrar coincidencias en otro... Drupal es fantástico pero no hace magia... todavía ;-).

Bien, solución? Muy "simple", expresiones regulares + mysql + tipos de contenido. Las expresiones regulares son algo así como la navaja suiza del programador, no entiendes su potencia hasta que realmente no te pones a trabajar con ellas.

La opción de usar un tipo de contenido es porque podemos crear un nodo específico para cada usuario en el que metamos un código php específico para ese tipo de nodos, y con rules, por ejemplo, hagamos que cuando un usuario se registra en la red ese nodo se crea automáticamente.

El contenido de dicho nodo como decía lo dirigiremos desde el node-TIPODECONTENIDO.tpl.php. La magia está simplemente en cargar desde la plantilla los datos del usuario "owner" usando el campo $node->uid). Con esos datos haremos ahora consultas sobre sobre los campos "nodeprofile" que pertenecen a dicho usuario, almacenamos los datos que nos interesen en un campo de texto, y lanzamos una consulta contra todos los usuarios obteniendo los mismos datos, pero de cada usuario.

Con esos datos en variables distintas "sólo" queda jugar con expresiones regulares, e ir almacenando, por ejemplo en un Array, los usuarios cuya coincidencia sea la que estamos buscando.

La coincidencia de la que os hablo puede ser exacta, lo que en la mayoría de los casos no tiene sentido, o "parcial". Ahora queda jugar con expresiones regulares en php para encontrar esa "coincidencia parcial" en los perfiles de usuario.

Usar de esta forma los tipos de contenido y los templates .tpl.php de Drupal es probablemente una aberración, pero es una solución rápida sin necesidad de tener que programar un módulo, cosa que por otra parte es muy sencillo.

Mucha teoría, verdad? Los próximos días pondré algún ejemplo en forma de código... y si habéis sido buenos probablemente en forma de módulo :-).

 

Drupal: Publicar un banner o mensaje despues del primer (o segudo) post

Seguro que te ha ocurrido alguna vez. Tienes un banner o un determinado mensaje que quieres colocar en el teaser, después del primer o segundo post, pero no más. No quieres que se repita de forma indefinida, sobre todo porque queda muy intrusivo.

La solución? Mas fácil de lo que en principio había estado tratando de hacer. Si usamos una variable global, su contenido se va a mantener a lo largo de todo el ciclo de vida de carga de la web (mientras un usuario abre la página). Por ejemplo:

<?php

global $nodenumber;

if($teaser){

//if(drupal_is_front_page()){

 

Fijaos que lo pongo al principio del fichero, justo antes de la declaración de inicio del $teaser de Drupal. De esta forma la varible ya está inicializada y evitamos que cada vez que vaya a mostrarse un post en la misma página se reinicie de nuevo la varible.

Ahora vamos al final de la plantilla del tipo de contenido, y hacemos lo siguiente:

<?php //print_r ($node); 

echo 'page:: ' . $page;

$nodenumber = $nodenumber + 1;

echo $nodenumber;

if($nodenumber == 1 || $nodenumber == 3) {

?>

<a href="http://bit.ly/sBPXWg"><img src="<?php echo base_path() . path_to_theme()?>/imagenes/BANNER.jpg" alt="" ></a>

<?php

}

?>

 

Facil, verdad? En nuestro caso estamos mostrando la imagen después del post número 1 y del tercero.

El código tendremos que insertarla en la plantilla del tipo de contenido que estamos usando, por ejemplo en node-blog.tpl.php, o en node-TIPOCONTENIDO.tpl.php