Python: autocomplete names with tab key [solved]

I learned a python trick that saved me a lot of time when using the interpreter. Just wanted to share it with you.

>>> import rlcompleter, readline
>>> readline.parse_and_bind("tab:complete")

With the above lines you’ll have a unix-like autocomplete for functions. For instance, if you type

>>> import os
>>> os.

And then you press “TAB” the list of OS module functions will show up. Ain’t it AWESOME? :>

WordPress: show excerpts in the category or tag view [SOLVED]

“I just want to only display the excerpt instead of the entire text of the post in the category / tag archives, how to achieve this?”. This is a common question of wordpress users.

Well, the fix is really simple. Go to your working theme directory and look for content.php (or sometimes archive.php). You should see something like:

<?php if (is_search()) the_excerpt(); else the_content(__('Read the rest of this entry &raquo;', '')); ?>

Or it might just be:

<?php if ( is_search() ) : // Only display Excerpts for Search ?>

Just change that to include the cases of displaying category archive (or tag archive), as in:

<?php if ( is_category() || is_tag() || is_date() || is_search() ) : // Only display Excerpts for Tag Archive, Date Archive, and Search ?>

Upload the file to your server and you’re ready to go :)

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 ;)

Compass (IV): 100% height using 960.gs grid [SOLVED]

Ayer os comenté la forma de conseguir un sticky footer usando el grid 960.gs en Compass

Sin embargo el ejemplo de ayer no completaba la altura del div de contenido (#content) hasta el footer:

El ejemplo de hoy es muy similar, pero el contenido se extiende hasta alcanzar el footer (height 100% del elemento contenedor):

Fichero de marcado:

<!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" />
<link href="./stylesheets/grid.css" media="screen, projection" rel="stylesheet" type="text/css" />
<link href="./stylesheets/text.css" media="screen, projection" rel="stylesheet" type="text/css" />
<title>Compass 24 column grid tutorial by Miguel Martín</title>
</head>
<body>
	<div id="wrapper2">
	    <div id="segundo" class="container_24">  
        	<div id="header">
        		<p>This is the header</p>
        	</div>
        	<div id="left-sidebar">
        		<p>This is left</p>
        	</div>
        	<div id="main-content">
        		<p>This is main content</p>
        	</div>
        	<div id="right-sidebar">
        		<p>This is right</p>
    		</div>
       </div> <!-- /segundo -->
    </div> <!-- /wrapper2 -->
 
    <div id="footer">
        	<p>This is footer</p>
    </div>
</body>
</html>

Fichero grid.scss (de estilo):

 
/* Tutorial Compass (IV) 
 * Autor: Miguel Martin (miguelm[at]unizar[dot]es)
 * Más detalles: www.leccionespracticas.com
 */
 
@import "compass/reset";
@import "960/grid";  
 
$ninesixty-columns: 24;
$ninesixty-gutter-width: 10px;
 
.container_24 {
  @include grid-container;
 
  background-image: url(../img/24_col.gif);
  background-color: #fff;
  background-repeat: repeat-y;
 
  min-height: 100%;
 
  #header {
    @include grid(24); 
  }
 
  #left-sidebar{
  	@include grid(4);
  }
 
  #right-sidebar {
    @include grid(4); 
  }
 
  #main-content {
    @include grid(16);
  } 
 
}
 
#footer {
    position: relative;
    margin-top: -50px; /* negative value of footer height */
    height: 50px;
    clear: both;
	background: #FFF;
	margin-bottom: 0px;
	padding:0px;
	width: 960px;
	margin-left: auto;
	margin-right:auto;
 
	p{
		padding: 5px;
		border: 0px;
		margin: 0px;
	}
} 
 
/* ---- con wrapper2 consigo height 100% en el contenedor de contenido ------ */
#wrapper2{
	height:100%;
	margin-bottom: -50px;
	background:#333;
	width:960px;
	margin-left:auto;
	margin-right:auto;
}
/* --------------------------------------------------------- */
 
/* General CSS settings */
body {
  background: #123;
  color: #333;
  font-size: 11px;
}
 
html, body, #wrapper {height: 100%;}
 
body > #wrapper { height: auto; min-height: 100%; }
 
#content { overflow: auto; padding-bottom: 50px; } 
 
a {
  color: #fff;
  text-decoration: none;
}
 
a:hover {
  text-decoration: underline;
}
 
h1 {
  font-family: Georgia, serif;
  font-weight: normal;
  padding-top: 20px;
  text-align: center;
  background: #FFF;
}
 
h2 {
  padding-top: 20px;
  text-align: center;
}
 
p {
  border: 1px solid #666;
  overflow: hidden;
  padding: 10px 0;
  text-align: center;
}
 
/* `Clear Floated Elements
----------------------------------------------------------------------------------------------------*/
.clear {
  clear: both;
  display: block;
  overflow: hidden;
  visibility: hidden;
  width: 0;
  height: 0;
}
 
 
.clearfix:before,
.clearfix:after,
.container_24:before,
.container_24:after {
  content: '.';
  display: block;
  overflow: hidden;
  visibility: hidden;
  font-size: 0;
  line-height: 0;
  width: 0;
  height: 0;
}
 
.clearfix:after,
.container_24:after {
  clear: both;
}
 
/*
  The following zoom:1 rule is specifically for IE6 + IE7.
  Move to separate stylesheet if invalid CSS is a problem.
*/
 
.clearfix,
.container_24 {
  zoom: 1;
}

Utilizando estos dos ejemplos como base se puede realizar de forma muy simple cualquier layout sobre un grid de anchura fija de 960px.

En próximos capítulos veremos las desventajas de utilizar grids de ancho fijo ahora que los tablets, móviles y demás aparatos de resoluciones dispares están conquistando el mercado.

Linux: Sustitución de texto en múltiples ficheros usando SED [resuelto]

¿Cómo hacer una sustitución de texto en múltiples ficheros de forma simultánea, usando la línea de comandos linux?

El comando SED permite hacer sustituciones de forma muy cómoda. Por ejemplo, el siguiente comando sustituye todas las ocurrencias (nótese el /g al final) de oldWord por newWord en todos los ficheros *.ext que se encuentren bajo ese directorio (.) (incluidos otros subdirectorios).

find . -name "*.ext" -exec sed -i "s/oldWord/newWord/g" '{}' \;

En mi caso lo he utilizado para añadir un nuevo usuario a un listado enorme de directorios protegidos por un .htaccess, sustituyendo “Require user” por “Require user newuser“:

find ./ -name ".htaccess" -exec sed -i "s/Require\ user/Require\ user\ newuser/g" '{}' \;

Compass (III): Sticky footer how to [SOLVED] [RESUELTO]

Llevo unos posts hablando sobre Compass y me preguntaban vía mail cómo conseguir un sticky footer mediante este sistema.

Bueno, me preguntaban cómo hacer que la altura de la página fuera 100%. Pero vamos, es lo mismo y se hace del mismo modo que se hace siempre: div para wrapper, div para content y el footer fuera. Pero veámoslo con un ejemplo:

<!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" />
<link href="./stylesheets/grid.css" media="screen, projection" rel="stylesheet" type="text/css" />
<link href="./stylesheets/text.css" media="screen, projection" rel="stylesheet" type="text/css" />
<title>Compass 24 column grid tutorial by Miguel Martín</title>
</head>
<body>
	<div id="wrapper">
	   <div id="content" class="container_24">  
        	<div id="header">
        		<p>This is the header</p>
        	</div>
        	<div id="left-sidebar">
        		<p>This is left</p>
        	</div>
        	<div id="main-content">
        		<p>This is main content</p>
        	</div>
        	<div id="right-sidebar">
        		<p>This is right</p>
    		</div>
       </div> <!-- content -->
    </div> <!-- /wrapper -->
 
    <div id="footer">
        <p>This is footer</p>
    </div>
</body>
</html>

Y el grid.scss para 24 columnas sería

/* Tutorial Compass (III) - sticky footer resuelto
 * Autor: Miguel Martin (miguelm[at]unizar[dot]es)
 * Más detalles: www.leccionespracticas.com
 */
 
@import "compass/reset";
@import "960/grid";  
 
$ninesixty-columns: 24;
$ninesixty-gutter-width: 10px;
 
.container_24 {
  @include grid-container;
 
  background-image: url(../img/24_col.gif);
  background-color: #fff;
  background-repeat: repeat-y;
 
  #header {
    @include grid(24); 
  }
 
  #left-sidebar{
  	@include grid(4);
  }
 
  #right-sidebar {
    @include grid(4); 
  }
 
  #main-content {
    @include grid(16);
  } 
 
}
 
#footer {
    position: relative;
    margin-top: -150px; /* negative value of footer height */
    height: 150px;
    clear: both;
	background: #FFF;
	margin-bottom: 0px;
	padding:0px;
} 
 
 
 
/* General CSS settings */
body {
  background: #123;
  color: #333;
  font-size: 11px;
}
 
 
html, body, #wrapper {height: 100%;}
 
body > #wrapper { height: auto; min-height: 100%; }
 
#content { overflow: auto; padding-bottom: 150px; } 
 
a {
  color: #fff;
  text-decoration: none;
}
 
a:hover {
  text-decoration: underline;
}
 
h1 {
  font-family: Georgia, serif;
  font-weight: normal;
  padding-top: 20px;
  text-align: center;
  background: #FFF;
}
 
h2 {
  padding-top: 20px;
  text-align: center;
}
 
p {
  border: 1px solid #666;
  overflow: hidden;
  padding: 10px 0;
  text-align: center;
}
 
/* `Clear Floated Elements
----------------------------------------------------------------------------------------------------*/
.clear {
  clear: both;
  display: block;
  overflow: hidden;
  visibility: hidden;
  width: 0;
  height: 0;
}
 
 
.clearfix:before,
.clearfix:after,
.container_24:before,
.container_24:after {
  content: '.';
  display: block;
  overflow: hidden;
  visibility: hidden;
  font-size: 0;
  line-height: 0;
  width: 0;
  height: 0;
}
 
.clearfix:after,
.container_24:after {
  clear: both;
}
 
/*
  The following zoom:1 rule is specifically for IE6 + IE7.
  Move to separate stylesheet if invalid CSS is a problem.
*/
 
.clearfix,
.container_24 {
  zoom: 1;
}

Y el resultado:

Compass (II): Grid de 24 columnas listo para trabajar

Como ya vimos en la primera parte del tutorial de Compass este sistema facilita muchísimo la escritura, legibilidad y jerarquización de CSS.

Los ejemplos de la primera parte del tutorial eran simplemente para entender los mecanismos de Compass+SASS. En esta segunda parte vamos a desarrollar un ejemplo más útil, que servirá para comenzar a diseñar sobre él: un grid de 24 columnas con un header, footer y dos sidebars.

Lo que vamos a obtener es esto:

El fichero index.html que contiene el marcado html (aka markup) será realmente simple:

<!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" />
<link href="./stylesheets/grid.css" media="screen, projection" rel="stylesheet" type="text/css" />
<link href="./stylesheets/text.css" media="screen, projection" rel="stylesheet" type="text/css" />
<title>Compass 24 column grid tutorial by Miguel Martín</title>
</head>
<body>
    <h1>Ejemplo más completo de Compass+LASS</h1>
	<div class="container_24">  
    	<div id="header">
        	<p>This is the header</p>
        </div>
        <div id="left-sidebar">
        	<p>This is left</p>
        </div>
        <div id="main-content">
        	<p>This is main content</p>
        </div>
        <div id="right-sidebar">
        	<p>This is right</p>
    	</div>
        <div id="footer">
        	<p>This is footer</p>
        </div>
    </div>
</body>
</html>

En este caso nuestro fichero grid.scss va a contener varias cosas adicionales que no habíamos visto en la primera parte del tutorial.

Algunos ajustes básicos de estilo:

body {
  background: #123;
  color: #333;
  font-size: 11px;
  height: auto;
  padding-bottom: 20px;
}
 
a {
  color: #fff;
  text-decoration: none;
}
 
a:hover {
  text-decoration: underline;
}
 
h1 {
  font-family: Georgia, serif;
  font-weight: normal;
  padding-top: 20px;
  text-align: center;
  background: #FFF;
}
 
h2 {
  padding-top: 20px;
  text-align: center;
}
 
p {
  border: 1px solid #666;
  overflow: hidden;
  padding: 10px 0;
  text-align: center;
}

Las reglas clearfix para un grid de 24 columnas:

/* `Clear Floated Elements
----------------------------------------------------------------------------------------------------*/
 
/* http://sonspring.com/journal/clearing-floats */
 
.clear {
  clear: both;
  display: block;
  overflow: hidden;
  visibility: hidden;
  width: 0;
  height: 0;
}
 
/* http://www.yuiblog.com/blog/2010/09/27/clearfix-reloaded-overflowhidden-demystified */
 
.clearfix:before,
.clearfix:after,
.container_24:before,
.container_24:after {
  content: '.';
  display: block;
  overflow: hidden;
  visibility: hidden;
  font-size: 0;
  line-height: 0;
  width: 0;
  height: 0;
}
 
.clearfix:after,
.container_24:after {
  clear: both;
}
 
/*
  The following zoom:1 rule is specifically for IE6 + IE7.
  Move to separate stylesheet if invalid CSS is a problem.
*/
 
.clearfix,
.container_24 {
  zoom: 1;
}

Y la parte jugosa, donde definiremos el grid de 24 columnas sobre el contenedor de 960px, centrado, con su margen (aka gutter) entre columnas (que no serán los 20px por defecto, sino 10px):

$ninesixty-columns: 24; // grid de 24 columnas...
$ninesixty-gutter-width: 10px; // separadas 10px...
 
.container_24 {
  @include grid-container;
 
  background-image: url(../img/24_col.gif); // imagen con las franjas "rosas" de fondo
  background-repeat: repeat-y; // que se repite en horizontal...
  background-color: #fff; // sobre un color de fondo blanco...
  margin-bottom: 20px;
 
  #header, #footer {
    @include grid(24); 
  }
 
  #left-sidebar{
  	@include grid(4);
  }
 
  #right-sidebar {
    @include grid(4); 
  }
 
  #main-content {
    @include grid(16);
  } 
}

Y por último, dejo el fichero grid.scss completo:

/* Tutorial Compass (II) 
 * Autor: Miguel Martin (miguelm[at]unizar[dot]es)
 * Más detalles: www.leccionespracticas.com
 */
 
@import "compass/reset";
@import "960/grid";  
 
$ninesixty-columns: 24;
$ninesixty-gutter-width: 10px;
 
body {
  background: #123;
  color: #333;
  font-size: 11px;
  height: auto;
  padding-bottom: 20px;
}
 
a {
  color: #fff;
  text-decoration: none;
}
 
a:hover {
  text-decoration: underline;
}
 
h1 {
  font-family: Georgia, serif;
  font-weight: normal;
  padding-top: 20px;
  text-align: center;
  background: #FFF;
}
 
h2 {
  padding-top: 20px;
  text-align: center;
}
 
p {
  border: 1px solid #666;
  overflow: hidden;
  padding: 10px 0;
  text-align: center;
}
 
.container_24 {
  @include grid-container;
 
  background-image: url(../img/24_col.gif);
  background-color: #fff;
  background-repeat: repeat-y;
  margin-bottom: 20px;
 
  #header, #footer {
    @include grid(24); 
  }
 
  #left-sidebar{
  	@include grid(4);
  }
 
  #right-sidebar {
    @include grid(4); 
  }
 
  #main-content {
    @include grid(16);
  } 
}
 
/* `Clear Floated Elements
----------------------------------------------------------------------------------------------------*/
 
/* http://sonspring.com/journal/clearing-floats */
 
.clear {
  clear: both;
  display: block;
  overflow: hidden;
  visibility: hidden;
  width: 0;
  height: 0;
}
 
/* http://www.yuiblog.com/blog/2010/09/27/clearfix-reloaded-overflowhidden-demystified */
 
.clearfix:before,
.clearfix:after,
.container_24:before,
.container_24:after {
  content: '.';
  display: block;
  overflow: hidden;
  visibility: hidden;
  font-size: 0;
  line-height: 0;
  width: 0;
  height: 0;
}
 
.clearfix:after,
.container_24:after {
  clear: both;
}
 
/*
  The following zoom:1 rule is specifically for IE6 + IE7.
  Move to separate stylesheet if invalid CSS is a problem.
*/
 
.clearfix,
.container_24 {
  zoom: 1;
}

Si deseáis descargarlo de forma completa, podéis hacerlo aqui:
DESCARGA EJEMPLO COMPLETO

Un poco más

Vamos a ver cómo añadir, por ejemplo, una tercera fila con contenido solo en la segunda columna. Debemos añadir una nueva clase (que llamaré ancho1_desplazado1 y resultará en un ancho de 30px) con:

  .ancho1_desplazado1{
 	@include grid-prefix(1,24);
  	@include grid(1);
  }

Y añadir un nuevo div de esa clase en nuestro marcado…

<body>
    <h1>Ejemplo más completo de Compass+LASS</h1>
    <div class="container_24">  
    	<div id="header">
        	<p>This is the header</p>
        </div>
        <div id="left-sidebar">
        	<p>This is left</p>
        </div>
        <div id="main-content">
        	<p>This is main content</p>
        </div>
        <div id="right-sidebar">
        	<p>This is right</p>
    	</div>
        <div class="ancho1_desplazado1">
        	<p>A1</p>
        </div>      
        <div id="footer">
        	<p>This is footer</p>
        </div>
    </div>
</body>
</html>

Y conseguiremos el efecto deseado:

Utilizando Photoshop para hacer nuestro diseño

Una vez visto cómo colocar elementos del ancho deseado en la posición deseada, podemos empezar a realizar nuestro diseño de página usando photoshop. Para ello abrimos un nuevo documento .psd y metemos la imagen rosa de fondo.

A partir de este punto podemos realizar todo nuestro diseño sobre el fichero PSD y más adelante “traducirlo” a CSS :)

Compass (I): instalación, primeros pasos y ejemplos básicos

Si diseñas webs a menudo puede que estés cansado de estar haciendo tú mismo los CSS’s (y los cálculos que esto conlleva). Hay sistemas, como 960 grid que ayudan (y mucho) a construir grids sobre un contenedor de 960 px. ¿Por qué 960px? Porque es un número fácilmente divisible (resto entero entre dos, tres, cuatro, cinco, etc)

Los sistemas como 960.gs son muy cómodos de utilizar una vez entiendes el funcionamiento básico, pero terminan generando un markup muy poco legible y sobrecargado de información de estilo, algo que va en contra de la filosofía de separar markup de información de estilos.

Un ejemplo (sacado de un proyecto real):

<div class="grid_6 push_3 suffix_2">
   <p>logo</p>
</div>
<div class="grid_2 prefix_3">
   <p>sometext</p>
</div>
...

Con Compass seguiremos manteniendo la comodidad de diseñar sobre un grid, pero obtendremos un marcado mucho mejor.

Por ejemplo, partiendo de esto:

@import "compass/utilities/general/clearfix";
@import "960/grid";
 
$ninesixty_columns: 16;
 
#wrapper
{
  @include grid_container;
  @include clearfix;
}
 
#mast
{
  @include grid(16);
  @include clearfix;
  background: #ddd;
 
  #logo
  {
    @include grid(6);
    @include alpha;
  }
 
  #strapline
  {
    @include grid(10);
    @include omega;
  }
}

Terminaremos consiguiendo un fichero CSS renderizado tal que asi:

/* line 7, ../src/grid.scss */
#wrapper {
  margin-left: auto;
  margin-right: auto;
  width: 960px;
  overflow: hidden;
  display: inline-block;
}
/* line 8, ../../../../../Library/Ruby/Gems/1.8/gems/compass-0.10.0/frameworks/compass/... */
#wrapper {
  display: block;
}
 
/* line 13, ../src/grid.scss */
#mast {
  display: inline;
  float: left;
  margin-left: 10px;
  margin-right: 10px;
  width: 940px;
  overflow: hidden;
  display: inline-block;
  background: #ddd;
}
/* line 8, ../../../../../Library/Ruby/Gems/1.8/gems/compass-0.10.0/frameworks/compass/... */
#mast {
  display: block;
}
/* line 19, ../src/grid.scss */
#mast #logo {
  display: inline;
  float: left;
  margin-left: 10px;
  margin-right: 10px;
  width: 340px;
  margin-left: 0;
}
/* line 25, ../src/grid.scss */
#mast #strapline {
  display: inline;
  float: left;
  margin-left: 10px;
  margin-right: 10px;
  width: 580px;
  margin-right: 0;
  background: red;
}

¿Cómodo, eh?

Instalando Compass

Compass necesita que tengas instalado Ruby. Existen múltiples instaladores de Ruby. Si desarrollas en Windows, una de las formas más simples de instalar Ruby es utilizar RubyInstaller. Si desarrollas en MAC OS o en Linux/Unix, lo más cómodo es instalar Ruby utilizando RVM (Ruby Version Manager).

Una vez instalado, deberemos añadir al PATH la ruta donde hemos instalado Ruby. Por ejemplo, en mi caso, instalo en un Windows 7, en la ruta c:\Ruby193 y añadiré al PATH (panel de control -> variables de entorno) este directorio.

Después abro una consola (Inicio -> Ejecutar -> Start command prompt with Ruby) y procedo a instalar Compass y el plugin compass-960-plugin:

gem update --system
gem install compass
gem install compass-960-plugin

¿Dónde está la documentación del plugin 960gs para Compass?

Puedes leerla en tu máquina al instalar el compass-960-plugin o consultar la documentación en línea y las distintas opciones.

Creando nuestro primer proyecto con Compass

Una vez instalado, vamos a crear un primer proyecto llamado my_project utilizando el plugin 960 para Compass.

compass create -r ninesixty my_project --using 960

Producirá una salida tal que:

directory my_project/
directory my_project/sass/
directory my_project/stylesheets/
   create my_project/config.rb
   create my_project/sass/grid.scss
   create my_project/sass/text.scss
   create my_project/stylesheets/grid.css
   create my_project/stylesheets/text.css
 
*********************************************************************
Congratulations! Your compass project has been created.
 
You may now add and edit sass stylesheets in the sass subdirectory of your project.
 
Sass files beginning with an underscore are called partials and will not be compiled to CSS, but they can be imported into other sass stylesheets.
 
You can configure your project by editing the config.rb configuration file. 
 
You must compile your sass stylesheets (.scss) into CSS when they change.
This can be done in one of the following ways:
  1. To compile on demand:
     compass compile [path/to/project]
  2. To monitor your project for changes and automatically recompile:
     compass watch [path/to/project]
 
More Resources:
  * Website: http://compass-style.org/
  * Sass: http://sass-lang.com
  * Community: http://groups.google.com/group/compass-users/
 
 
Please see the 960 website for documentation:
 
    http://960.gs/
 
To import your new stylesheets add the following lines of HTML (or equivalent) to your webpage:
<head>
  <link href="/stylesheets/grid.css" media="screen, projection" rel="stylesheet" type="text/css" />
  <link href="/stylesheets/text.css" media="screen, projection" rel="stylesheet" type="text/css" />
</head>

Ya está el proyecto creado. Vamos a echar un vistazo a los ficheros que se han creado en C:\Users\miguelm\my_project:

C:\Users\miguelm\my_project>dir
29/11/2011  09:47    <DIR>          .
29/11/2011  09:47    <DIR>          ..
29/11/2011  09:47    <DIR>          .sass-cache
29/11/2011  09:47               908 config.rb
29/11/2011  09:47    <DIR>          sass
29/11/2011  09:47    <DIR>          stylesheets

En la carpeta sass tenemos los ficheros SIN compilar y en la carpeta stylesheets los ficheros compilados. Los settings del proyecto se pueden modificar editando el archivo config.rb. Por ejemplo, puedes indicar cuál es el images_dir o el output_style (si deseas CSS comprimido o sin comprimir), por ejemplo:

...
images_dir = "public/images"
output_style = :compressed

Para hacer el desarrollo más cómodo y que compass detecte y auto-compile los ficheros “al vuelo”, vamos a ejecutar:

compass watch my_project

Y ya podemos empezar a editar los ficheros de /sass/*.scss
Por ejemplo, voy comentando los contenidos de sass/grid.scss:

 
// importa los resets y algunas cosas básicas del grid
@import "compass/reset";
@import "960/grid";
 
// Hay tres versiones del célebre 960.gs, en 12, 16 y 24 columnas (el que usaremos en el siguiente ejemplo)
.container_12 {
  @include grid-system(12); }
 
.container_16 {
  @include grid-system(16); }
 
// La mayoría de nosotros estamos acostumbrados a diseñar layouts algo más semánticos (por ejemplo, dos columnas, con header y footer)
$ninesixty-columns: 24;
 
// El contenedor de todo será de clase two-column
.two-column {
 
  // La siguiente línea indica que queremos CENTRAR el contenedor
  @include grid-container;
 
  // Comenzamos a describir nuestros id's...
  #header, #footer {
    @include grid(24); }
  #sidebar {
    @include grid(8); }
  #main-content {
    @include grid(16); } }

Vamos a hacer una prueba creando el archivo de markup para este CSS:

<!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" />
<link href="./stylesheets/grid.css" media="screen, projection" rel="stylesheet" type="text/css" />
<link href="./stylesheets/text.css" media="screen, projection" rel="stylesheet" type="text/css" />
 
<title>My Project</title>
</head>
 
<body>
	<div class="two-column">
    	  <div id="header">
        	This is the header
          </div>
          <div id="main-content">
        	This is main-content
          </div>
          <div id="sidebar">
        	This is sidebar
    	  </div>
          <div id="footer">
        	This is footer
    	  </div>  
    </div>
</body>
</html>

Con el markup anterior vemos que nuestro contenedor será de la clase “two-column” y estará dividido en 24 columnas.

Tanto el header como el footer tienen 24 columnas (@include grid(24);), es decir, ocuparán los 960px de ancho.

La barra lateral (#sidebar) ocupará 8 columnas (@include grid(8);) y la zona del contenido, 16 columnas (@include grid(16);).

Nótese que el total de columnas será SIEMPRE igual al valor del parámetro $ninesixty-columns (24, en este caso).

Para que veamos mejor el grid, voy a poner color negro de fondo a todos los div (y el texto en blanco). Para ello simplemente añado al archivo grid.scss las líneas 14 a 16:

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
/* 960 Grid System ~ Core CSS.
 * Learn more ~ http://960.gs/
 * *
 * Licensed under GPL and MIT. */
 
@import "compass/reset";
@import "960/grid";
 
// The following generates the default grids provided by the css version of 960.gs
.container_12 {
  @include grid-system(12); 
}
 
.container_16 {
  @include grid-system(16); 
}
 
// But most compass users prefer to construct semantic layouts like so (two column layout with header and footer):
 
$ninesixty-columns: 24;
 
*div{
	background: #000;
	color: #fff;
}
 
.two-column {
 
  @include grid-container;
 
  #header, #footer {
    @include grid(24); 
 
  }
  #sidebar {
    @include grid(8); 
  }
  #main-content {
    @include grid(16);
  } 
}

Guardamos el fichero.

Si nos fijamos en la consola que teníamos abierta, donde tecleamos compass wathc my_project veremos que ha detectado los cambios y sobreescrito grid.css.

>>> Change detected to: grid.scss
overwrite my_project/stylesheets/grid.css

Al ver el ejemplo en nuestro navegador, observaremos algo tal que:

Es feo, pero es un comienzo. Sigamos.

Compass alpha y omega: Ajustando márgenes entre elementos

Por defecto los bloques están separados 20px (cada uno tiene un margin de 10px). Podemos eliminar el margen entre elementos o bien al principio (@include alpha;) o bien al final (@include omega;) de los mismos.

Por ejemplo, para eliminar el margen al final de nuestro div main-content, añadimos @include omega; en el mismo…o añadimos @include alpha; en el sidebar.

...
#sidebar {
    @include grid(8); 
    @include alpha;
}
...

A continuación vamos a ver cómo sería un diseño en tres columnas usando 960 gs para Compass:

/* This is grid.scss */
 
@import "compass/reset";
@import "960/grid";
 
// The following generates the default grids provided by the css version of 960.gs
.container_12 {
  @include grid-system(12); 
}
 
.container_16 {
  @include grid-system(16); 
}
 
// But most compass users prefer to construct semantic layouts like so (two column layout with header and footer):
 
$ninesixty-columns: 24;
 
*div{
	background: #000;
	color: #fff;
}
 
.three-column {
 
  @include grid-container;
 
  #header, #footer {
    @include grid(24); 
 
  }
 
  #left-sidebar{
  	@include grid(4);
  }
 
  #right-sidebar {
    @include grid(4); 
  }
 
  #main-content {
    @include grid(16);
  } 
 
}

Y el marcado:

<!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" />
<link href="./stylesheets/grid.css" media="screen, projection" rel="stylesheet" type="text/css" />
<link href="./stylesheets/text.css" media="screen, projection" rel="stylesheet" type="text/css" />
<title>My Project</title>
</head>
<body>
	<div class="three-column">  
    	<div id="header">
        	This is the header
        </div>
        <div id="left-sidebar">
        	This is left
        </div>
        <div id="main-content">
        	This is main-content
        </div>
        <div id="right-sidebar">
        	This is right
    	</div>
        <div id="footer">
             This is the footer                                      
    	</div>
    </div>
</body>
</html>

Explorando más posibilidades

En el README del compass-960-plugin leemos:

To create a grid system using only CSS, use the following semantic grid mixins:
 
    Use the +grid-container mixin to declare your container element.
    Use the +grid(N, columns, gutter-width) mixin to declare a grid element.
    Use the +alpha and +omega mixins to declare the first and last grid elements for a row.
    Use the +grid-prefix(N, columns) and +grid-suffix(N, columns) mixins to add empty grid columns before or after a grid element.
    Use the +grid-push(N, columns) and +grid-pull(N, columns) mixins to move a grid element from its default position.
 
N is the number of grid columns to span as in grid_N or push_N with the original 960 Grid System framework.

Además de las ya exploradas @include grid(N) encontramos una forma útil de crear espacios negativos (vacíos) en el layout con @include grid-prefix(N,cols) y @include grid-suffix(N,cols).

Por ejemplo, vamos a crear una segunda fila en la que desplacemos 1 columna hacia la derecha el layout:

/* 960 Grid System ~ Core CSS.
 * Learn more ~ http://960.gs/
 * *
 * Licensed under GPL and MIT. */
 
@import "compass/reset";
@import "960/grid";
 
// The following generates the default grids provided by the css version of 960.gs
.container_12 {
  @include grid-system(12); 
}
 
.container_16 {
  @include grid-system(16); 
}
 
// But most compass users prefer to construct semantic layouts like so (two column layout with header and footer):
 
$ninesixty-columns: 24;
 
*div{
	background: #000;
	color: #fff;
}
 
.three-column {
 
  @include grid-container;
 
  #header, #footer {
    @include grid(24); 
 
  }
 
  #left-sidebar{
  	@include grid(4);
  }
 
  #right-sidebar {
    @include grid(4); 
  }
 
  #main-content {
    @include grid(16);
  } 
 
  #left-sidebar-2{
  	@include grid(4);
        // extiendo 1 columna hacia la derecha de 24 totales...
        // Nótese que sigue sumando 24: 4(grid)+1(extensión)+3(right)+16(main-content2)
	@include grid-suffix(1,24);
  }
 
  #right-sidebar-2 {
    @include grid(3); 
  }
 
  #main-content-2 {
    @include grid(16);
  } 
}

Y la salida que obtendremos:

En próximos posts, haremos algún ejemplo real de uso de Compass :)

vBulletin 4: Disable plugin/mod per style [SOLVED]

Suppose you install a new vBulletin 4 plugin that affects all your styles. For instance, the Subforum maganer plugin I talked about some days ago.

This Subforum manager plugin does NOT work with the mobile style included in vBulletin 4.1.8.

If the mod has an on/off switch, then you can write a plugin to turn off the mod when using styleid xx. You can use the hook location style_fetch for that. If the mod doesn’t have an on/off switch, then you will need to put a condition around the modification plugins themselves to turn them off for styleid xx.

For instance, my mobile styleid is styleid=6 (if I type mysite.com/?styleid=6) I see the mobile theme.

Looking at the XML file for the product I want to disable for mobile style I notice this line which indicates there is indeed an option for activating/desactivating this product, $vbulletin->options['sub_forum_manager']

<stylevardfns>
	</stylevardfns>
	<stylevars>
	</stylevars>
	<plugins>
		<plugin active="1" executionorder="5">
			<title>Sub-forum Manager (FORUMDISPLAY)</title>
			<hookname>forumdisplay_complete</hookname>
			<phpcode><![CDATA[if ( $vbulletin->options['sub_forum_manager'] )

I want to disable the product ‘Hasann – Sub-Forum Manager’ for styleid=6 so I write a new plugin like this:

Product: Hassan - Sub-Forum-Manager
Hook: style_fetch
Title: DisableHassanForMobileStyle
Order: 1
PHP Code:
if ($styleid == 6){
  $vbulletin->options['sub_forum_manager'] = 0;
}
Active plugin: YES

Job done!

vBulletin 4: Añadir páginas custom

Imagina que quieres añadir a tu foro vBulletin una página con código HTML/PHP custom pero utilizando el sistema de plantillas de vBulletin. Para verlo, nada mejor que un ejemplo. Vamos a añadir una página de ‘Reglamento’ a nuestro foro.

Estos son los pasos que debes seguir:

Creación del fichero reglamento.php

Generamos un fichero llamado reglamento.php y lo subimos a la carpeta raiz de nuestro servidor. El contenido será tal que asi (sustituye ‘reglamento’ por el titulo de tu pagina. Ojo! Es case-sensitive)

<?php
 
// ####################### SET PHP ENVIRONMENT ###########################
error_reporting(E_ALL & ~E_NOTICE);
 
// #################### DEFINE IMPORTANT CONSTANTS #######################
 
define('THIS_SCRIPT', 'reglamento');
define('CSRF_PROTECTION', true);  
// change this depending on your filename
 
// ################### PRE-CACHE TEMPLATES AND DATA ######################
// get special phrase groups
$phrasegroups = array();
 
// get special data templates from the datastore
$specialtemplates = array();
 
// pre-cache templates used by all actions
$globaltemplates = array('reglamento',
);
 
// pre-cache templates used by specific actions
$actiontemplates = array();
 
// ######################### REQUIRE BACK-END ############################
// if your page is outside of your normal vb forums directory, you should change directories by uncommenting the next line
// chdir ('/path/to/your/forums');
require_once('./global.php');
 
// #######################################################################
// ######################## START MAIN SCRIPT ############################
// #######################################################################
 
$navbits = construct_navbits(array('' => 'Politica de privacidad'));
$navbar = render_navbar_template($navbits);
 
// ###### YOUR CUSTOM CODE GOES HERE #####
$pagetitle = 'Reglamento (titulo de mi página custom)';
 
 
 
 
// ###### NOW YOUR TEMPLATE IS BEING RENDERED ######
 
$templater = vB_Template::create('reglamento');
$templater->register_page_templates();
$templater->register('navbar', $navbar);
$templater->register('pagetitle', $pagetitle);
print_output($templater->render());
 
?>

Creación de nueva plantilla (template)

Vamos al AdminControl Panel: ACP > Estilos y Plantillas > Administrar estilos, veremos el nombre del estilo que estamos utilizando en ese instante y en el desplegeable de la derecha pulsamos en ‘Añadir nueva plantilla’.

Nuestra plantilla se va a llamar ‘reglamento’ (el mismo nombre que le dimos antes dentro del fichero reglamento.php).

Pegamos el código de la plantilla, donde irá la parte del custom HTML/PHP:

{vb:stylevar htmldoctype}
<html xmlns="http://www.w3.org/1999/xhtml" dir="{vb:stylevar textdirection}" lang="{vb:stylevar languagecode}" id="vbulletin_html">
  <head>
    <title>{vb:raw vboptions.bbtitle} - {vb:raw pagetitle}</title>
    {vb:raw headinclude}
    {vb:raw headinclude_bottom}
  </head>
  <body>
 
    {vb:raw header}
 
    {vb:raw navbar}
 
    <div id="pagetitle">
      <h1>{vb:raw pagetitle}</h1>
    </div>
 
    <h2 class="blockhead">Reglamento de mi foro vBulletin 4</h2>
    <div class="blockbody">
      <div class="blockrow">
        <!-- AQUI EMPIEZA EL CUSTOM CODE -->
 
        <!-- /AQUI TERMINA EL CUSTOM CODE -->
      </div>
    </div>
 
    {vb:raw footer}
  </body>
</html>

Creación de plugins

A continuación creamos dos plugins: ACP > Plugins y productos > Agregar nuevo plugin

Crearemos uno llamado plugincustom1 con Ubicación de Enganche = online_location_process (curiosa traducción de hook) con el siguiente contenido y nos aseguraremos de marcarlo como activo:

switch ($filename)
{
    case 'reglamento.php':
        $userinfo['activity'] = 'Reglamento';
        break;
// add more cases here if you have more than one custom page. no need for multiple plugins. one plugin can handle all.
}

A continuación crearemos el plugincustom2 con Ubicación de enganche = online_location_unknown con el siguiente contenido y nos aseguramos de marcarlo como activo:

switch ($userinfo['activity'])
{
    case 'Reglamento':
        $userinfo['where'] = '<a href="reglamento.php?'.$vbulletin->session->vars[sessionurl].'">Reglamento</a>';
        $userinfo['action'] = "Reglamento de mi foro vBulletin";
        $handled = true;
        break;
// add more cases here if you have more than one custom page. no need for multiple plugins. one plugin can handle all.
}

Creación del enlace

Llegados a este punto ya podemos probar la URL de nuestro reglamento: http://www.misitioweb.com/reglamento.php debería funcionarnos. En este punto modificaremos la plantilla del punto 2 y meteremos nuestro custom code en ‘reglamento’.

A continuación querremos enlazar esta nueva página. Para ello, vamos a suponer que queremos enlazarla desde el menú de pie de página (gestionado por la plantilla footer) o la barra de navegación superior (gestionado por la plantilla navbar).

Si, por ejemplo, deseamos añadirlo a la barra de navegación: ACP > Estilos y plantillas > Administrar Estilos y en el desplegable de la derecha, elegiremos Editar plantillas, desplegamos ‘Navigation breadcrumb Plantillas‘ y seleccionamos ‘navbar‘.

Buscamos:

{vb:raw template_hook.navtab_end}

Y lo cambiamos por:

<!-- nueva pestaña en navbar -->
  <vb:if condition="THIS_SCRIPT == 'reglamento'">
     <li class="selected"><a class="navtab" href="reglamento.php">Reglamento</a></li>
  <vb:else />
     <li><a class="navtab" href="reglamento.php">Reglamento</a></li>
  </vb:if>  
<!-- /nueva pestaña reglamento -->
 
{vb:raw template_hook.navtab_end}

Y ya está :)

Paypal donate

Please help me keep this blog up by donating.

Por favor, ayúdame a continuar con el blog donando.