Entradas

Mostrando entradas de 2011

HTML + Javascript para usar cualquier framework

Lea el artículo original en Puroguramu .

Por qué la Programación Orientada a Objetos es mala para Drupal

artículo de Matt Buttcher (2010/10/13), traducción libre de Antonio Kobashikawa Nota de traductor : Aunque Drupal se ha convertido en un movimiento poderoso, parece que, en el interés por capitalizar algunos negocios asociados, se han tomado decisiones que están distanciando al producto de sus objetivos primarios para la comunidad. Algunas personas han estado notando eso desde hace algún tiempo y me parece interesante el tema. He conducido o contribuido a docenas de proyectos Open Source. Y todo mi código ha sido siempre Orientado a Objetos, con una excepción. Esa excepción es Drupal. Java, Python, PHP, y aún OO Perl... soy un desarrollador que teje con la lana del OO. Así que esto puede sonar chocante para cualquiera que me conoce, pero mi argumento es que la OO es mala para Drupal. Créame que decirlo no es algo notable en mi vida de desarrollador. Me siento como si le dijera a mi niño que debe faltar al colegio, sólo porque tal nivel de sofisticación no es necesaria en su vida

Acceder a los valores de un nodo con javascript

Imagen
Una forma simple de hacer esto, es a través de Drupal.settings , que es un objeto siempre disponible. Para agregar el nodo a Drupal.settings , lo hago en alguna función adecuada, por ejemplo en la implementación del hook_form_alter() , ya que allí se hacen las alteraciones de los formularios de edición de nodos. Por ejemplo: function mymodule_form_alter(&$form, &$form_state, $form_id) {   switch ($form_id) {     case 'my_node_form':       ...       $node = node_load($form['nid']['#value']);       // port to javascript       if ($node) {         drupal_add_js(array('node' => $node), 'setting');       }       ...       break;     ...   } } Luego, en algún javascript que se invoque para el tipo my_node , se puede usar algo como:   var node = Drupal.settings.node;   var nid = Drupal.settings.node.nid;   var node_my_field = node.field_my_field[0].value; Si usa Firebug, podrá encontrar el objeto Drupal en la pestaña

Resolviendo el cambio de alias con views_customfield

Imagen
Views Custom Field  es un módulo que permite colocar PHP como contenido de un campo de una vista. Normalmente, uno usa la variable $data para acceder a los valores de los campos que se hayan definido. Por ejemplo, $data->nid permite obtener el valor de nodo y haciendo print_r($data) uno puede explorar otros valores que usar. Pero hay un problema con los valores de los campos CCK. El nombre de los campos que contienen sus valores en $data corresponden a aliases que no son constantes. Por ejemplo, cuando usa filtros expuestos, podrá encontrar que ese nombre de campo en $data cambia según qué filtro esté aplicando. Una forma de solucionar esto es usar $this->view , también disponible, para obtener el alias adecuado en cada caso. Es decir, en lugar de usar $data->some_field_alias usar $data->{$this->view->field['field_id']->field_alias} Este es un ejemplo real: <?php $cliente_nid = $data->{$this->view->field['field_client_nid'

Aplicando un patch en Windows

Imagen
El comando patch, disponible en Linux, usualmente no está disponible en Windows. Cuando uno quiere aplicar algún patch, suele encontrar una traba de solución no tan fácil. En lugar de las recomendaciones de instalar Cygwin, o algo parecido, alguna vez use Aptana (un derivado de Eclipse) para aplicar un parche. Hoy estoy instalando Simpletest y la documentación indica aplicar  patch -p0 < path/to/simpletest/D6-core-simpletest.patch y ya no recuerdo cómo lo hice con Aptana :-S Tampoco quisiera instalar Cygwin sólo para eso. Esta vez, noto que tengo instalado Git para Windows ( https://git-scm.com/download/win ), hago click derecho sobre el directorio drupal y elijo Git Bash Here . Hago patch --help para comprobar que cuento con el comando y luego: $ patch -p0 < sites/all/modules/simpletest/D6-core-simpletest.patch patching file `install.php' Hunk #1 succeeded at 19 (offset -1 lines). patching file `includes/bootstrap.inc' Hunk #1 succeeded at 1111 (offset -1 li

Generación modular de HTML

Imagen
Actualmente, cuando desarrolla un sitio usando cierto framework, no lo puede modificar con otro. Si está metido en esto, puede parecer obvio y hasta natural. Pero, si lo vemos en perspectiva, es algo así como una limitación por diseño. Algo que se podría mejorar. Lea el artículo original en  Puroguramu: Generación modular de HTML

Redirigir, excepto si se está recuperando contraseña

Imagen
El requerimiento es que los usuarios logueados sean redirigidos a la página proyectos-nuevos . Eso se puede implementar usando actions/triggers . Es decir, el action redirigir a proyectos-nuevos cuando ocurre el trigger login del usuario. Cuando un usuario solicita recuperar su contraseña, se le facilita un enlace que conduce a una página de acceso provisional y luego, normalmente ocurre una redirección a la edición de su cuenta. Sin embargo, la redireccion con actions/triggers interfiere con esto y conduce también a este caso hacia proyectos-nuevos . Para solucionarlo, es mejor usar el módulo rules . Instalado rules, en  admin/rules/trigger se puede agregar una nueva regla que conduzca a proyectos-nuevos cuando ocurra el login. Produce el mismo efecto que al usar actions/triggers, incluso el de interferir con la redirección de recuperación de contraseña. Para prevenir la redirección en ese caso, se puede agregar una condición PHP a la regla: if (arg(0) == 'use

Nombre real en el email de registro

Imagen
Normalmente, en el proceso de registro con Drupal, el usuario recibe un email que se refiere a él usando su nombre de usuario. Si entra a  admin/user/settings puede ver que existen ciertos tokens propios, entre los que esta  !username . ¿Y si se desea mostrar el nombre real? Por ejemplo, Antonio Kobashikawa, en lugar de akobashikawa. Una forma es usando hook_mail_alter() . Por ejemplo: // Custom email registration message function misc_mail_alter(&$message) {   // http://drupal.org/files/issues/realname_token_system_mail_notifications.patch   $midparts = explode('_', $message['id'], 2);   if ($midparts[0] == 'user' || $midparts[0] == 'logintoboggan') {     switch ($midparts[1]) {       case 'register_no_approval_required':         $realname = trim($_POST[' field_profile_nombres '][0]['value']) . " " . trim($_POST[' field_profile_apellidos '][0]['value']);         $message['subject'] =

Entorno Drupal en Linux Mint

Imagen
Luego de usar Ubuntu Natty Narwhal por algunas semanas, estoy probando Linux Mint 11 . Felizmente es un derivado de Ubuntu, así que puedo usar lo que aprendí allí. Los pasos que describo a continuación servirían también en Ubuntu Natty Narwhal. Una de las razones por la que decidí probar Linux Mint fue la incomodidad de usar el escritorio Unity .  Ahora, en Linux Mint, siento que las cosas son más simples y claras.  Para instalar un entorno para trabajar con Drupal: Usé Synaptic Package Manager marcando los siguientes paquetes (y respondiendo afirmativamente a sus requerimientos de dependencias): apache2 php5 mysql-server mysql-client php5-mysql Y otras que me parecieron adecuadas (aunque no sabría decir cuáles son estríctamente necesarias): php5-gd php5-curl php5-xmlrpc php5-sqlite php5-mcrypt php5-xdebug php5-adodb php5-geoip php-pear En el caso de mysql-server , en algún punto solicitará la contraseña del root para proseguir. Como instalé primero apache2

Geany con Zen Coding

Imagen
Geany es un editor de texto disponible para Linux y también para Windows. Zen Coding es una utilidad que permite generar HTML a partir de una expresión abreviada. Por ejemplo, resulta práctico que algo como 'html:xs' pueda expandirse en el esqueleto completo de un documento XHTML. Hay plugins que permiten tener la funcionalidad de Zen Coding en editores como Notepad++ o gEdit. Para Geany, está tardando un poco. Pero hay una manera, sugerida en el artículo http://damour-ua.com/?p=65 que puede ayudar mientras tanto. Descargar el archivo  http://damour-ua.com/files/zen.zip y descomprimirlo en algún lugar. Por ejemplo, yo lo coloqué como /home/rulo/Bin/zen En Geany, entrar a Edit, Format, Send Selection To, Set Custom Commands y colocar allí una línea como: python /home/rulo/Bin/zen/1.py Para probar la funcionalidad, en un documento de Geany, ingrese una expresión zen coding, como html:xs , selecciónela y pulse CTRL+1. Referencias http://damour-ua.com/?p=65 h

Drupal 6 con Admin Menu, Admin Theme, Seven, Bartik Mod

Hacen una bonita combinación. Admin Menu http://drupal.org/project/admin_menu Coloca un menú dinámico en el top de la página. Se puede indicar que mantenga la posición aunque haya scroll hacia abajo. Una vez habilitado, puede entrar a la configuración de su tema de administración y quitar el bloque Navigation (Navegación), ya que contiene básicamente los mismos items. Admin Theme http://drupal.org/project/admin_theme Agrega funcionalidades al Administration Theme (admin/settings/admin). Entre ellas, poder indicar en qué otras páginas usar también el tema de administración, o en cuáles no. Seven http://drupal.org/project/seven Un tema simple y agradable destinado a administración. Hace juego con Bartik. Bartik Mod http://kahthong.com/2010/10/bartik-drupal-6-theme-backported http://theme.thanage.eu/node/9 Bartik es el tema oficial de Drupal 7. Aunque no hay una versión oficial para Drupal 6, están estos ports disponibles.

Mostrando nodos con bloques asociados

Imagen
Lo que se requiere es mostrar páginas, cada una de las cuales tiene un banner superior y un banner lateral. Además, que ambos banners sean fácilmente editables. Quizás se pueda resolver con relativa facilidad usando Panels, pero tengo problemas usando ese módulo en un servicio de hosting que limita la memoria para PHP a 32 MB. Idea Que los banners sean nodos asociados a un tipo principal (usando CCK, node reference). La presentación sería usando bloques. Los bloques que contienen a los nodos se definirían usando Views. Implementación Las páginas son nodos de tipo page . Creo el tipo de contenido banner_superior . En mi caso, contiene un CCK imagefield. Creo una vista que provee una lista de nodos de tipo banner_superior. No es necesario definir un display, como se verá en el paso 4. En el tipo de contenido page, agrego el campo field_page_banner_superior , de tipo node reference , con widget tipo select . En la configuración de este campo, indico que el select use los v

Unobstrusive wev dev

Imagen
Lea el artículo original en  Unobstrusive web dev .

Un entorno de desarrollo Drupal portable con XAMPP y FreeCommander

Imagen
Uso habitualmente Windows 7 y XAMPP 1.7.1 (por la compatibilidad con Drupal 6.x). Hay proyectos que avanzo en casa y hay otros que avanzo en la oficina. En muchas ocasiones requiero consultar cómo hice algo en tal o cual site y me gustaría poder tenerlos al mismo tiempo. Portatil Ir cargando una laptop podría ser ser, pero creo que preferiría otra opción. USB Podría tener mi entorno de desarrollo en el USB y trabajar directamente allí. XAMPP tiene versiones portables que se pueden instalar en un USB. XAMPP Lite es incluso más ligera. Sin embargo, mi experiencia es que es realmente muy lento. Hosting Un tiempo probé hacer el desarrollo directamente en un hosting. La ventaja es que el desarrollo se hace en un solo lugar. La desventaja es que la edición via FTP es mucho más lenta. Además, es una opción vulnerable porque el hosting puede quedar fuera de servicio o haber problemas de conectividad, lo que me ocurrió algunas veces (es para ponerse a pensar, si uno ha puesto bastan

uphp para Drupal

Imagen
En días recientes, navegando por Internet, me topaba con las opiniones de algunos desarrolladores sobre Drupal. Comparado con otros frameworks, como los tipo MVC, CakePHP o similares, Drupal es raro. Brillante, pero raro. No es MVC y se apoya, más bien, en una arquitectura que usa hooks para permitir la colaboración de los módulos que se instalen. Drupal tiene su modo particular de hacer las cosas y cuesta un poco acostumbrarse. A su modo de tratar los formularios, de hacer los temas, de intervenir en el flujo. Sin embargo, el hecho es que Drupal está floreciendo más rápido que otros frameworks. Muchos puristas de OOP critican que no use objetos, aunque Drupal dice que implementa los conceptos de OOP de modo diferente. Quizás sea eso. Que Drupal ofrece una forma diferente de hacer las cosas que, una vez que se aprenden, ayuda a ser más colaborativo y productivo. Pero, si uno tiene un sistema modelado en OOP tradicional, puede encontrar algunos inconvenientes para pasarlo a Drupal

Resolviendo node.save en Services

Imagen
El módulo services  viene con algunos servicios por default. Node Service pone a nuestra disposición varios servicios relativos a nodos. Uno de ellos es node.save . node.save permite publicar un nodo desde otro site. En particular, otro site Drupal. Sin Keys Servidor Suponiendo que el site donde queremos publicar es http://myserver.example.com , allí se instala services. Hay que activar los módulos: Services XMLRPC Server Node Service En la interfaz de administración (admin/build/services), en la pestaña Browse , puede navegar por los servicios disponibles. Como está activado Node Service , estarán disponibles: node.view node.get node.save node.delete Cuando elige un servicio, se le mostrará su sintaxis y un formulario de prueba. En el caso de node.save , se requiere como parámetro un array node. Como la publicación se hará como usuario anónimo, hay que darle los permisos necesarios para crear el tipo de nodo que deseamos. Por ejemplo, si queremos crear de este modo

Usando XMLRPC con Services

Imagen
Services es un módulo que permite definir web services que responden a solicitudes usando diversos protocolos. Por default, viene con soporte para XMLRPC. En este ejemplo, hay un proveedor de web services y un cliente de web services. Proveedor Supongamos que el proveedor del web service tenga el url http://webservice-provider.com Luego de instalar el módulo services (y activar Services y XMLRPC Server) puede entrar al administrador, admin/build/services, para navegar por los services definidos por default. Uno puede agregar más services, colocando un módulo adecuado en modules/services/services/. Por ejemplo, si tengo un tipo de contenido llamado job: modules/services/services/job_service/job_service.info name = Job Service description = Provides a job service package = Services - services dependencies[] = services core = 6.x modules/services/services/job_service/job_service.module /** * Implements hook_service */ function job_service_service() { return array(

Haciendo backtrace rápido y sucio

Imagen
En el artículo  Quick-and-Dirty Debugging , de Angela Byron , se muestra una manera rápida de ver el backtrace (la secuencia de llamadas de funciones), de un error. Consiste en modificar drupal_set_message(), localizado en includes/bootstrap.inc: function drupal_set_message($message = NULL, $type = 'status', $repeat = TRUE) { if ($type == 'error') { $message .= '<xmp>'. print_r(debug_backtrace(), 1) .'</xmp>'; drupal_add_js('console.log('.json_encode(array('Drupal Backtrace'=>debug_backtrace())).');','inline'); } if ($message) { ... } La línea en amarillo está basada en la propuesta de Byron y la verde en la que David Konsumer puso en los comentarios al artículo. Puedes comentar la linea que desees o el condicional if para hacer el backtrace en diferentes circunstancias.

Listando los hooks invocados

Imagen
Al programar con Drupal, algo que me gustaría conocer es cuáles son los hooks que podría usar en un momento determinado. Y, si se pudiera, en que orden son ejecutados. Cuando he preguntado a otros, nadie parece tener la respuesta. Bueno, aún no la he hallado, pero he encontrado en el artículo  Drupal: Exposed  de Angie Byron , una forma de listar los hooks usados en un momento determinado. Consiste en localizar la funcion module_implements , que está en includes/module.inc , y hacer algo algo como: function module_implements($hook, $sort = FALSE, $reset = FALSE) { ... drupal_set_message("hook_$hook"); ... } Dice el articulo que como pueden haber hooks que se invocan después que la página es mostrada (no sabía que eso podía suceder), esta lista de hooks los mostraría en la siguiente carga de la página.

CSS3 para mejorar el breadcrumb de un tema Zen

Imagen
CSS3 está permitiendo hacer muchas cosas interesantes que antes requerían además javascript o imágenes de apoyo. Por ejemplo, usando sólo CSS se puede hacer que la lista de breadcrumbs se vea como: La idea es independiente del tema. En este caso, la ilustraré con un subtema Zen. Configuración del tema Normalmente hay un caracter de separación para los términos del breadcrumb. Ingresar a la configuración del tema e indicar que no se use ninguno. También indicar que no se agregue dicho caracter al final de la lista. HTML De ese modo, el HTML del breadcrumb será similar a: <div class="breadcrumb"> <a href="/drupal/inmobiliaria/">Inicio</a> <a href="/drupal/inmobiliaria/admin">Administrar</a> <a title="Controla la apariencia del sitio." href="/drupal/inmobiliaria/admin/build">Construcci&#195;&#179;n del sitio</a> <a title="Cambia el tema que usa el sitio

Hacking Views

Vengo usando Views  prácticamente desde que empecé con Drupal. Aprender Views me requirió paciencia y, principalmente, práctica, pero creo que ha valido el esfuerzo. La interfaz puede parece un poco intimidante al comienzo, pero luego va adquiriendo sentido. Hay varias cosas de Views que me gustaría saber, pero aún no he resuelto. Estas son algunas, sin ningún orden en particular: ¿Se puede usar Views para mostrar un array arbitrario? Eso me ayudaría a usar su mecanismo de paginación, al menos, para presentar otro tipo de resultados que no tengan que ver necesariamente con base de datos. ¿Puede usar Views un SQL arbitrario? ¿Cuál es la forma de modificar, programaticamente, la consulta, el proceso o el resultado? ¿Cómo lograr una caja de búsqueda que ubique el termino en cualquiera de un conjunto de campos especificados? Hoy encontré este artículo de Jeff Eaton :  Hacking Views, Part 1: Basic Concepts Me está ayudando a entender mejor algunas cosas. Por ejemplo, yo suelo defi

Cómo agregar un formato minutos:segundos

Imagen
Para agregar un nuevo formato a los disponibles en el combo que se muestra en las opciones de visualización de un nodo (o de un campo CCK), normalmente habría que agregar algunas funciones en un módulo. El módulo custom_formatters permite hacerlo de modo más sencillo. Requiere que además esté instalado cck y token . Pasos Una vez instalado custom_formatters, ir a admin/build/formatters. Hay algunos ejemplos que pueden servir de guía. Elegir Add new formatter para agregar un nuevo formato. Para este ejemplo: Nombre: minuto_segundo Etiqueta: Minuto:Segundo Editor mode: Advanced Field type(s): number_float PHP: return sprintf('%02d:%02d', $element['#item']['value']/60, $element['#item']['value']%60); Cuando se elige Editor mode: Advanced, se puede usar PHP. De otro modo es HTML y tokens. Para este caso, el valor del elemento a formatear, está en $element['#item']['value']. Puede leer el artículo original en  Drupa

Cómo definir un selector CSS que requiera dos clases

Imagen
Lea el artículo original en Puroguramu .

Cómo personalizar los enlaces de nodereference_url

Imagen
Nodereference_url permite indicar que se agreguen enlaces para crear un hijo al final del nodo padre. Por ejemplo, si hay un nodo proyecto , se puede crear un nodo foto , con un campo nodereference que apunte a un determinado proyecto. Nodereference_url permite agregar automáticamente al nodo proyecto un enlace que conduzca a la creación de un nodo foto. Esto puede ser cómodo. De ese modo podemos tener nodo foto , nodo plano , nodo noticia , nodo inscripcíon , etc, cada uno con un campo nodereference apuntando a proyecto. Y, en el nodo proyecto, automáticamente enlaces que permiten crear estos nodos hijos. Los nodos automáticos son dispuestos en orden alfabético. ¿Qué tal si deseamos otro orden?. Además, ¿qué tal si queremos que se muestre el enlace sólo en algunas circunstancias y no en otras?. nodereference_url_create_link El módulo nodereference_url contiene la función nodereference_url_create_link ($node, $field_name, $type_name, $attributes), donde: $node es el nodo q

Como modificar el breadcrumb para un nodo de cierto tipo

Imagen
El breadcrumb es el conjunto de enlaces que suele aparecer en la parte superior de las páginas para indicar el camino seguido para llegar hasta allí. Pero, por default, no siempre queda tal cual se quiere. En este caso, mostraré cómo se puede modificar usando el archivo template.php del tema shamrock , que es un subtema que hice del tema  zen . Ejemplo Tengo un nodo proyecto, que tiene un campo CCK field_proyecto_tipo , que puede ser 'Nuevo' o 'Entregado' . Se desea que el breadcrumb pueda conducir a las página proyectos-nuevos o p royectos-entregados según si el nodo presentado es de tipo 'Nuevo' o 'Entregado' . function shamrock_preprocess_node(&$vars, $hook) { if ($vars['type']=='proyecto') { $tipo = $vars['field_proyecto_tipo'][0]['value']; $bc = drupal_get_breadcrumb(); if ($tipo==t('Nuevo')) { $bc[] = l(t('Proyectos Nuevos'), 'proyectos-nuevos'); }

Cómo hacer un segundo botón de envío

Me resultó de ayuda este post:  Additional submit button on node forms

Una forma de usar Cufon

Imagen
Cufon es una alternativa para reemplazar las fuentes de la página con otras no estandar. Cufón es un script que traza las fuentes con ayuda de archivos .js generados (desde esta página http://cufon.shoqolate.com/generate/) a partir de una fuente .ttf, otf, o pfb. En el formulario que aparece en la página del generador de coufon, pueder ser útil (particularmente para el español) indicar que incluya además los siguientes glifos: “”‘’…_&-–—åäöæøàèìòùáéíóúâêîôûäëïöüãõñçÅÄÖÆØÀÈÌÒÙÁÉÍÓÚÂÊÎÔÛÄËÏÖÜÃÕÑÇ©®™′″´×⁺ Aunque existe el módulo cufon , aquí describo una forma de usarlo diréctamente. Los archivos Coloco cufon-yui.js y los archivos .js de las fuentes en un módulo. Por ejemplo el módulo misc. El código Creo un bloque (llamado Cufon, por ejemplo) que contenga el código php que requiero y se muestre en cada página: <?php drupal_add_js(drupal_get_path('module', 'misc') . '/js/cufon-yui.js'); drupal_add_js(drupal_get_path('module', 'misc

Cómo hacer un login AJAX alternativo

Imagen
El login normal de Drupal es un formulario que, en caso de error, conduce a otra página. El objetivo es un formulario que use AJAX para el login y permita mostrar los mensajes de error sin cargar otra página. El bloque Creo un bloque (my-login) con este contenido: <?php global $user; ?> <?php if ($user->uid): ?> <div id="block-my-login"> <div class="title"><?php echo l(t('Login'), 'user', array('attributes'=>array('id'=>'btn-my-login'))) ?></div> <div class="content"> <ul> <li> <?php echo l(t('Mi cuenta'), 'user') ?> </li> <li> <?php echo l(t('Salir'), 'logout') ?> </li> </ul> </div> </div> <?php else: ?> <div id="block-my-login"> <div class="title&quo

Solucionando error con drush dl

Imagen
Venía utilizando drush 4.2 con normalidad. Tanto en Linux (Centos 5, php 5.2.10) como en Windows 7 (xampp 1.7.1). Uno de estos días, me ocurrió, en ambos, que ya no funcionaba ejecutar algo como: drush dl drupal-6.20 En Windows, obtenía un error como: C:\bin\dev\xampp171\htdocs\>drush dl drupal-6.20 Source directory [error] C:\Users\compaq\AppData\Local\Temp/drush_tmp_1299865530/drupal is not readable or does not exist. Project drupal (6.20) could not be downloaded to [error] Investigando, se debe a un issue documentado en http://drupal.org/node/1078318 . Alli proveen también el parche http://drupal.org/files/issues/drush-1078318.patch : diff --git a/commands/pm/pm.drush.inc b/commands/pm/pm.drush.inc index e39096a..18ec069 100644 --- a/commands/pm/pm.drush.inc +++ b/commands/pm/pm.drush.inc @@ -1858,7 +1858,7 @@ function pm_parse_project_version($requests) { function pm_project_types() {