WordPress Yoast SEO + wp_comfy theme + Category titles

If you are using Yoast SEO plugin for wordpress with WP_Comfy theme you will notice that title’s (<title> tag) are not working as expected. Despite your settings in Yoast WordPress SEO: Titles the titles are not showing what you want.

Follow these steps to make them work:

Changes in header.php

Edit your /wp-content/themes/wp-comfy/header.php and change:

tle><?php seotitles(); ?></title>

To:

tle><?php wp_title(''); ?></title>

Changes in CATEGORY TITLE’s

In my SEO titles settings page, and more precisely in the Taxonomies->Category->title template I set the rule to:

%%title%% | %%sitename%% - %%sitedesc%%

But it failed to show the titles like I wanted.

I decided to make a quick (and dirty) fix in order to make it work:
– Edit \wp-content\plugins\wordpress-seo\frontend\class-frontend.php. Look for:

} else if ( is_category() || is_tag() || is_tax() ) {
			$term = $wp_query->get_queried_object();
			$title = trim( wpseo_get_term_meta( $term, $term->taxonomy, 'title' ) );

And change it to:

} else if ( is_category() || is_tag() || is_tax() ) {
			$term = $wp_query->get_queried_object();
			//$title = trim( wpseo_get_term_meta( $term, $term->taxonomy, 'title' ) );
			$title = $title . '  | '.get_bloginfo('name').' - '.get_bloginfo('description');

And you are ready to go!

Saber la URL actual desde php (o “dónde estás”) [resuelto] + consejillos SEO

¿Cómo saber la URL en la que “estás” con PHP?

Echa un vistazo a este código (pruébalo en tu server):

$host = $_SERVER['HTTP_HOST'];
$self = $_SERVER['PHP_SELF'];
$query = !empty($_SERVER['QUERY_STRING']) ? $_SERVER['QUERY_STRING'] : null;
$url = !empty($query) ? "http://$host$self?$query" : "http://$host$self";
echo $url;

¿Para qué quiero saber la URL en la que estoy?

Motivos de SEO
Imagina que diseñas una web y la cabecera (la llamaré header.php) es común a todas tus páginas.

Algo asi:

<!-- esto es header.php -->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>miguel martin | fotografía de moda y retrato en Zaragoza</title>
<link rel="stylesheet" type="text/css" href="css/styles.css" />
<!-- Muestro imágenes, cabecera o lo que sea -->

Después, desde cada página de tu web (las llamaré index1.phpindexN.php) haces un

<!-- esto es indexI.php -->
<?php
require_once('header.php');
# o un include('header.php');
?>

De forma que, escribiendo el código de header.php una única vez, éste se “empotre” en todas tus páginas. Hasta aqui, perfecto. Pero como algunos sabréis, google penaliza aquéllos sitios que considera con información duplicada…y la duplicidad de títulos.

¿Cómo puedo entonces saber dónde estoy desde el fichero header.php para que la información del título cambie en cada página?

Pues con algo asi…

<!-- esto es header.php -->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 
<?php
/* ¿Dónde demonios estoy? $_SERVER['PHP_SELF']; me dice la parte que me interesa... */
$self = $_SERVER['PHP_SELF'];
 
if (strpos($self,"beauty")) { // si la cadena "self" contiene la palabra "beauty" entonces quiero que mi título sea...
 $self = "Beauty portfolio |";
}
// y bla, bla, bla
else if (strpos($self,"fashion")) { $self = "Fashion portfolio |";}
else if (strpos($self,"sports")) { $self = "Sports portfolio |";}
else if (strpos($self,"beauty")) { $self = "Glamour portfolio |";}
else if (strpos($self,"contact")) { $self = "Contacto |";}
else if (strpos($self,"about")) { $self = "About |";}
else { $self = "";} 
 
?>
<title>miguel martin | <?php echo $self; ?> fotografía de moda y retrato en Zaragoza</title>
<link rel="stylesheet" type="text/css" href="css/styles.css" />

Creo que no hacen falta explicaciones adicionales. ¿No?

Ah! Hace algún tiempo escribí un artículo similar a este pero para joomla, por si os es de utilidad.

SEO: las mejores herramientas gratis

Os he hablado en muchas ocasiones de SEARCH ENGINE OPTIMIZATION (SEO) y me gustaría destacar algunas de las herramientas seo gratuitas más útiles.

1. Herramienta google para palabras clave: https://adwords.google.es/select/KeywordToolExternal.
Utilice la Herramienta para palabras clave para obtener nuevas ideas sobre palabras clave. Seleccione una de las opciones siguientes para introducir unas palabras o frases descriptivas, o especifique la URL de su sitio web. Sugerencias para utilizar la Herramienta para palabras clave.

2. Una vez seleccionadas las palabras clave (y las long tails, si las hubiera) para las que deseamos posicionarnos podemos chequear la densidad de keywords usando esta herramienta (gratis): densidad de keywords.

3. Tampoco debéis algo de lo que ya os he hablado, la generación de sitemaps con herramientas gratuitas como gsitecrawler.

Espero que os resulte útil esta info.

Adding jQuery UI tabs to Drupal 7 [SOLVED]

I recently wanted to add some jQuery UI tabs to nodes. Drupal 7 has jQuery 1.4 included in core, so we’ll take advantage of that.

This is how you do it:

First, edit template.php and create / make some changes to hook _preprocess_html.

function THEMENAME_preprocess_html(&$variables){
   // This function looks for node 1 and only adds the javascript for this.
   // However it can be extended in different ways if required
    drupal_add_library('system', 'ui.tabs');
    drupal_add_js('jQuery(document).ready(function(){
                jQuery("#tabs").tabs({event: "mouseover"});
                jQuery("#tabs").tabs().addClass("ui-tabs-vertical ui-helper-clearfix");
                jQuery("#tabs li").removeClass("ui-corner-top").addClass("ui-corner-left");
            });',
        'inline');
}

*Note that you can remove ui-tabs-vertical if you want horizontal tabs. You can also change the mouseover event to the event you prefer.

This would be the markup:

<!-- TITULOS PESTAÑAS -->
<div id="tabs">
<div id="tab-list">
  <ul>
  <li><a href="#tabs-1">Titulo 1</a></li>
  <li><a href="#tabs-2">Titulo 2</a></li>
  <li><a href="#tabs-3">Titulo 3</a></li>
  <li><a href="#tabs-4">Titulo 4</a></li>
  <li><a href="#tabs-5">Titulo 5</a></li>
  <li><a href="#tabs-6">Titulo 6</a></li>
  <li><a href="#tabs-7">Titulo 7</a></li>
  <li><a href="#tabs-8">Titulo 8</a></li>
  <li><a href="#tabs-9">Titulo 9</a></li>
  <li><a href="#tabs-10">Titulo 10</a></li>
  </ul>
</div>
 
 
<!-- CONTENIDO PESTAÑAS -->
<div id="tab-content">    
  <div id="tabs-1">
    <p>Texto de la TABS-1</p>
  </div>
  <div id="tabs-2">
    <p>Texto de la TABS-2</p>
  </div>
  <div id="tabs-3">
    <p>Texto de la TABS-3</p>
  </div>
  <div id="tabs-4">
    <p>Texto de la TABS-4</p>
  </div>
  <div id="tabs-5">
    <p>Texto de la TABS-5</p>
  </div>
  <div id="tabs-6">
   <p>Texto de la TABS-6</p>
  </div>
  <div id="tabs-7">
    <p>Texto de la TABS-7</p>
  </div>
  <div id="tabs-8">
    <p>Texto de la TABS-8</p>
  </div>
  <div id="tabs-9">
    <p>Texto de la TABS-9</p>
  </div>
  <div id="tabs-10">
    <p>Texto de la TABS-10</p>
  </div>
</div>
</div>

And a sample output:
UI-Tabs-Drupal

CDS Invenio: avoid duplicate content on comments and other record tabs

Using Invenio 0.99.x and interested in SEO? You should definetly try to avoid duplicate title‘s! When viewing a record (for instance, http://yourinveniopage.com/record/XXXX), you will notice several tabs on top: Information, Discussion, Usage Statistics…

cds invenio tabs

These links show different content, but the same <title>> Not great for SEO purposes. Use Google’s Webmaster Tools and you will notice this (Diagnose > HTML Suggestions > Duplicate title tags)
Duplicate titles CDS Invenio (SEO)

There are several ways to avoid duplicate titles. The easiest is to use robots.txt to avoid indexing, or even add a rel=”nofollow” (or even noindex) to the link tabs.

Using nofollow (or noindex) to avoid comments pages from being indexed

You just have to add a rel=”noindex,nofollow” to the html a tag.

Edit $PATH_TO_cds-invenio/lib/python/invenio/webstyle_templates.py

Search this:

elif label != _('Fulltext') and label != _('References') and label != _('Citations'):
                    out_tabs += '<li%(class)s><a href="%(url)s">%(label)s</a></li>' % \
                                {'class':css_class,
                                 'url':url,
                                 'label':label}

Change it to:

elif label != _('Fulltext') and label != _('References') and label != _('Citations'):
                    out_tabs += '<li%(class)s><a href="%(url)s" rel="noindex,nofollow">%(label)s</a></li>' % \
                                {'class':css_class,
                                 'url':url,
                                 'label':label}

And, as usual, do not forget to run to see changes:

inveniocfg --update-all; /etc/init.d/httpd restart

Changing the titles of comments pages to avoid duplicate titles

What if we want bots to index these pages? No worries, it can be done by hacking the code a bit.

For instance, lets refer to comments tab. Open /cds-invenio/lib/python/invenio/webcomment_webinterface.py and look for:

title, description, keywords = websearch_templates.tmpl_record_page_header_content(req, self.recid, argd['ln'])

Lets see how this line works (refer to last line):

python
 
>>> import urllib
from invenio.webcomment import check_recID_is_in_range, \
                               perform_request_display_comments_or_remarks,\
                               perform_request_add_comment_or_remark,\
                               perform_request_vote,\
                               perform_request_report
from invenio.config import CFG_SITE_LANG, \
                           CFG_SITE_URL, \
                           CFG_SITE_SECURE_URL, \
                           CFG_WEBCOMMENT_ALLOW_COMMENTS,\
                           CFG_WEBCOMMENT_ALLOW_REVIEWS
from invenio.webuser import getUid, page_not_authorized, isGuestUser, collect_user_info
from invenio.webpage import page, pageheaderonly, pagefooteronly
from invenio.search_engine import create_navtrail_links, \
     guess_primary_collection_of_a_record, \
     get_colID, check_user_can_view_record
from invenio.urlutils import get_client_ip_address, \
                             redirect_to_url, \
                             wash_url_argument, make_canonical_urlargd
from invenio.messages import wash_language, gettext_set_language
from invenio.webinterface_handler import wash_urlargd, WebInterfaceDirectory
from invenio.websearchadminlib import get_detailed_page_tabs
from invenio.access_control_config import VIEWRESTRCOLL
from invenio.access_control_mailcookie import mail_cookie_create_authorize_action
import invenio.template
webstyle_templates = invenio.template.load('webstyle')
websearch_templates = invenio.template.load('websearch')>>> from invenio.webcomment import check_recID_is_in_range, \
...                                perform_request_display_comments_or_remarks,\
...                                perform_request_add_comment_or_remark,\
...                                perform_request_vote,\
...                                perform_request_report
>>> from invenio.config import CFG_SITE_LANG, \
...                            CFG_SITE_URL, \
...                            CFG_SITE_SECURE_URL, \
...                            CFG_WEBCOMMENT_ALLOW_COMMENTS,\
...                            CFG_WEBCOMMENT_ALLOW_REVIEWS
>>> from invenio.webuser import getUid, page_not_authorized, isGuestUser, collect_user_info
>>> from invenio.webpage import page, pageheaderonly, pagefooteronly
>>> from invenio.search_engine import create_navtrail_links, \
...      guess_primary_collection_of_a_record, \
...      get_colID, check_user_can_view_record
>>> from invenio.urlutils import get_client_ip_address, \
...                              redirect_to_url, \
...                              wash_url_argument, make_canonical_urlargd
>>> from invenio.messages import wash_language, gettext_set_language
>>> from invenio.webinterface_handler import wash_urlargd, WebInterfaceDirectory
>>> from invenio.websearchadminlib import get_detailed_page_tabs
>>> from invenio.access_control_config import VIEWRESTRCOLL
>>> from invenio.access_control_mailcookie import mail_cookie_create_authorize_action
>>> import invenio.template
>>> webstyle_templates = invenio.template.load('webstyle')
>>> websearch_templates = invenio.template.load('websearch')
 
>>> title, description, keywords = websearch_templates.tmpl_record_page_header_content('http://zaguan.unizar.es/record/6765',6765,'es')
>>> print title
Implementación de una pasarela entre el protocolo RT-WMP y TCP/IP  |  Trabajos academicos
>>>

How-to fix duplicate title’s in comments

Edit webcomment_webinterface.py:

Look for:

title, description, keywords = websearch_templates.tmpl_record_page_header_content(req, self.recid, argd['ln'])

Add after:

title =  _("Comments") + title

And run this from commandline:

inveniocfg --update-all; /etc/init.d/httpd restart

Perform in a similar fashion to fix other ‘Statistics’ or other pages 😉

Joomla: know the section of an article [SOLVED]

Lets suppose you are developing a joomla module which displays some “share to facebook and twitter” links. That module should not display those links if the article’s section id is equals to 10.

We will be bulding a new function called getSection which will return the section of an article.

<?php
function getSection($iId) {
    $database = &JFactory::getDBO();
    if(Jrequest::getCmd('view',0) == "section") {
        return JRequest::getInt('id');
    }
    elseif(Jrequest::getCmd('view',0) == "category") {
        $sql = "SELECT section FROM #__categories WHERE id = $iId ";
        $database->setQuery( $sql );
        $row=$database->loadResult();
        return $row;
    }
    elseif(Jrequest::getCmd('view',0) == "article") {
        $temp=explode(":",JRequest::getInt('id'));
        $sql = "SELECT sectionid FROM #__content WHERE id = ".$temp[0];
        $database->setQuery( $sql );
        $row=$database->loadResult();
        return $row;
    }
}
 
// use it like:
$sectionId=getSection(JRequest::getInt('id'));
?>

For instance, you can rewrite the joomla addthis plugin. Notice lines 57-58 (the call to the new function) and lines 54-55 (remember the know where you are in joomla posts? ) 😉

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
<?php
/**
 * @version		$Id: example.php 10714 2008-08-21 10:10:14Z eddieajau $
 * @package		Joomla
 * @subpackage	Content
 * @copyright	Copyright (C) 2005 - 2008 Open Source Matters. All rights reserved.
 * @license		GNU/GPL, see LICENSE.php
 * Joomla! is free software. This version may have been modified pursuant
 * to the GNU General Public License, and as distributed it includes or
 * is derivative of works licensed under the GNU General Public License or
 * other free or open source software licenses.
 * See COPYRIGHT.php for copyright notices and details.
 * ------------------------------------------
 * MODIFIED By Miguel Martín 2011-07-22
 * ------------------------------------------
 */
 
// Check to ensure this file is included in Joomla!
defined( '_JEXEC' ) or die( 'Restricted access' );
 
jimport( 'joomla.plugin.plugin' );
 
 
function getSection($iId) {
  $database = &JFactory::getDBO();
  if(Jrequest::getCmd('view',0) == "section") {
      return JRequest::getInt('id');
  }
  elseif(Jrequest::getCmd('view',0) == "category") {
      $sql = "SELECT section FROM #__categories WHERE id = $iId ";
      $database->setQuery( $sql );
      $row=$database->loadResult();
      return $row;
  }
  elseif(Jrequest::getCmd('view',0) == "article") {
      $temp=explode(":",JRequest::getInt('id'));
      $sql = "SELECT sectionid FROM #__content WHERE id = ".$temp[0];
      $database->setQuery( $sql );
      $row=$database->loadResult();
      return $row;
  }
}
 
/**
 * Example Content Plugin
 *
 * @package		Joomla
 * @subpackage	Content
 * @since 		1.5
 */
class plgContentAddThisPlugin extends JPlugin
{
    function getButtonCode(&$params) {
	if($_REQUEST['view']=="frontpage") return ''; 
        //do not show the buttons in frontpage, no matter which is the section of the article
 
        if (JRequest::getVar('view')!='article') return ''; 
        // do not show if we are not on a full-view of the article
 
	$sectionId=getSection(JRequest::getInt('id'));
	if ($sectionId == '10') //the article category is equals to '10', so do not show the buttons...
		  	return '';
 
        $code = $this->params->get('code');
        if( empty($code) )
            $code = '<br/><a href="http://www.addthis.com/bookmark.php?v=250" onmouseover="return addthis_open(this, \'\', \'[URL]\', \'[TITLE]\')" onmouseout="addthis_close()" onclick="return addthis_sendto()"><img src="http://s7.addthis.com/static/btn/lg-share-en.gif" width="125" height="16" alt="Bookmark and Share" style="border:0"/></a><script type="text/javascript" src="http://s7.addthis.com/js/250/addthis_widget.js?pub=xa-4a3f0b283a364b52"></script><br/>';
      return '<!-- section id='.$sectionId.' -->'.$code;
    }
 
	function onBeforeDisplayContent( &$article, &$params, $limitstart )
	{
		global $mainframe;
 
        if( $this->params->get('position')==1 )
            return $this->getButtonCode($params);
		return '';
	}
 
	function onAfterDisplayContent( &$article, &$params, $limitstart )
	{
		global $mainframe;
        if( $this->params->get('position')==2 )
            return $this->getButtonCode($params);
 
		return '';
	}
}

Drupal para tontos (II): urls amigables con pathauto, theming de Views, etc

Ayer os conté cómo crear content types complejos con el módulo noderefURL. Como ejemplo creamos fichas de personas con datos propios y galería de fotos relacionada. Nuestro ejemplo es muy mejorable, veamos por qué:

1. Mejorar la URL: si visitamos el nodo de ejemplo que creamos en el anterior post, veremos que la URL es similar a:
www.tusitio.com/node/14. Esta URL es poco descriptiva. Para mejorarla usaremos los módulos Token, Path (instalado por defecto en Drupal 6) y Pathauto

2. Crear una categoría de menú para mostrar un listado de fichas: hemos creado una ficha y la hemos visto. Pero… ¿cómo veremos un listado de todas las fichas? ¿Cómo se ordenará esta visualización? ¿y si queremos tener una visualización “especial” del listado de fichas? Para ello usaremos el módulo Views

3. Crear “subcategorías” de fichas basándonos, por ejemplo, en el género. ¿Cómo añadir esta información a las fichas? Para ello usaremos el Módulo Taxonomy (ya instalado en Drupal 6). Si deseas puedes consultar este estupendo manual de taxonomy para drupal.

Configurando pathauto y URL’s automáticas

Vamos a empezar instalando y activando todos los módulos enumerados anteriormente. A continuación vamos a ir a /admin/build/path/pathauto y desplegaremos los Node path settings. En esta sección, en Patter for all Ficha paths ponemos fichas/[titler-raw].

pathauto drupal node path settings

Para que nuestro nodo de ejemplo tenga una URL de este tipo deberemos editarlo, desplegar las ULR path settings y marcar Automatic alias. La URL del nodo será ahora del tipo /ficha/miguel-martín.

pathauto drupal tilde

Si os fijáis, esta URL contiene una tilde. Como deseo eliminar las tildes de las URL’s, vuelvo a las opciones de pathauto y marco, en General Settings la opción Reduce strings to letters and numbers from ASCII-96.

Si deseo que funcionen tanto /ficha/miguel-martín como /ficha/miguel-martin deberé marcar, además, en las Update action de General Settings, la opción Create a new alias. Leave the existing alias functioning.

pathauto configuration drupal

Si ya tenía muchos nodos creados sin asignar url’s, puedo marcar la opción Bulk generate aliases for nodes that are not aliased y se generarán de forma automática estas URL’s. ¿No es genial?

Creando un listado de “Fichas” usando Views

Ahora vamos a jugar con el módulo Views para que al insertar la url /ficha nos liste todos los nodos de este tipo. Veamos cómo (si queréis leerlo en inglés, podéis hacerlo en este excelente tutorial).

Empezamos yendo al menú de Views (/admin/build/views) y pulsamos Add. Nos solicita varios datos (ver siguiente imagen):

drupal views add new view

Pulsamos Next.

Lo próximo que vamos a hacer es añadir campos (Add Fields) sobre qué deseamos mostrar. En mi caso marco:
* Content-foto (field_foto) [OJO! Cuando lo añadas, la última opción es “FORMAT” y debe tener seleccionado Image para que la imagen se muestre como tal ]
* Node: Link
* Node: Path
* Node: Title

Y pulso “add”.

Ahora tengo que añadir un FILTRO (Filter) para que esta vista sólo me muestre los nodos que me interesann.
* Filtro por Node Type == ‘ficha’. (elegimos en el filtro la opción Node: Type)

taxonomy filter drupal

A continuación hay que crear un Display para esta vista. Puede ser tanto una página, como un bloque, como un feed. En mi caso crearé una página (Page), pero perfectamente podría ser un bloque. Los matices entre página, bloque, feed, etc, los podéis leer en el manual del módulo Views.

Bien, pulsamos en Add Display. Veremos que en la parte inferior aparece la opción de darle un Path. Pulsamos sobre None y en el campo que aparece la URL, insertamos la palabra ‘ficha’. Se han marcado los pasos en la siguiente imagen (click para ampliarla):

drupal views add display page

Además, si nos fijamos, aparece la consulta (query) mysql que genera esta vista. En mi caso la consulta es:

SELECT node.nid AS nid,
   node_data_field_foto.field_foto_fid AS node_data_field_foto_field_foto_fid,
   node_data_field_foto.field_foto_list AS node_data_field_foto_field_foto_list,
   node_data_field_foto.field_foto_data AS node_data_field_foto_field_foto_data,
   node_data_field_foto.delta AS node_data_field_foto_delta,
   node.type AS node_type,
   node.vid AS node_vid,
   node.title AS node_title
 FROM drup_node node 
 LEFT JOIN drup_content_field_foto node_data_field_foto ON node.vid = node_data_field_foto.vid
 WHERE node.type in ('ficha')

También aparece una previsualización (preview) de cómo se ve el resultado de la ficha:
drupal views page display preview

Dando estilo a los Page Display’s creados con Views usando el módulo Theme Developer

Ya hemos creado nuestra nueva vista. Veamos qué aspecto tiene:

drupal preview

Si os fijáis, en la parte inferior derecha aparece una ventanita negra (Drupal Themer Information), que forma parte del paquete Theme Developer. Este paquete resulta de mucha utilidad cuando estamos creando temas. Nos dice qué fichero está produciendo esa salida (en este caso, es el views-view-fields.tpl.php).

A continuación vamos a personalizar ese fichero. Deseamos personalizarlo SOLO para esta vista, y no para las demás. Por tanto deberemos crear un NUEVO fichero para darle el estilo que deseemos a nuestro listado de fichas. Sin embargo, aun nos queda una duda: ¿cómo nombrar a ese nuevo fichero?

Entre los nombres propuestos por Drupal en esta View para las Row style output elijo views-view-fields–listafichas–page-1.tpl.php y pulso Rescan Template Files. Aparecerá en negrita el nuevo fichero usado para formatear la vista:

drupal views module template scan

Para empezar es bueno que se muestren los valores de los fields “en bruto” (el vector) y asi a partir de ahí ir jugando. Para ello, prueba el siguiente código (presta atención a las últimas líneas):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
<?php
// $Id: views-view-fields.tpl.php,v 1.6 2008/09/24 22:48:21 merlinofchaos Exp $
/**
 * @file views-view-fields.tpl.php
 * Default simple view template to all the fields as a row.
 *
 * - $view: The view in use.
 * - $fields: an array of $field objects. Each one contains:
 *   - $field->content: The output of the field.
 *   - $field->raw: The raw data for the field, if it exists. This is NOT output safe.
 *   - $field->class: The safe class id to use.
 *   - $field->handler: The Views field handler object controlling this field. Do not use
 *     var_export to dump this object, as it can't handle the recursion.
 *   - $field->inline: Whether or not the field should be inline.
 *   - $field->inline_html: either div or span based on the above flag.
 *   - $field->separator: an optional separator that may appear before a field.
 * - $row: The raw result object from the query, with all data it fetched.
 *
 * @ingroup views_templates
 */
?>
<?php foreach ($fields as $id => $field): ?>
  <?php if (!empty($field->separator)): ?>
    <?php print $field->separator; ?>
  <?php endif; ?>
 
  <<?php print $field->inline_html;?> class="views-field-<?php print $field->class; ?>">
    <?php if ($field->label): ?>
      <label class="views-label-<?php print $field->class; ?>">
        <?php print $field->label; ?>:
      </label>
    <?php endif; ?>
      <?php
      // $field->element_type is either SPAN or DIV depending upon whether or not
      // the field is a 'block' element type or 'inline' element type.
      ?>
      <<?php print $field->element_type; ?> class="field-content"><?php print $field->content; ?></<?php print $field->element_type; ?>>
  </<?php print $field->inline_html;?>>
<?php endforeach; ?>
 
<?php
//print print_r(array_keys(get_defined_vars()), 1);
//print print_r(array_keys($fields))
 
// O si tienes instalado el módulo developer, usa la función dpm o  dprint_r:
echo "<br />".dpm($fields);."<br />";

Esta función dsm nos crea una caja amarilla con la información de las variables (fields) que podemos usar:

drupal views module dsm function

Por ejemplo podemos acceder a la variable field_foto_fid, que es la que contiene la “imagen de perfil” de la ficha con:

print "<pre>".print_r($fields['field_foto_fid']->content)."

“;

¡A partir de este punto las posibilidades son ilimitadas!

En vez de escribir un rollo enorme, podéis ver este completo screencast sobre theming con views.

Drupal para tontos: crear un nuevo Content Type COMPUESTO para galería fotográfica

Hoy os voy a explicar cómo crear nuevos Content Types complejos. ¿Para qué sirve esto? Imagina que quieres hacer “fichas” de usuarios, que contengan, por ejemplo:
– Fotografía de perfil
– URL de su página web
– Texto
– Galería de fotos asociada

Queremos llegar a algo parecido a:
drupal custom content type complex nodereference style css

Imagina, además, que la galería se actualiza muy a menudo, pero no el resto de campos. O que quieres dar al usuario la opción de modificar las fotos de su galería, pero no el resto de campos. O quieres que un usuario tenga la opción de tener varias galerías, y ya tienes un Content Type galería que te gustaría seguir usando. O muchísimos otros casos donde queremos gestionar por separado unos datos del nodo de otros.

Una opción muy interesante para solventar este problema es crear Content Types complejos (con datos propios al nodo y “punteros” que “apuntan” a nodos de otro tipo).

Módulos necesarios

Para realizar los pasos que vienen a continuación es necesario tener instalados los siguientes módulos en Drupal. El orden en que los pongo es el orden en que los instalé yo (si no tienes ni idea, aqui puedes ver cómo instalar un módulo drupal):

Una vez instalados todos los módulos deberemos activarlos (/admin/build/modules).

Proceso de configuración

Ya tenemos instalados, activados y en funcionamiento nuestros módulos. Ahora hay que crear el nuevo Content Type (/admin/content/types/). En mi caso, hay dos tipos de nodos que intervienen:
1) Nodo “ficha”, que contendrá como propios los campos: url, cuerpo, foto y como puntero (node reference) la galería de fotos en cuestión.
drupal custom content type

2) Nodo tipo “gallery” (contiene la galería de fotos en sí misma). Este Content Type se crea de forma automática al instalar Gallery Assist.

A la hora de crear el nodo “ficha”, los Custom Fields quedan asi (click para ampliar la imagen):
custom content type fields drupal

En Manage Fields vemos el campo url (Type: text, Name: field_url), el campo foto (Type: File, Name: field_foto) y el campo galleria_fotos (Type: Node reference, Name: field_noderefgalleryassist).

Cuando creé este último campo, tuve que elegir el widget usado durante la creación del nodo. Hay varias opciones para este campo. Yo marco ‘select list’. A continuación una pequeña explicación (en inglés) sobre qué diferencias hay entre cada opción:



Select list
if you don’t have too many nodes to choose from, this can be a great choice; the user can see all of her choices at once and make a decision on which node to reference;
Check boxes/radio buttons
if you need to refer to multiple nodes at once, checkboxes can help; and/or if the list of possibilities is even smaller than needed for a select list (5 to 9 at most), then radio buttons may be your choice;
Autocomplete
this widget works very similar to a freetagging taxonomy selector or the Authored by: field at the bottom of a node form; you start typing, and Drupal will display a list of node titles that match the text you entered; you often only need to type a few letters to find exactly what you need, however, this requires the user to have some idea of what she is looking for; you also have the option to choose whether to search inside the node’s titles, or only at the beginning;

También deberé seleccionar el “tipo de contenidos que pueden ser referenciados” (Content types that can be referenced) y elijo “gallery”. El menú que nos permite realizar esta selección es similar a:

En Display Fields del tipo de nodo “ficha” (admin/content/node-type/ficha/display), prestemos especial atención al Field galleria_fotos, en especial al parámetro Full node, que debe tener seleccionado Teaser. Esto hace que nuestra galería G1 se muestre completa en la “Ficha” F1 con la que guarda relación. Más información sobre esto en el manual de theming complex data drupal.

drupal complex data

Creando nodos de ejemplo de tipo “ficha” y “gallery”

A continuación vamos a crear un nuevo nodo “Ficha” con una “gallery” asociada. Para ello primero creo la “gallery”, subo las fotos y guardo el nodo. Después creo una nueva “Ficha”, relleno los campos y selecciono de la lista de opciones la galería que deso enlazar a esta “ficha”.

Al final tendréis algo asi:
drupal custom types

Dándole estilo

Si habéis seguido los consejos hasta este punto, y no teneis customizada la plantilla de mostrar nodos, veréis algo asi:

Sí, sale, pero no como queremos. Por ello voy a crear dos plantillas personalizadas (custom templates) para mostrar los contenidos como yo deseo, una para la “ficha” y otra para la “gallery”.

* Plantilla para la galería: en /themes/garland/node-gallery_assist.tpl.php con el siguiente contenido:

1
2
3
4
5
6
<?php
// $Id: node.tpl.php,v 1.5 2007/10/11 09:51:29 goba Exp $
?>
  <div class="content clear-block">
    <?php print $content ?>
  </div>

* Plantilla para la ficha: en /themes/garland/node-ficha.tpl.php con el siguiente contenido:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<?php
// $Id: node-ficha.tpl.php,v 1.0 2010/07/05 08:39:36 miguelm Exp $
?>
<?php if ($page == 0) { ?><h2 class="title"><a href="<?php print $node_url?>"><?php print $title?></a></h2><?php }; ?>
 
<div id="maincontainer" style="margin-left: 50px;">
  <br />
  <!-- para poner algo en la zona superior 
  <div id="topsection">
    <div class="innertube"><h1>CSS Liquid Layout #2.1- (Fixed-Fluid)</h1></div>
  </div>-->
 
  <div id="contentwrapper" style="float: left; width: 100%;">
    <div id="contentcolumn" style="margin-left: 200px; >
      <div class="innertube" style="margin:10px">
      <?php /* para mostrar el cuerpo del nodo */ echo $node->content['body']['#value']; ?>
      </div>
    </div>
  </div>
 
  <div id="leftcolumn" style="float: left; width: 200px; margin-left: -100%; font-size:">
    <div class="innertube">
      <?php /* para mostrar la imagen del campo field_foto */echo theme('imagefield_image', $node->field_foto[0], "", "", array('width' =>  '200'), $getsize = FALSE); ?>
      <br />
      <?php /* para mostrar la URL */ echo l(t('Visita la web de '.$title), $node->field_url[0]['safe'], array('class' => 'active'));?>
    </div>
  </div>
</div>
 
<?php echo $node->field_noderefgalleryassist[0]['view']; ?>

Ahora, si recargamos el nodo de la Ficha, veremos que queda como nosotros queríamos:
drupal custom content type complex nodereference style css

Espero que os haya sido útil 😉

vBA news module customization (avoid topic links display)

A client’s vBulletin board uses vbadvaced news module to display posts from a hidden forum. Every post is wrapped with adv_portal_module_wrapper.

My client did not want the topic links to be displayed, so he asked me to hack the code to achieve this.

Change adv_portal_module_wrapper

The adv_portal_module_wrapper you will find in you ACP —> style manager —> in the drop down for which ever style your working on pick edit templates —> vbadvanced cmps templates —> adv_portal_module_wrapper (should be located halfway down in the list of templates)

However you might want to copy that template and make a new one in case you need the default, you can add one by ACP —> style manager —> the add template. copy and paste your adv_portal_module_wrapper contents in for a starting point.

The following is the original code of adv_portal_module_wrapper:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
$mods[formcode]
 
<div style="padding-bottom:$vba_style[portal_vspace]px">
	<table align="center" border="0" cellpadding="$stylevar[cellpadding]" cellspacing="$stylevar[cellspacing]" class="tborder" width="100%">
		<thead>
			<tr>
				<td class="tcat" colspan="$mods[colspan]">
				<if condition="$vba_style['portal_collapsemods']">
					<a href="#top" onclick="return toggle_collapse('module_$mods[collapse]')" style="float:$stylevar[right]"><img alt="" border="0" id="collapseimg_module_$mods[collapse]" src="$stylevar[imgdir_button]/collapse_tcat$modimgcollapse.gif" /></a>
				</if>
				<span class="smallfont"><strong>$vba_style[portal_blockbullet] <if condition="$mods['link']"><a href="$mods[link]">$mods[title]</a><else />$mods[title]</if></strong></span></td>
			</tr>
		</thead>
		<tbody id="collapseobj_module_$mods[collapse]" style="$modcollapse">
			<if condition="$show['tablerow']">
				<tr>
					<td class="$bgclass">
						$modulehtml
					</td>
				</tr>
			<else />
				$modulehtml
			</if>
		</tbody>
	</table>
</div>
<if condition="$show['endform']"></form></if>

I noticed the links where being created with the $mods[title] (refer to line 11). So where is this variable defined? Thanks to grep linux command I found out where it was assigned a value:

/includes/vba_cmps_include_top.php
/modules/news.php

In /modules/news.php there is this line, which gave me the clue on how to solve this issue

$mods['title'] = ($news['prefix'] ? $news['prefix'] : '') . ' <a href="' . $vbulletin->options['bburl'] . '/showthread.php?' . $vbulletin->session->vars['sessionurl'] . 't=' . $news['threadid'] . '">' . $news['title'] . '</a>';

So I thought I’d change the $mods[‘title’] call in adv_portal_module_wrapper to $news[‘title’], so my resulting copy of adv_portal_module_wrapper is called adv_portal_module_wrapper_miguel and is like follows (the only thing changed is line 11):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
$mods[formcode]
<!-- adv_portal_module_wrapper_miguel -->
<div style="padding-bottom:$vba_style[portal_vspace]px">
	<table align="center" border="0" cellpadding="$stylevar[cellpadding]" cellspacing="$stylevar[cellspacing]" class="tborder" width="100%">
		<thead>
			<tr>
				<td class="tcat" colspan="$mods[colspan]">
				<if condition="$vba_style['portal_collapsemods']">
					<a href="#top" onclick="return toggle_collapse('module_$mods[collapse]')" style="float:$stylevar[right]"><img alt="" border="0" id="collapseimg_module_$mods[collapse]" src="$stylevar[imgdir_button]/collapse_tcat$modimgcollapse.gif" /></a>
				</if>
				<span class="smallfont"><strong>$vba_style[portal_blockbullet] $news[title]</strong></span></td>
			</tr>
		</thead>
		<tbody id="collapseobj_module_$mods[collapse]" style="$modcollapse">
			<if condition="$show['tablerow']">
				<tr>
					<td class="$bgclass">
						$modulehtml
					</td>
				</tr>
			<else />
				$modulehtml
			</if>
		</tbody>
	</table>
</div>
<if condition="$show['endform']"></form></if>