Archivo de la categoría: Drupal

Druplicon

Drupal 7: Controlar completamente los template de Field collection

El muy jodido tiene mas vueltas que una oreja cuando de theming se trata.

NOTA: todos los templates que hay que crear ponlos en tu theme. Lo ideal es dentro del directorio tu_theme/templates/field_collection o algo similar.

Primero creamos el tpl field-collection-view.tpl.php que es el wrapper que hay entre el html del field y el del field collection. Pon esto dentro:

<?php print $element['#children']; ?>

Luego field-collection-item.tpl.php que es el tpl que controla el render de cada uno de los item individuales de la colección:

<?php print render($content); ?>

Por ultimo necesitamos field-field-collection.tpl.php (ojo que mi wordpress junta los dos guiones), un tpl para el field que contiene todo lo que field collection entregue:

<ul class="coleccion de items">
  <?php foreach ($items as $delta => $item): ?>
    <li><?php print render($item); ?></li>
  <?php endforeach; ?>
</ul>

Y listo! ya tenes control a todos los niveles del markup que va a entregar un field collection.

Chau!

Druplicon

Drupal 7 : Crear un template block-bean-type-ENTITY-TYPE.tpl.php para bundles del módulo Bean

Caso de uso. Creaste un bean del tipo “banner” y quieres que el block.tpl.php tenga un marcado específico para este tipo de contenidos. O lo que es lo mismo que decir que quieres tener un block-bean-type-banner.tpl.php

La solución es poner este preprocess:

<?php
/**
 * Implements hook_preprocess_block().
 */
function TU_THEME_O_MODULO_preprocess_block(&$vars) {
  // Añadimos theme suggestions por tipo de bean.
  if ($vars['block']->module == "bean") {
    /** @var $bean Bean */
    $bean = bean_load_delta($vars['block']->delta);
    $vars['theme_hook_suggestions'][] = 'block__bean__type_' . $bean->type;
  }
}

Y ya podés copiar block.tpl.php a tu theme, renombrarlo a block-bean-type-banner.tpl.php, personalizarlo y borrar el cache.

Chau!

Druplicon

Drupal 7: Hacer bypass a page.tpl.php y html.tpl.php programáticamente

¿Y si necesitaras entregar una página sin los CSS ni JS ni el HTML (cabeceras, footer, sidebars) que viene por defecto?

Solo hay que hacer dos cosas:

1. Añadir la propiedad ‘delivery callback’ a tu menu callback

<?php
$items['factura/%node'] = array(
  'title' => 'Entrega una factura',
  'page callback' => 'generar_factura',
  'delivery callback' => 'mi_delivery_page',
  'access callback' => TRUE,
);

2. Añadir esta función.

No hace falta modificarla. Si querés cambiarle el nombre no te olvides de modificar también el nombre en el delivery callback del menú.

<?php
/**
 * Delivery callback.
 *
 * Entrega el contenido así como viene sin pasar ni
 * por page.tpl.php ni por html.tpl.php
 *
 */
function mi_delivery_page($page_callback_result) {
  if (isset($page_callback_result) && is_null(drupal_get_http_header('Content-Type'))) {
    drupal_add_http_header('Content-Type', 'text/html; charset=utf-8');
  }
  global $language;
  drupal_add_http_header('Content-Language', $language->language);
  print $page_callback_result;
  drupal_page_footer();
}

Borra cache y listo.

Chau!

Druplicon

BoF de Context vs panels

El Martes 22 a las 19hs España (GMT +1) junto a estoyausente vamos a dar una pequeña charla sobre el eterno dilema de cual usar.. Context? Panels?… pues eso.

Personalmente voy a tratar de hacerlo lo mejor posible. Hablando en publico soy medio boludo a veces XD

Este BoF se va a hacer por Hangouts para los que entren, y como este tiene una capacidad limitada, todo aquel que no pueda participar activamente, puede seguirlo por Youtube (via streaming) ;)

Se va a pasar el link de Hangouts y Youtube por el Twitter de la Asociacion española de Drupal

De que vamos a hablar?
Hemos elegido una página que presenta las problematicas que todo drupalero se encuentra cuando tiene que por ejemplo:

  • Gestion de layouts.
  • Contenidos condicionales.
  • Que tipo de markup genera cada modulo y posibles mejoras (no hace falta decir cual de los módulos hace eso XD).
  • Exponer contenidos relacionados y aprovecharlos para mezclarlo todo en una sola pantalla
    (Por ejemplo: node -> author -> Profile2 -> apellido).
  • Soporte para i18n,
  • Y algunos etc, etc, etc.

Ya saben.

Chau!

Druplicon

Drupal 7: Quitar un CSS o JS programaticamente

El siguiente hook lo pones en el template.php de tu theme:

<?php
function TU_THEME_css_alter(&$css) {
  $css = array_diff_key($css, array(
    // Añade todos los CSS que quieras quitar antes que se entregue la página.
    drupal_get_path('module', 'NOMBRE_MODULO') . '/PATH/HASTA/EL/CSS/foo.css' => FALSE,
    drupal_get_path('theme', 'NOMBRE_THEME') . '/PATH/HASTA/EL/CSS/foo.css' => FALSE,
  ));
}
function TU_THEME_js_alter(&$js) {
  $js = array_diff_key($js, array(
    // Añade todos los JS que quieras quitar antes que se entregue la página.
    drupal_get_path('module', 'user') . '/user.js' => FALSE,
  ));
}

Está claro que esos hook tienen juego. Puedes mirar cual URL vas a renderizar, o averiguar cualquier otra cosa que te ayude a decidir que CSS’s/JS’s vas a querer quitar.

Chau!

Druplicon

Drupal 7: Habilitar templates para nodos basados en su view mode

Si tenemos un content type llamado “citas” y tenemos mas de un view mode, por ejemplo “resumida” y “detallada“.
Para poder hacer templates tipo “node-cita-resumida.tpl.php” y “node-cita-detallada.tpl.php” simplemente tenemos que poner una linea en el HOOK_preprocess_node().

<?php
/**
 * Implements HOOK_preprocess_node().
 */
function HOOK_preprocess_node(&$variables, $hook) {
  $variables['theme_hook_suggestions'][] = 'node__' . $variables['node']->type . '__' . $variables['view_mode'];
}

Chau!

Drupal APC: configuración rápida

Aquí dejo una configuración rápida de APC.

extension=apc.so
apc.shm_segments=1
apc.shm_size=256M

Si están usando Debian o derivados pueden poner la configuración en /etc/php5/conf.d/20-apc.ini (la parte del nombre “20-” puede variar, verifiquenlo antes de editar).

Para mas opciones ver http://www.php.net/manual/es/apc.configuration.php

No olvides reiniciar apache: sudo service apache2 restart

Chau!

Drupal 7 + Views: Temear exposed filters como Dios manda

Lo primero que tenes que saber es que podes tomar el control del template que imprime los filtros expuestos de un view (views-exposed-form.tpl.php) simplemente copiandolo a tu theme y poniéndole un nombre con este formato:

views-exposed-form--VIEW_NAME.tpl.php
views-exposed-form--VIEW_NAME--DISPLAY_ID.tpl.php

Ejemplos:
Tengo un view llamado listado_usuarios y dos display: una página “administracion_usuarios” y un bloque “usuarios_por_fecha

(De mas especifico a mas genérico)

Solo para el formulario expuesto del display administracion_usuarios.

views-exposed-form--listado_usuarios--administracion_usuarios.tpl.php

Solo para el formulario expuesto del display usuarios_por_fecha.

views-exposed-form--listado_usuarios--usuarios_por_fecha.tpl.php

Para todos los display que tengan formulario expuesto en este view.

views-exposed-form--listado_usuarios.tpl.php

Cualquier view (CUALQUIERA) que tenga un display llamado administracion_usuarios.

views-exposed-form--administracion_usuarios.tpl.php

Cualquier view con cualquier display.

views-exposed-form.tpl.php

Chau!

Drupal: throbber para input gordos

La ruedita de autocomplete de drupal tiene un fallo, y es que cuando un input es un poquito “gordo” ya se ve parte de la ruiedita activa (porque es un sprite).
Aca les dejo el css y las imagenes que reemplazan al throbber de Drupal por el mismo pero separados, así deja de ser un incordio.

html.js input.form-autocomplete {
    background: url("throbber-inactive.png") no-repeat scroll 98% 50% transparent;
}
html.js input.form-autocomplete.throbbing {
    background: url("throbber-active.gif") no-repeat scroll 98% 50% transparent;
}

throbber-inactive <—- (click derecho y “guardar imagen como”)

throbber-active <—-(click derecho y “guardar imagen como”)

Aca pongo una versión con las imágenes embebidas. no hace falta que descargues las imágenes porque ya vienen incrustadas en el CSS.

html.js input.form-autocomplete {
  background: url('data:"image/png";base64,iVBORw0KGgoAAAANSUhEUgAAAA8AAAARCAMAAAA11AaTAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA2ZpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYxIDY0LjE0MDk0OSwgMjAxMC8xMi8wNy0xMDo1NzowMSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDpGRkY0M0MxQ0ZDOUFFMjExOUYwNTkyQzM4NDM3MTEyQiIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDpDNzEyMkVCMjlBRkUxMUUyQTQxNTk4RTJBMDQ5RjZDQiIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDpDNzEyMkVCMTlBRkUxMUUyQTQxNTk4RTJBMDQ5RjZDQiIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ1M1LjEgV2luZG93cyI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOjA1RjUzQzFDRkM5QUUyMTE5RjA1OTJDMzg0MzcxMTJCIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOkZGRjQzQzFDRkM5QUUyMTE5RjA1OTJDMzg0MzcxMTJCIi8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+8+0pVAAAAFFQTFRFxsbGzs7O3t7e5+fnCHO9////a6/Yi7/h3u/3RpzODHu91uf3HITG7/f/oM7nNZDKyuLztdbv5+/3GHvG9/f/7+/vvb291tbW9/f3tbW1////V+AtUQAAABt0Uk5T//////////////////////////////////8AJzQLNQAAAFxJREFUeNp8j1kOgDAIRIHGI7CM9z+oharRuvBBeJBhgNZ70BureIuTg5HBMTgMxk6ALcUMyokaPFlhQ6pAL0iqXVK0nhyyc1WP+ayf96c/rv7HfR4f9//+uwkwABszFtyhYnczAAAAAElFTkSuQmCC') no-repeat scroll 98% 50% transparent !important;
}
html.js input.form-autocomplete.throbbing {
  background: url('data:"image/gif";base64,R0lGODlhDwARAMQTAMri8xyExgx7ve/3/73e7/f3/9bn9xh7xrXW797v91qi0zWQyou/4aDO52uv2Ofv90aczghzvf///////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh/wtYTVAgRGF0YVhNUDw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYxIDY0LjE0MDk0OSwgMjAxMC8xMi8wNy0xMDo1NzowMSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDpGRkY0M0MxQ0ZDOUFFMjExOUYwNTkyQzM4NDM3MTEyQiIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDo3RkE0MTI2MTlBRkUxMUUyQUNCRDlCOEFDNDQ5MzZGQyIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDo3RkE0MTI2MDlBRkUxMUUyQUNCRDlCOEFDNDQ5MzZGQyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ1M1LjEgV2luZG93cyI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOjAyRjUzQzFDRkM5QUUyMTE5RjA1OTJDMzg0MzcxMTJCIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOkZGRjQzQzFDRkM5QUUyMTE5RjA1OTJDMzg0MzcxMTJCIi8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+Af/+/fz7+vn49/b19PPy8fDv7u3s6+rp6Ofm5eTj4uHg397d3Nva2djX1tXU09LR0M/OzczLysnIx8bFxMPCwcC/vr28u7q5uLe2tbSzsrGwr66trKuqqainpqWko6KhoJ+enZybmpmYl5aVlJOSkZCPjo2Mi4qJiIeGhYSDgoGAf359fHt6eXh3dnV0c3JxcG9ubWxramloZ2ZlZGNiYWBfXl1cW1pZWFdWVVRTUlFQT05NTEtKSUhHRkVEQ0JBQD8+PTw7Ojk4NzY1NDMyMTAvLi0sKyopKCcmJSQjIiEgHx4dHBsaGRgXFhUUExIREA8ODQwLCgkIBwYFBAMCAQAAIfkEBQYAEwAsAAAAAA8AEQAABWjgJI5kaZ6mwThNgiZQJMvKUCZCJAQR3xek2CLBiDAAPMfIoHtIigwJQGabNCIOydOojSFEDu42KgkzRMWsBKFAdCPfCVPg1GqnkepEmLADDlgkODIQDjE/JQ+HMw56JQYNLC4olJUoIQAh+QQFBgATACwAAAIADQANAAAFR+AkTkDDTMOormIxPsEULcoiLukqFUF0vCoJIwIhiB6rhExpI5wcIoVK2mhMpJOHwzUiAGQskUAyinVZ5qttsg5HkSvkaRUCACH5BAUGABMALAAAAgANAA0AAAU/4CROz5iMY4mK6nSK0FqsoiQBwghM0SgRi55AIlKwjJEADSVg0Bwo1YI1ya0IvNZiJ+KmRtOYaGBazlZe8igEACH5BAUGABMALAAAAgANAA0AAAVI4CROBuOM6JSk4oAKE+xAYsCmtmjEqCQBk4hrcpoQGEiGDXFiiJyRaGSCRCEUWMVydwNOhqLVTQWbQIqTQGH0YDnAo91JLAoBACH5BAUGABMALAAAAgANAA0AAAVJ4CROQMNMw6iuYjE+wRQtyrikbP7kEyHuqofjIZEseieHqCZgSGqNxqQ22UUigSMBIFMRFpGJQDKKjQiClXl6nLR5U2BwclqFAAAh+QQFBgATACwAAAIADQANAAAFQOAkTs+YjGOJiup0itC0jMW6HiMwRbYuSCIFqjaJ2UQM4MohSvASStJEMGJEIIRda6ErBHio7WpgOhJROhF5FAIAIfkEBQYAEwAsAAACAA0ADQAABUXgJE7G5IzolKTigAoT7EBiwKa2WMJ35JoiAoOAQpwYIuToqExOGJIJDVEaMSJQQAuVuDIABy4vEMkFCqMHy/FDlU6rUQgAIfkEBQYAEwAsAAACAA0ADQAABUbgJE7AxEzDqK5iMT7BFC3KuKRs/uQTIe6qhwO36J0cohpyUms0mL2IACcilCKTRaQhGQm6osNMIvGtYllFMcsbKYBBEysEACH5BAUGABMALAAAAgANAA0AAAVB4CROz5iMY4mK6nSK0LSMxboeIzBFti5IIoXoVJvEUAUGzwYL8ByjGUkUgRiAE8KuFQBgdagWbDQwMYso8KQ8CgEAIfkEBQYAEwAsAAACAA0ADQAABUngJE4G44zolKTigAoT7EBiwKa2aMT3FA2MSUBBVCBQiFNkKQpOTs4FY8ogiGiIneAhkYwArdFi1UvAJpBTrTB6sByu1O5EFoUAACH5BAUGABMALAAAAgANAA0AAAVI4CROQMNMw6iuYjE+wRQtyrikY8yKjxxBhhGB15hAApGIA7eYEE6OwmniENWKE4VEkoiqCADZbiKQ5L4sXbY5YY+zvVVvqgoBACH5BAUGABMALAAAAgANAA0AAAVB4CROz5iMY4mK6nSiy1isUSweI8AuUSPqAolIISFMBCPISiJRrFAO1mQgspWQK2OktdD9VtyJUkQVvVazlXeKCgEAOw==') no-repeat scroll 98% 50% transparent !important;
}

Chau!