<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>
<channel>
	<title>Jorge Iván Meza Martínez &#187; CMS</title>
	<atom:link href="http://blog.jorgeivanmeza.com/tag/cms/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.jorgeivanmeza.com</link>
	<description>The Fire Within Me: &#34;knowledge will set you free&#34;</description>
	<lastBuildDate>Thu, 22 Jul 2010 06:31:20 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=8066</generator>
		<item>
		<title>Integración de una autenticación externa con los foros de Simple Machines 1.1.11</title>
		<link>http://blog.jorgeivanmeza.com/2010/05/integracion-de-una-autenticacion-externa-con-los-foros-de-simple-machines-1-1-11/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=integracion-de-una-autenticacion-externa-con-los-foros-de-simple-machines-1-1-11</link>
		<comments>http://blog.jorgeivanmeza.com/2010/05/integracion-de-una-autenticacion-externa-con-los-foros-de-simple-machines-1-1-11/#comments</comments>
		<pubDate>Mon, 10 May 2010 20:59:12 +0000</pubDate>
		<dc:creator>jimezam</dc:creator>
				<category><![CDATA[Software]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Autenticación]]></category>
		<category><![CDATA[CMS]]></category>
		<category><![CDATA[CodeIgniter]]></category>
		<category><![CDATA[Foros]]></category>
		<category><![CDATA[Hipergalaxia]]></category>
		<category><![CDATA[Integración]]></category>
		<category><![CDATA[PHP]]></category>
		<guid isPermaLink="false">http://blog.jorgeivanmeza.com/?p=2429</guid>
		<description><![CDATA[Introducción. La situación es la siguiente, se cuenta con un CMS desarrollado en PHP bajo el framework de CodeIgniter con su propio sistema de autenticación en el que se almacenan los usuarios de la siguiente manera. CREATE TABLE IF NOT EXISTS `core_usuario` ( `id_usuario` int(11) unsigned NOT NULL auto_increment, `estado` enum(&#8216;activo&#8217;,'inactivo&#8217;) NOT NULL, `_username` varbinary(16) [...]]]></description>
			<content:encoded><![CDATA[<h2>Introducción.</h2>
<p>La situación es la siguiente, se cuenta con un CMS desarrollado en <a href="http://php.net/" target="_blank">PHP</a> bajo el <em>framework</em> de <a href="http://codeigniter.com/" target="_blank">CodeIgniter</a> con su propio sistema de autenticación en el que se almacenan los usuarios de la siguiente manera.</p>
<p><span style="font-family: courier new,courier;">CREATE TABLE IF NOT EXISTS `<strong>core_usuario</strong>` (<br />
<strong> `id_usuario` int(11) unsigned NOT NULL auto_increment,</strong><br />
<strong>`estado` enum(&#8216;activo&#8217;,'inactivo&#8217;) NOT NULL,<br />
</strong><strong> `_username` varbinary(16) NOT NULL,<br />
`_password` varbinary(32) NOT NULL,<br />
`nombres` varchar(50) NOT NULL,<br />
`apellidos` varchar(50) NOT NULL,<br />
</strong>`fecha_nacimiento` date default NULL,<br />
`tipo_documento` enum(&#8216;cc&#8217;,'ce&#8217;,'ti&#8217;,'nit&#8217;) NOT NULL,<br />
`documento_identidad` varchar(12) NOT NULL,<br />
`genero` enum(&#8216;m&#8217;,'f&#8217;) NOT NULL,<br />
`correo` varchar(255) NOT NULL,<br />
`pagina` varchar(255) default NULL,<br />
`observaciones` varchar(255) default NULL,<br />
`fecha_creacion` datetime NOT NULL,<br />
`fecha_actualizacion` datetime NOT NULL,<br />
PRIMARY KEY  (`id_usuario`),<br />
);</span></p>
<p>En el sitio se ha instalado un foro basado en la versión 1.1.11 de <a href="http://www.simplemachines.org/" target="_blank">Simple Machines</a> el cual comparte la base de datos con el CMS.  Se necesita encontrar la forma de unificar los nombres de los usuarios y las contraseñas para tener una única identificación para la autenticación en los dos sistemas.</p>
<p>Para hacer esto se utiliza el API de <a href="http://docs.simplemachines.org/index.php?topic=400.0" target="_blank">SSI</a> de SMF de la siguiente manera.</p>
<h2>Hooks de integración.</h2>
<p>SMF provee una facilidad para alterar el ciclo de flujo del software mediante la manipulación de <em>hooks</em> que se agregan a etapas específicas del programa para modificar su comportamiento por defecto.  En este caso nos interesa crear un <em>hook</em> sobre el punto <a href="http://www.simplemachines.org/community/index.php?topic=173483.msg1106028#msg1106028" target="_blank"><span style="font-family: courier new,courier;">integrate_validate_login</span></a> ya que ese es el punto exacto en que SMF va a realizar la validación de los usuarios durante su autenticación.</p>
<p>Para implementar esto se crea un archivo llamado <span style="font-family: courier new,courier;">jimhook.php</span> (el nombre es arbitrario) con el siguiente contenido inicial.</p>
<pre class="php">&lt;?php
define('SMF_INTEGRATION_SETTINGS', serialize(array(
    'integrate_validate_login' =&gt; 'user_validate',
)));
require_once('SSI.php');
function user_validate()
{
    // Implementación de la lógica de la nueva autenticación.
}
?&gt;</pre>
<p>Estos <em>hooks</em> deben asociarse al sistema de foros agregando la siguiente línea al inicio del archivo <span style="font-family: courier new,courier;">index.php</span>.</p>
<pre class="php">include_once("jimhook.php");</pre>
<h2>Conexión a la base de datos.</h2>
<p>Como se mencionó inicialmente el CMS fue desarrollado en CodeIngniter y en este caso, comparte la base de datos con los foros.  El primer paso es obtener la información de conexión a la base de datos desde los archivos de configuración del CMS.</p>
<pre class="php">define('BASEPATH', 1);
include('../pt/system/application/config/database.php');</pre>
<p>Teniendo esta información se realiza una conexión global a la base de datos utilizando las funciones de PDO.</p>
<pre class="php">$pdo = null;
try
{
    $pdo = new PDO("mysql:host={$db['default']['hostname']};dbname={$db['default']['database']}",
                   $db['default']['username'],
                   $db['default']['password'],
                   array(PDO::MYSQL_ATTR_INIT_COMMAND =&gt; "SET NAMES utf8")
    );
}
catch (PDOException $e)
{
    print "Error!: " . $e -&gt; getMessage() . "&lt;br/&gt;";
    die();
}</pre>
<h2>Funciones de apoyo del CMS.</h2>
<p>Se crean algunas funciones básicas que servirán de soporte para el nuevo procedimiento de autenticación.</p>
<pre class="php">function existeUsuarioEnPlataforma($usuario)
{
    global $pdo;
    $stmt = $pdo -&gt; prepare("SELECT id_usuario FROM `usuarios` WHERE user=?");
    $results = $stmt -&gt; execute(array($usuario));
    return ($stmt -&gt; rowCount() &gt; 0);
}</pre>
<p>Verifica si el usuario identificado por el nombre de usuario (<span style="font-family: courier new,courier;">$usuario</span>) existe o no registrado en el CMS.  Retorna <span style="font-family: courier new,courier;">true</span> o <span style="font-family: courier new,courier;">false</span> según se encuentren o no efectivamente registrados.</p>
<pre class="php">function autenticarUsuarioEnPlataforma($usuario, $contrasena)
{
    global $pdo;
    $stmt = $pdo -&gt; prepare("SELECT id_usuario FROM `usuarios` WHERE user=? AND pass=?");
    $results = $stmt -&gt; execute(array($usuario, MD5($contrasena)));
    return ($stmt -&gt; rowCount() &gt; 0);
}</pre>
<p>Verifica que el usuario identificado con el nombre de usuario (<span style="font-family: courier new,courier;">$usuario</span>) tenga efectivamente a <span style="font-family: courier new,courier;">$contraseña</span> como clave de usuario.  Retorna <span style="font-family: courier new,courier;">true</span> en caso de coincidir, <span style="font-family: courier new,courier;">false</span> de lo contrario.</p>
<p>Nótese como el CMS almacena sus contraseñas en <a href="http://co.php.net/md5" target="_blank">MD5</a> motivo por el cual es necesario realizar esta conversión antes de realizar la comparación en la consulta SQL.</p>
<h2>Funciones de apoyo de los foros.</h2>
<p>De manera análoga, estas funciones facilitan la manipulación de la información en las tablas del sistema de foros, las cuales tienen configurado el prefijo <span style="font-family: courier new,courier;">foros_</span> en sus tablas.</p>
<pre class="php">function existeUsuarioEnForos($usuario)
{
    global $pdo;
    $stmt = $pdo -&gt; prepare("SELECT ID_MEMBER FROM foros_members WHERE memberName = ?");
    $results = $stmt -&gt; execute(array($usuario));
    if($stmt -&gt; rowCount() == 0)
        return false;
    $fuente = $stmt -&gt; fetch();
    return $fuente['ID_MEMBER'];
}</pre>
<p>Verifica si el usuario identificado por el nombre de usuario (<span style="font-family: courier new,courier;">$usuario</span>) existe o no registrado en el foro .  Retorna el identificador del usuario si existe o <span style="font-family: courier new,courier;">false</span> de lo contrario.</p>
<pre class="php">function traerUsuario($usuario, $contrasena)
{
    global $pdo, $sourcedir, $modSettings;
    if(!existeUsuarioEnPlataforma($usuario))
        return false;
    $stmt = $pdo -&gt; prepare("SELECT * FROM `usuarios` WHERE user=?");
    $results = $stmt -&gt; execute(array($usuario));
    $fuente = $stmt -&gt; fetch();
    require_once($sourcedir . '/Subs-Members.php');
    $regOptions = array('username' =&gt; $fuente['user'],
                        'password' =&gt; $contrasena,
                        'password_check' =&gt; $contrasena,
                        'email' =&gt; $fuente['email'],
                        'posts' =&gt; '0',
                        'ID_GROUP' =&gt; '0',
                        'ID_POST_GROUP' =&gt; '4');
    $memberID = registerMember($regOptions);
    return ($memberID &gt; 0);
}</pre>
<p>Obtiene la información del usuario de plataforma identificado por <span style="font-family: courier new,courier;">$usuario</span> y <span style="font-family: courier new,courier;">$contrasena</span>, y lo agrega en la base de datos del foro a través de su API interno.  A este nivel no se realiza ninguna verificación de autenticación.</p>
<pre class="php">function activarUsuarioForo($usuario, $estado='1')
{
    global $pdo;
    $stmt = $pdo -&gt; prepare("UPDATE foros_members SET is_activated = ? WHERE memberName = ?");
    $control = $stmt -&gt; execute(array($estado, $usuario));
    return $control;
}</pre>
<p>Activa al usuario del foro recién creado, el cual por defecto siempre queda en espera de confirmación (<span style="font-family: courier new,courier;">is_activated = 3</span>).</p>
<pre class="php">function actualizarContrasenaForo($usuario, $contrasena)
{
    global $pdo;
    $passwd       = sha1(strtolower($usuario) . $contrasena);
    $passwordSalt = substr(md5(mt_rand()), 0, 4);
    $stmt = $pdo -&gt; prepare("UPDATE foros_members SET passwd = ?, passwordSalt = ? WHERE memberName = ?");
    $control = $stmt -&gt; execute(array($passwd, $passwordSalt, $usuario));
    return $control;
}</pre>
<p>Actualiza la <span style="font-family: courier new,courier;">$contrasena</span> del <span style="font-family: courier new,courier;">$usuario</span> en el sistema de foros.  Nótese como la <span style="font-family: courier new,courier;">$contrasena</span> se recibe de manera plana y se almacena en la base de datos de SMF en <a href="http://co.php.net/sha1" target="_blank">SHA1</a>.</p>
<h2>Acerca del comportamiento del <em>login</em> de SMF.</h2>
<p>Algo que se debe tener en cuenta acerca del comportamiento del <em>login </em>de SMF es que desde el cliente (navegador del usuario) se envía la contraseña ya en su propia representación SHA1 así que si la contraseña con que se va a comparar no está en la misma representación, como en este caso, el CMS la almacena en MD5, se tiene entonces un problema.</p>
<p>Para solventar esto, el sistema de foros permite solicitar nuevamente la contraseña al usuario (<em>retry</em>) y en este segundo intento la envía totalmente plana para su manipulación libre.  En este punto es donde la aprovechamos para verificar la autenticación del usuario contra la información del CMS, crear el usuario en el foro si no existe y actualizar la contraseña en el foro previniendo que haya sido actualizada antes en el CMS.</p>
<h2>Implementación del nuevo proceso de autenticación.</h2>
<pre class="php">function user_validate()
{
    $user = $_REQUEST['user'];
    $id   = 0;
    // Verificar un usuario proveniente de plataforma.
    if(existeUsuarioEnPlataforma($user))
    {
        $id = existeUsuarioEnForos($user);
        // Nueva lógica de autenticación.
    }
    // El usuario no existe en plataforma, verificar los nativos del foro.
    return false;
}</pre>
<p>La base de la nueva autenticación es entonces la definición de la función <span style="font-family: courier new,courier;">user_validate</span> que corresponde con la especificada inicialmente durante la configuración de los <em>hooks</em>.</p>
<p>En ella se verifica inicialmente si el usuario que intenta acceder al sistema (<em>login</em>) se encuentra presente o no en la base de datos de usuarios del CMS.  En caso de no estar presente el control de la autenticación se libera para que el sistema verifique sus usuarios propios, esto permite definir también usuarios internos del foro que no estén presentes en el CMS.</p>
<p>El paso siguiente consiste en determinar si el usuario existe previamente o no en el foro, es decir, no es su primer ingreso al mismo.  A partir de esta respuesta se toma uno de los siguientes caminos.</p>
<ul>
<li>Si no está disponible la contraseña plana (primer <em>login</em>) se solicita nuevamente (segundo <em>login</em>).</li>
<li>Si el usuario no existe en el foro entonces ...
<ul>
<li>Se verifica que el nombre de usuario y la contraseña coincidan.</li>
<li>Se crea el usuario en el foro.</li>
<li>Se activa al nuevo usuario.</li>
</ul>
</li>
<li>Si el usuario ya existía previamente en el foro entonces ...
<ul>
<li>Se verifica que el nombre de usuario y la contraseña coincidan.</li>
<li>Se actualiza la contraseña en el foro por si ha sido actualizada previamente en el CMS.</li>
</ul>
</li>
</ul>
<p>La implementación de estas acciones se detalla a continuación.  En el caso en que el usuario no exista previamente en el foro se ejecuta la siguiente lógica del negocio.</p>
<pre class="php">if($id === false)
{
    // Esta disponible la contrasena (2do. login).
    if(isset($_REQUEST['passwrd']) &amp;&amp; !empty($_REQUEST['passwrd']))
    {
        $auth = autenticarUsuarioEnPlataforma($user, $_REQUEST['passwrd']);
        if($auth)                           // La informacion del usuario es valida.
        {
            $id = traerUsuario($user, $_REQUEST['passwrd']);
            activarUsuarioForo($user);
            return false;                   // La autenticacion tiene EXITO.
        }
        else                                // La informacion del usuario NO es valida.
            return true;                    // La autenticacion FALLA.
    }
    else                                    // No esta disponible la contrasena (1er. login).
        return "retry";                     // Vuelva a solicitar el login para confirmar.
}</pre>
<p>En el caso en que el usuario si exista previamente en el foro, el procedimiento es mas simple y se ejecuta  la siguiente lógica del negocio.</p>
<pre class="php">// El usuario existe en el foro.
if($id !== false)
{
    // Esta disponible la contrasena (2do. login) -&gt; actualizar la contraseña en el foro.
    if(isset($_REQUEST['passwrd']) &amp;&amp; !empty($_REQUEST['passwrd']))
    {
        $auth = autenticarUsuarioEnPlataforma($user, $_REQUEST['passwrd']);
        if($auth)                           // La informacion del usuario es valida.
        {
            actualizarContrasenaForo($user, $_REQUEST['passwrd']);
            return false;                   // La autenticacion tiene EXITO.
        }
        else                                // La informacion del usuario NO es valida.
            return true;                    // La autenticacion FALLA.
    }
    else                                    // No esta disponible la contrasena (1er. login).
        return "retry";                     // Vuelva a solicitar el login para confirmar.
}</pre>
<h2>Conclusiones.</h2>
<p>Hasta ahora, con poca experiencia en su uso, SMF parece ser un sistema de foros útil y práctico.  El proceso de determinar esta unificación de la autenticación fue largo y doloroso debido a la poca documentación que pude encontrar acerca del API, la cual en su mayor parte se encuentra diseminada en los foros de su sitio web.</p>
<p>En términos de su código parece tener un nivel decente de flexibilidad, el concepto de <em>hooks</em> permite realizar modificaciones interesantes al flujo normal del software, sin embargo es difícil formalizarlo al no contar con información suficiente de su lógica de funcionamiento.  Algunas partes del software, en especial los temas, adolecen de separación MVC por lo que se hace necesario editar funciones, entre comillas, que retornan el código HTML que se desea modificar siendo esto molesto, difícil y propenso a errores, sobretodo si se compara con tener archivos PHP separados con la lógica y HTML con la presentación como sería una mejor opción.</p>
<p>Finalmente, después de varios días de luchas y de pruebas, la unificación de la autenticación está funcionando y se ve bien, de todas maneras es mi primer acercamiento a este software por lo que no puedo garantizar que sea la mejor aproximación.  Como siempre, estoy abierto a sugerencias constructivas.</p>
<h2>Enlaces.</h2>
<ul>
<li>Simple Machines.<br />
<a href="http://www.simplemachines.org/" target="_blank">http://www.simplemachines.org/</a></p>
<ul>
<li>A guide to the SMF integration hooks.<br />
<a href="http://www.simplemachines.org/community/index.php?topic=173483.0" target="_blank">http://www.simplemachines.org/community/index.php?topic=173483.0</a></li>
</ul>
</li>
<li>CodeIgniter.<br />
<a href="http://codeigniter.com/" target="_blank">http://codeigniter.com/</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.jorgeivanmeza.com/2010/05/integracion-de-una-autenticacion-externa-con-los-foros-de-simple-machines-1-1-11/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Como obtener los nodos de un tipo específico en Drupal 6 desde API</title>
		<link>http://blog.jorgeivanmeza.com/2009/08/como-obtener-los-nodos-de-un-tipo-especifico-en-drupal-6-desde-api/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=como-obtener-los-nodos-de-un-tipo-especifico-en-drupal-6-desde-api</link>
		<comments>http://blog.jorgeivanmeza.com/2009/08/como-obtener-los-nodos-de-un-tipo-especifico-en-drupal-6-desde-api/#comments</comments>
		<pubDate>Tue, 25 Aug 2009 14:08:43 +0000</pubDate>
		<dc:creator>jimezam</dc:creator>
				<category><![CDATA[Desarrollo de software]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[CMS]]></category>
		<category><![CDATA[Drupal]]></category>
		<category><![CDATA[Hipergalaxia]]></category>
		<category><![CDATA[PHP]]></category>
		<guid isPermaLink="false">http://blog.jorgeivanmeza.com/?p=1994</guid>
		<description><![CDATA[Introducción. En algunos casos puede ser útil obtener desde un fragmento de código PHP utilizando el API oficial, los nodos de un portal basado en Drupal 6 que correspondan con un tipo específico (file, story, event, page, ...).  Esto se puede hacer fácilmente de la siguiente manera. Procedimiento. Obtener el listado con la información general [...]]]></description>
			<content:encoded><![CDATA[<h2>Introducción.</h2>
<p>En algunos casos puede ser útil obtener desde un fragmento de código PHP utilizando el API oficial, los nodos de un portal basado en Drupal 6 que correspondan con un tipo específico (<em>file</em>, <em>story</em>, <em>event</em>, <em>page</em>, ...).  Esto se puede hacer fácilmente de la siguiente manera.</p>
<h2>Procedimiento.</h2>
<p>Obtener el listado con la información general de los nodos del tipo específico.  Para esto se consulta la tabla <span style="font-family: courier new,courier;">node</span> que contiene la siguiente información de los nodos.</p>
<p style="padding-left: 30px;"><span style="font-family: courier new,courier;">nid         int(10)           # ID del nodo.<br />
vid         int(10)           # ID de la versión del nodo.<br />
type        varchar(32)       # Tipo del nodo.<br />
title       varchar(255)      # Título.<br />
uid         int(11)           # ID del propietario.<br />
status      int(11)           # Estado (publicado = 1; sin publicar/oculto = 0)<br />
created     int(11)           # Timestamp de la creación del nodo.<br />
changed     int(11)           # Timestamp de la modificación del nodo.<br />
comment     int(11)           # Estado de comentarios (desactivados = 0; sólo lectura = 1; activados = 2).<br />
promote     int(11)           # Promocionado a la página principal (no = 0; si = 1).<br />
moderate    int(11)           # Moderado </span><span style="font-family: courier new,courier;">(no = 0; si = 1).</span><br />
<span style="font-family: courier new,courier;">sticky      int(11)           # Pegajoso </span><span style="font-family: courier new,courier;">(no = 0; si = 1).</span><br />
<span style="font-family: courier new,courier;">language    varchar(12)       # Código del idioma.<br />
tnid        int(10)<br />
translate   int(11)</span></p>
<p>La consulta básica se puede realizar de la siguiente manera.</p>
<pre class="php">$sql = "SELECT nid
        FROM {node}
        WHERE type = 'TIPO_DE_NODO' AND
              status = 1
        ORDER BY created DESC";
$results = db_query($sql);</pre>
<p>Posteriormente se iteran los resultados obtenidos de la consulta y se carga la información completa de cada uno de los nodos.</p>
<pre class="php">while ($result = db_fetch_object($results))
{
    $node = node_load($result -&gt; nid);
}</pre>
<p>El contenido del nodo recuperado dependerá en cierta medida de los módulos instalados que alteran su estructura.  Para mostrar por ejemplo el título, la fecha de creación, el mensaje y la fecha de modificación de una noticia se utiliza el siguiente fragmento.</p>
<pre class="php">echo 'Titulo: ' . $node -&gt; title . '&lt;br /&gt;';
echo 'Fecha: ' . format_date($node-&gt;created) . '&lt;br /&gt;';
echo 'Mensaje: ' . $node-&gt;body . '&lt;br /&gt;&lt;br /&gt;&lt;hr /&gt;&lt;br /&gt;';
echo 'changed on: ' . format_date($node-&gt;changed, 'custom', 'Y-m-d H:i:s O') . '&lt;br /&gt;';</pre>
<h2>Enlaces.</h2>
<ul>
<li>Headless Drupal: Using Drupal’s API to Batch Script Your Drupal Site.<br />
<a href="http://www.stonemind.net/blog/2009/01/20/headless-drupal-using-drupals-api-to-batch-script-your-drupal-site/" target="_blank">http://www.stonemind.net/blog/2009/01/20/headless-drupal-using-drupals-api-to-batch-script-your-drupal-site/</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.jorgeivanmeza.com/2009/08/como-obtener-los-nodos-de-un-tipo-especifico-en-drupal-6-desde-api/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Mejorando la creación de contenido traducido con Drupal 6</title>
		<link>http://blog.jorgeivanmeza.com/2009/08/mejorando-la-creacion-de-contenido-traducido-con-drupal-6/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=mejorando-la-creacion-de-contenido-traducido-con-drupal-6</link>
		<comments>http://blog.jorgeivanmeza.com/2009/08/mejorando-la-creacion-de-contenido-traducido-con-drupal-6/#comments</comments>
		<pubDate>Wed, 19 Aug 2009 22:02:52 +0000</pubDate>
		<dc:creator>jimezam</dc:creator>
				<category><![CDATA[Software]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[CMS]]></category>
		<category><![CDATA[Drupal]]></category>
		<category><![CDATA[i18n]]></category>
		<guid isPermaLink="false">http://blog.jorgeivanmeza.com/?p=1985</guid>
		<description><![CDATA[Además de los pasos realizados para la configuración y edición del contenido traducido en Drupal 6 recientemente he instalado algunos módulos adicionales que permiten mayor flexibilidad en su mantenimiento como el hecho de tener una barra para cambiar el idioma desplegado, controlar que nodo es la traducción a otro idioma de otro, cuales idiomas ya [...]]]></description>
			<content:encoded><![CDATA[<p>Además de los pasos realizados para la configuración y edición del <a href="http://blog.jorgeivanmeza.com/2009/06/creacion-de-contenido-traducido-en-drupal-6/" target="_blank">contenido traducido en Drupal 6</a> recientemente he instalado algunos módulos adicionales que permiten mayor flexibilidad en su mantenimiento como el hecho de tener una barra para cambiar el idioma desplegado, controlar que nodo es la traducción a otro idioma de otro, cuales idiomas ya han sido traducidos de un nodo, traducción de partes del portal como cadenas, taxonomía y encuestas, y mostrar la versión original de un nodo si el idioma requerido aún no se encuentra disponible.</p>
<p>Los siguientes módulos requieren que los idiomas del sitio se encuentren definidos (<span style="font-family: courier new,courier;">?q=admin/settings/language</span>) y que el <em>Language Negotiation</em> (<span style="font-family: courier new,courier;">?q=admin/settings/language/configure</span>) deba ser <em>Path prefix only</em> o <em>Path prefix with language fall-back</em>.</p>
<ul>
<li><strong>Language Interface</strong><br />
<a href="http://drupal.org/project/languageinterface" target="_blank">http://drupal.org/project/languageinterface</a></li>
<li><strong>Active Translation</strong><br />
<a href="http://drupal.org/project/active_translation" target="_blank">http://drupal.org/project/active_translation</a></li>
<li><strong>Translation overview</strong><br />
<a href="http://drupal.org/project/translation_overview" target="_blank">http://drupal.org/project/translation_overview</a></li>
<li><strong>Internationalization</strong><br />
<a href="http://drupal.org/project/i18n" target="_blank">http://drupal.org/project/i18n</a></li>
</ul>
<div id="_mcePaste" style="overflow: hidden; position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px;">?q=admin/settings/language/configure</div>
]]></content:encoded>
			<wfw:commentRss>http://blog.jorgeivanmeza.com/2009/08/mejorando-la-creacion-de-contenido-traducido-con-drupal-6/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Personalizar el formulario de login en Drupal 6</title>
		<link>http://blog.jorgeivanmeza.com/2009/08/personalizar-el-formulario-de-login-en-drupal-6/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=personalizar-el-formulario-de-login-en-drupal-6</link>
		<comments>http://blog.jorgeivanmeza.com/2009/08/personalizar-el-formulario-de-login-en-drupal-6/#comments</comments>
		<pubDate>Tue, 18 Aug 2009 15:44:49 +0000</pubDate>
		<dc:creator>jimezam</dc:creator>
				<category><![CDATA[Software]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[CMS]]></category>
		<category><![CDATA[Drupal]]></category>
		<category><![CDATA[Hipergalaxia]]></category>
		<category><![CDATA[PHP]]></category>
		<guid isPermaLink="false">http://blog.jorgeivanmeza.com/?p=1981</guid>
		<description><![CDATA[Procedimiento. Editar el archivo template.php y agregar la siguiente función (el nombre es libre). function phptemplate_generarFormularioLogin() { $form_id = 'user_login'; $form = array(); $form['name'] = array( '#type' =&#62; 'textfield', '#maxlength' =&#62; USERNAME_MAX_LENGTH, '#required' =&#62; TRUE, '#attributes' =&#62; array('tabindex' =&#62; '1', 'class' =&#62; 'registro'), ); $form['pass'] = array( '#type' =&#62; 'password', '#required' =&#62; TRUE, '#attributes' =&#62; [...]]]></description>
			<content:encoded><![CDATA[<h2>Procedimiento.</h2>
<p>Editar el archivo <span style="font-family: courier new,courier;">template.php</span> y agregar la siguiente función (el nombre es libre).</p>
<pre class='php'>function phptemplate_generarFormularioLogin()
{
   $form_id = 'user_login';
   $form = array();
   $form['name'] = array(
      '#type' =&gt; 'textfield',
      '#maxlength' =&gt; USERNAME_MAX_LENGTH,
      '#required' =&gt; TRUE,
      '#attributes' =&gt; array('tabindex' =&gt; '1',
      'class' =&gt; 'registro'),
   );
   $form['pass'] = array(
      '#type' =&gt; 'password',
      '#required' =&gt; TRUE,
      '#attributes' =&gt; array('tabindex' =&gt; '2',
      'class' =&gt; 'registro'),
   );
   $form['submit'] = array(
      '#type' =&gt; 'submit',
      '#value' =&gt; t('Log in'),
      '#weight' =&gt; 2,
      '#attributes' =&gt; array('tabindex' =&gt; '3')
   );
   $form['#validate'] = user_login_default_validators();
   $form['#build_id'] = sprintf('form-%s', md5(uniqid(mt_rand(), TRUE)));
   $form_state = array();
   drupal_prepare_form($form_id, $form, $form_state);
   drupal_process_form($form_id, $form, $form_state);
   $out = new stdClass;
   $out-&gt;form_start = sprintf("&lt;form method='post' accept-charset='UTF-8' action='%s'&gt;",
                             url('user/login'));
   $out-&gt;form_end = "&lt;/form&gt;";
   $out-&gt;name = drupal_render($form['name']);
   $out-&gt;pass = drupal_render($form['pass']);
   $out-&gt;submit = drupal_render($form['form_id']) .
   drupal_render($form['form_build_id']) .
   drupal_render($form['submit']);
   return $out;
}</pre>
<p>Insertar en el lugar deseado de <span style="font-family: courier new,courier;">page.tpl.php</span> el siguiente fragmento de código o su correspondiente personalización.</p>
<pre class="php">&lt;?php $login_form = phptemplate_generarFormularioLogin(); ?&gt;
&lt;?php print $login_form -&gt; form_start; ?&gt;
    Usuario &amp;nbsp; &lt;?php print $login_form-&gt;name; ?&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;
    Contraseña &amp;nbsp; &lt;?php print $login_form-&gt;pass; ?&gt;&amp;nbsp;&amp;nbsp;
    &lt;?php print $login_form-&gt;submit; ?&gt;
&lt;?php print $login_form-&gt;form_end; ?&gt;</pre>
<h2>Enlaces.</h2>
<ul>
<li>Theming the Drupal 6 User Login Form.<br />
<a href="http://thefaultandfracture.blogspot.com/2009/04/theming-drupal-user-login-form.html" target="_blank">http://thefaultandfracture.blogspot.com/2009/04/theming-drupal-user-login-form.html</a></li>
<li>Customizing the login form.<br />
<a href="http://drupal.org/node/19855" target="_blank">http://drupal.org/node/19855</a></li>
<li>Modifying Forms in Drupal 5 and 6.<br />
<a href="http://www.lullabot.com/articles/modifying-forms-5-and-6" target="_blank">http://www.lullabot.com/articles/modifying-forms-5-and-6</a></li>
<li>10 tips for theming Drupal 6 forms.<br />
<a href="http://www.advomatic.com/blogs/amanda-luker/10-tips-theming-drupal-6-forms" target="_blank">http://www.advomatic.com/blogs/amanda-luker/10-tips-theming-drupal-6-forms</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.jorgeivanmeza.com/2009/08/personalizar-el-formulario-de-login-en-drupal-6/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Personalizar el formulario de búsqueda en un tema de Drupal 6</title>
		<link>http://blog.jorgeivanmeza.com/2009/08/personalizar-el-formulario-de-busqueda-en-un-tema-de-drupal-6/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=personalizar-el-formulario-de-busqueda-en-un-tema-de-drupal-6</link>
		<comments>http://blog.jorgeivanmeza.com/2009/08/personalizar-el-formulario-de-busqueda-en-un-tema-de-drupal-6/#comments</comments>
		<pubDate>Thu, 13 Aug 2009 20:57:10 +0000</pubDate>
		<dc:creator>jimezam</dc:creator>
				<category><![CDATA[Software]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[CMS]]></category>
		<category><![CDATA[Drupal]]></category>
		<category><![CDATA[Hipergalaxia]]></category>
		<category><![CDATA[PHP]]></category>
		<guid isPermaLink="false">http://blog.jorgeivanmeza.com/?p=1968</guid>
		<description><![CDATA[Introducción. En algunas ocasiones no es suficiente con el bloque de búsquedas de Drupal y es necesario incluír un formulario de búsquedas en la plantilla del tema con un estilo muy específico. Las búsquedas en Drupal utilizan un sistema de llaves o claves para impedir que sean consumidas desde fuera del sitio, así que escribir [...]]]></description>
			<content:encoded><![CDATA[<h2>Introducción.</h2>
<p>En algunas ocasiones no es suficiente con el bloque de búsquedas de Drupal y es necesario incluír un formulario de búsquedas en la plantilla del tema con un estilo muy específico.</p>
<p>Las búsquedas en Drupal utilizan un sistema de llaves o claves para impedir que sean consumidas desde fuera del sitio, así que escribir un formulario propio con el <span style="font-family: courier new,courier;">action</span> direccionado no es una buena alternativa.</p>
<h2>Implementación.</h2>
<ol>
<li>Activar el formulario de búsquedas en el tema.
<ol>
<li>Acceda el menú de administración de temas (<span style="font-family: courier new,courier;">?q=admin/build/themes</span>).</li>
<li>Haga clic sobre el enlace <strong>Configurar</strong> frente al tema elegido.</li>
<li>Seleccione la casilla <strong>Bloque de búsqueda</strong>.</li>
<li>Presione el botón <strong>Guardar configuración</strong>.</li>
</ol>
</li>
<li>Copie el archivo <span style="font-family: courier new,courier;">modules/search/search-<strong>block</strong>-form.tpl.php</span> a la carpeta del tema con el nombre <span style="font-family: courier new,courier;">search-<strong>theme</strong>-form.tpl.php</span>.</li>
<li>Edite <span style="font-family: courier new,courier;">page.tpl.php</span> del tema e incluya la etiqueta <span style="font-family: courier new,courier;">&lt;?php print $search_box; ?&gt;</span> donde desee que aparezca el campo de búsqueda en el tema.</li>
<li>Edite el archivo <span style="font-family: courier new,courier;">search-theme-form.tpl.php</span> con el formulario de búsqueda personalizado.
<ol>
<li>No es necesario incluír las etiquetas <span style="font-family: courier new,courier;">&lt;form&gt;</span> ya que estas se incluyen automáticamente.</li>
<li>El <span style="font-family: courier new,courier;">ID</span> del formulario generado es <span style="font-family: courier new,courier;">search-theme-form</span>.</li>
<li>El ID del campo de las palabras clave deberá ser <span style="font-family: courier new,courier;">edit-search-theme-form-1</span>.</li>
<li>El nombre del campo de las palabras clave deberá ser <span style="font-family: courier new,courier;">search_theme_form</span>.</li>
<li>Incluya esta etiqueta en cualquier lugar del archivo <span style="font-family: courier new,courier;">&lt;?= $search['hidden']; ?&gt;</span>.</li>
</ol>
</li>
</ol>
<h2>Enlaces.</h2>
<ul>
<li>Customizing the search forms.<br />
<a href="http://drupal.org/node/45295" target="_blank">http://drupal.org/node/45295</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.jorgeivanmeza.com/2009/08/personalizar-el-formulario-de-busqueda-en-un-tema-de-drupal-6/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Como crear nuevas regiones en Drupal 6</title>
		<link>http://blog.jorgeivanmeza.com/2009/08/como-crear-nuevas-regiones-en-drupal-6/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=como-crear-nuevas-regiones-en-drupal-6</link>
		<comments>http://blog.jorgeivanmeza.com/2009/08/como-crear-nuevas-regiones-en-drupal-6/#comments</comments>
		<pubDate>Wed, 12 Aug 2009 16:52:42 +0000</pubDate>
		<dc:creator>jimezam</dc:creator>
				<category><![CDATA[Software]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[CMS]]></category>
		<category><![CDATA[Drupal]]></category>
		<category><![CDATA[Hipergalaxia]]></category>
		<category><![CDATA[PHP]]></category>
		<guid isPermaLink="false">http://blog.jorgeivanmeza.com/?p=1960</guid>
		<description><![CDATA[Introducción. Las regiones en Drupal permiten la ubicación de los bloques en la página.  Su distribución se realiza generalmente en el archivo page.tpl.php del tema. Por defecto se incluyen las siguientes regiones. Columna izquierda (left). Columna derecha (right). Contenido central (content). Cabecera (header). Pies de página (footer). Agregar nuevas regiones al tema. Es posible según [...]]]></description>
			<content:encoded><![CDATA[<h2>Introducción.</h2>
<p>Las regiones en Drupal permiten la ubicación de los bloques en la página.  Su distribución se realiza generalmente en el archivo <span style="font-family: courier new,courier;">page.tpl.php</span> del tema.</p>
<p>Por defecto se incluyen las siguientes regiones.</p>
<ol>
<li>Columna izquierda (<span style="font-family: courier new,courier;">left</span>).</li>
<li>Columna derecha (<span style="font-family: courier new,courier;">right</span>).</li>
<li>Contenido central (<span style="font-family: courier new,courier;">content</span>).</li>
<li>Cabecera (<span style="font-family: courier new,courier;">header</span>).</li>
<li>Pies de página (<span style="font-family: courier new,courier;">footer</span>).</li>
</ol>
<h2>Agregar nuevas regiones al tema.</h2>
<p>Es posible según la complejidad del tema que sea necesario agregar nuevas regiones para manipular la distribución del contenido del sitio con mayor precisión y granularidad.</p>
<p>Hasta la versión 5 de Drupal esto se realizaba sobreescribiendo la <a href="http://blog.jorgeivanmeza.com/2007/08/crear-nuevas-secciones-en-pagetpl-de-drupal/" target="_blank">función <span style="font-family: courier new,courier;">phptemplate_regions()</span> del archivo <span style="font-family: courier new,courier;">template.php</span></a>, sin embargo este estilo de configuración fue modificado para las versiones 6 y posteriores.</p>
<p>Ahora la configuración de las regiones se realiza en el archivo <span style="font-family: courier new,courier;">TEMA.info</span> de la siguiente manera.</p>
<p><span style="font-family: courier new,courier;">regions[left] = Columna izquierda<br />
regions[right] = Columna derecha<br />
regions[content] = Contenido<br />
regions[header] = Cabecera<br />
regions[footer] = Pies de pagina<br />
<strong>regions[menu] = Menu horizontal</strong><br />
</span></p>
<h2>Enlaces.</h2>
<ul>
<li>Regiones, estructura del archivo <span style="font-family: courier new,courier;">.info</span>.<br />
<a href="http://drupal.org/node/171205#regions" target="_blank">http://drupal.org/node/171205#regions</a></li>
<li>Crear nuevas secciones en page.tpl de Drupal.<br />
<a href="http://blog.jorgeivanmeza.com/2007/08/crear-nuevas-secciones-en-pagetpl-de-drupal/" target="_blank">http://blog.jorgeivanmeza.com/2007/08/crear-nuevas-secciones-en-pagetpl-de-drupal/</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.jorgeivanmeza.com/2009/08/como-crear-nuevas-regiones-en-drupal-6/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Cómo determinar si el usuario se encuentra autenticado en Drupal</title>
		<link>http://blog.jorgeivanmeza.com/2009/08/como-determinar-si-el-usuario-se-encuentra-autenticado-en-drupal/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=como-determinar-si-el-usuario-se-encuentra-autenticado-en-drupal</link>
		<comments>http://blog.jorgeivanmeza.com/2009/08/como-determinar-si-el-usuario-se-encuentra-autenticado-en-drupal/#comments</comments>
		<pubDate>Wed, 12 Aug 2009 16:26:24 +0000</pubDate>
		<dc:creator>jimezam</dc:creator>
				<category><![CDATA[Software]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[CMS]]></category>
		<category><![CDATA[Drupal]]></category>
		<category><![CDATA[PHP]]></category>
		<guid isPermaLink="false">http://blog.jorgeivanmeza.com/?p=1958</guid>
		<description><![CDATA[En algunas ocasiones es necesario saber si el usuario que visita el portal basado en Drupal se encuentra autenticado o no en una sesión.  Particularmente útil para determinar que elementos de la interfaz de usuario pueden ser accedidos por usuarios anónimos y cuales deben ser accedidos sólo por usuarios autenticados. Esto se realiza gracias al [...]]]></description>
			<content:encoded><![CDATA[<p>En algunas ocasiones es necesario saber si el usuario que visita el portal basado en Drupal se encuentra autenticado o no en una sesión.  Particularmente útil para determinar que elementos de la interfaz de usuario pueden ser accedidos por usuarios anónimos y cuales deben ser accedidos sólo por usuarios autenticados.</p>
<p>Esto se realiza gracias al objeto <span style="font-family: courier new,courier;">$user</span> disponible durante la generación de las vistas de la siguiente manera.</p>
<pre class="php">global $user;
if($user -&gt; uid)
{
    // El usuario se encuentra autenticado y en sesión.
}
else
{
    // El visitante del portal es anónimo.
}</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.jorgeivanmeza.com/2009/08/como-determinar-si-el-usuario-se-encuentra-autenticado-en-drupal/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Personalizar las &#8220;migas de pan&#8221; en Drupal</title>
		<link>http://blog.jorgeivanmeza.com/2009/08/personalizar-las-migas-de-pan-en-drupal/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=personalizar-las-migas-de-pan-en-drupal</link>
		<comments>http://blog.jorgeivanmeza.com/2009/08/personalizar-las-migas-de-pan-en-drupal/#comments</comments>
		<pubDate>Wed, 12 Aug 2009 14:11:37 +0000</pubDate>
		<dc:creator>jimezam</dc:creator>
				<category><![CDATA[Software]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[CMS]]></category>
		<category><![CDATA[Drupal]]></category>
		<category><![CDATA[Hipergalaxia]]></category>
		<category><![CDATA[PHP]]></category>
		<guid isPermaLink="false">http://blog.jorgeivanmeza.com/?p=1954</guid>
		<description><![CDATA[Introducción. Las &#8220;migas de pan&#8221; o breadcrumbs es aquella sección de los sitios web que lleva un registro jerárquico de los niveles del sitio que se han visitado permiténdonos regresar a través de ellos de manera asíncrona.  Un ejemplo de breadcrumbs podría ser este. Inicio &#62; Software &#62; Web. Esto significaría que se está en [...]]]></description>
			<content:encoded><![CDATA[<h2>Introducción.</h2>
<p>Las &#8220;migas de pan&#8221; o <em>breadcrumbs</em> es aquella sección de los sitios web que lleva un registro jerárquico de los niveles del sitio que se han visitado permiténdonos regresar a través de ellos de manera asíncrona.  Un ejemplo de <em>breadcrumbs</em> podría ser este.</p>
<p style="padding-left: 30px;">Inicio &gt; Software &gt; Web.</p>
<p>Esto significaría que se está en la sección Web que depende del Software y que pende del inicio del sitio.</p>
<h2><em>Breadcrumbs</em> en Drupal.</h2>
<p>Drupal provee automáticamente esta facilidad, él mismo va generando las &#8220;migas de pan&#8221; y las ubica donde se inserte la siguiente etiqueta, comúnmente en <span style="font-family: courier new,courier;">page.tpl.php</span>.</p>
<pre class="php">&lt;?php print $breadcrumb ?&gt;</pre>
<p>Por defecto Drupal se hace cargo de generar el contenido HTML asociado a las &#8220;migas de pan&#8221; con un estilo por defecto.  En algunas ocasiones este estilo no se adecúa a las necesidades propias.</p>
<h2>Personalizar las <em>breadcrumbs</em> en Drupal.</h2>
<p>Para hacer esto es necesario crear o editar el archivo <span style="font-family: courier new,courier;">template.php</span> ubicado en el tema activo y agregar o modificar la definición de la función <span style="font-family: courier new,courier;">phptemplate_breadcrumb($breadcrumb)</span> donde <span style="font-family: courier new,courier;">$breadcrumb</span> es un arreglo y cada una de sus celdas corresponde con un segmento de las &#8220;migas de pan&#8221;.</p>
<pre class="php">/**
 * Return a themed breadcrumb trail.
 *
 * @param $breadcrumb - An array containing the breadcrumb links.
 * @return a string containing the breadcrumb output.
 */
function phptemplate_breadcrumb($breadcrumb)
{
    if (empty($breadcrumb))
        return "";
    $str = "&lt;ul&gt;";
    $length = count($breadcrumb);
    for($i=0; $i&lt;$length; $i++)
    {
        $bc = $breadcrumb[$i];
        $class = ($i &lt; $length - 1) ? "" : "class='ruta_final'";
        $str .= "&lt;li {$class}&gt;{$bc}&lt;/li&gt;";
    }
    $str .= "&lt;/ul&gt;";
    return $str;
 }</pre>
<p>El ejemplo anterior crea las &#8220;migas de pan&#8221; como un UL donde cada LI corresponde con una sección visitada y cuya última sección tiene además una clase CSS llamada <span style="font-family: courier new,courier;">ruta_final</span>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.jorgeivanmeza.com/2009/08/personalizar-las-migas-de-pan-en-drupal/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Como referenciar las imagenes de un tema en Drupal</title>
		<link>http://blog.jorgeivanmeza.com/2009/08/como-referenciar-las-imagenes-de-un-tema-en-drupal/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=como-referenciar-las-imagenes-de-un-tema-en-drupal</link>
		<comments>http://blog.jorgeivanmeza.com/2009/08/como-referenciar-las-imagenes-de-un-tema-en-drupal/#comments</comments>
		<pubDate>Wed, 12 Aug 2009 13:52:24 +0000</pubDate>
		<dc:creator>jimezam</dc:creator>
				<category><![CDATA[Software]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[CMS]]></category>
		<category><![CDATA[Drupal]]></category>
		<category><![CDATA[Hipergalaxia]]></category>
		<guid isPermaLink="false">http://blog.jorgeivanmeza.com/?p=1949</guid>
		<description><![CDATA[Imágenes a partir de las hojas de estilo. Cuando se desarrolla un tema la mayoría de las imágenes quedan relacionadas a través de las hojas de estilos (CSS) sus rutas son relativas automáticamente al directorio del tema y se incluyen, al igual que los archivos Javascript, en el archivo *.info del tema. ; $Id: dm.info,v [...]]]></description>
			<content:encoded><![CDATA[<h2>Imágenes a partir de las hojas de estilo.</h2>
<p>Cuando se desarrolla un tema la mayoría de las imágenes quedan relacionadas a través de las hojas de estilos (CSS) sus rutas son relativas automáticamente al directorio del tema y se incluyen, al igual que los archivos Javascript, en el archivo <span style="font-family: courier new,courier;">*.info</span> del tema.</p>
<p style="padding-left: 30px;"><span style="font-family: courier new,courier;">; $Id: dm.info,v 0.1 2009/08/11 11:11:00 jimezam Exp $<br />
name = miTema<br />
description = Esta es la descripción del tema.<br />
version = 1.0<br />
core = 6.x<br />
engine = phptemplate</span></p>
<p style="padding-left: 30px;"><span style="font-family: courier new,courier;">stylesheets[all][] = css/style.css<br />
stylesheets[all][] = css/layout.css</span>
</p>
<p style="padding-left: 30px;"><span style="font-family: courier new,courier;">scripts[] = js/jquery-1.3.2.min.js</span></p>
<p>El ejemplo anterior hace que <span style="font-family: courier new,courier;">miTema</span> incluya automáticamente las hojas de estilo <span style="font-family: courier new,courier;">style.css</span> y <span style="font-family: courier new,courier;">layout.css</span> ubicadas bajo <span style="font-family: courier new,courier;">css/</span> y el archivo <span style="font-family: courier new,courier;">jquery-1.3.2.min.js</span> ubicado bajo <span style="font-family: courier new,courier;">js/</span>.  Esto se hace exactamente donde se inserten las siguientes etiquetas, normalmente ubicadas en el <span style="font-family: courier new,courier;">&lt;head&gt;</span> de <span style="font-family: courier new,courier;">page.tpl.php</span>.</p>
<pre class="php">&lt;?php print $styles; ?&gt;
&lt;?php print $scripts; ?&gt;</pre>
<h2>Imágenes estáticas directamente del tema.</h2>
<p>En otras ocasiones es necesario referenciar imágenes (<span style="font-family: courier new,courier;">&lt;img&gt;</span>) u otros recursos estáticos que se encuentran ubicados en el directorio del tema activo.  Para hacer esto se utiliza el método <a href="http://api.drupal.org/api/function/path_to_theme/6" target="_blank"><span style="font-family: courier new,courier;">path_to_theme</span></a> del API de Drupal.</p>
<p>Supongamos que se desea crear una imagen con el archivo <span style="font-family: courier new,courier;">Foto.png</span> que se encuentra ubicado en el directorio <span style="font-family: courier new,courier;">imagenes/</span> del tema activo.  Se debe utilizar la siguiente expresión.</p>
<pre class="php">&lt;img src="&lt;?php global $base_path; print $base_path.path_to_theme(); ?&gt;/imagenes/Foto.png" /&gt;</pre>
<p>Otra forma de hacerlo, con una sintaxis un poco mas resumida es utilizando las funciones directas que provee Drupal de la siguiente manera.</p>
<pre class="php">&lt;img src="&lt;?php print base_path() . path_to_theme(); ?&gt;/imagenes/Foto.png" /&gt;</pre>
<h2>Solución de problemas.</h2>
<p>A pesar de que no se encuentren activos los cachés de Drupal, algunas veces los cambios que se realizan en estos archivos de presentación no se reflejan cuando se refresca el sitio.  Para corregir este comportamiento es necesario limpiar el caché de datos del tema para que se generen nuevas versiones que incluyan los cambios recién realizados.</p>
<p>Para limpiar el caché de datos de Drupal inicie como administrador y acceda a la configuración de desempeño (<span style="font-family: courier new,courier;">?q=admin/settings/performance</span>).</p>
<p>Al final de la página presione el botón <span style="font-family: courier new,courier;">Clear cached data</span> y al terminar esta página refresque nuevamente el sitio web para observbar los cambios.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.jorgeivanmeza.com/2009/08/como-referenciar-las-imagenes-de-un-tema-en-drupal/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Actualización de portales web basados en Drupal a la versión 6.13</title>
		<link>http://blog.jorgeivanmeza.com/2009/07/actualizacion-de-portales-web-basados-en-drupal-a-la-version-6-13/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=actualizacion-de-portales-web-basados-en-drupal-a-la-version-6-13</link>
		<comments>http://blog.jorgeivanmeza.com/2009/07/actualizacion-de-portales-web-basados-en-drupal-a-la-version-6-13/#comments</comments>
		<pubDate>Mon, 13 Jul 2009 22:12:47 +0000</pubDate>
		<dc:creator>jimezam</dc:creator>
				<category><![CDATA[Software]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[CMS]]></category>
		<category><![CDATA[Drupal]]></category>
		<category><![CDATA[Hipergalaxia]]></category>
		<category><![CDATA[PHP]]></category>
		<guid isPermaLink="false">http://blog.jorgeivanmeza.com/?p=1886</guid>
		<description><![CDATA[Introducción. Después de actualizada la versión 5 del portal a la 6.12 o la instalación de una versión 6.x fresca, se hace necesario actualizar el portal a la nueva versión disponible, la 6.13. Procedimiento. Realizar la copia de seguridad de la base de datos del portal. Ingresar al portal con el usuario cuyo id = [...]]]></description>
			<content:encoded><![CDATA[<h2>Introducción.</h2>
<p>Después de <a href="http://blog.jorgeivanmeza.com/2009/06/migracion-de-drupal-5-a-la-version-6/" target="_blank">actualizada la versión 5 del portal a la 6.12</a> o la <a href="http://blog.jorgeivanmeza.com/2009/06/procedimiento-de-instalacion-basica-de-drupal-6/" target="_blank">instalación de una versión 6.x</a> fresca, se hace necesario actualizar el portal a la nueva versión disponible, la 6.13.</p>
<h2>Procedimiento.</h2>
<ol>
<li>Realizar la copia de seguridad de la base de datos del portal.</li>
<li>Ingresar al portal con el usuario cuyo id = 1.</li>
<li>Modificar  la configuración del sitio poniéndolo en modo administración: <span style="font-family: courier new,courier;">?q=admin/settings/site-maintenance</span>.</li>
<li>Actualizar los módulos disponibles según el módulo de <strong>update-status</strong>: <span style="font-family: courier new,courier;">?q=admin/reports/updates</span>.</li>
<li>Desactivar los módulos (<span style="font-family: courier new,courier;">?q=admin/build/modules</span>) y temas (<span style="font-family: courier new,courier;">?q=admin/build/themes</span>) de terceros.</li>
<li>Realizar la actualización de los archivos.
<ol>
<li><span style="font-family: courier new,courier;">$ wget http://ftp.drupal.org/files/projects/drupal-6.13.tar.gz</span></li>
<li><span style="font-family: courier new,courier;">$ rm site.old</span></li>
<li><span style="font-family: courier new,courier;">$ mv site site.old</span></li>
<li><span style="font-family: courier new,courier;">$ tar zxvf drupal-6.13.tar.gz</span></li>
<li><span style="font-family: courier new,courier;">$ mv drupal-6.13/ site</span></li>
<li><span style="font-family: courier new,courier;">$ cp -rf site.old/files site    <span style="font-family: times new roman,times;">(si no se utiliza la convención bajo</span> sites/default<span style="font-family: times new roman,times;">)</span>.<br />
</span></li>
<li><span style="font-family: courier new,courier;">$ cp -rf site.old/sites site</span></li>
<li><span style="font-family: courier new,courier;">(web) $URL/apps/site/update.php</span></li>
<li><span style="font-family: courier new,courier;">(web) $URL/?q=admin/reports/updates</span></li>
<li><span style="font-family: courier new,courier;">rm site/install.php site/CHANGELOG.txt site/INSTALL.txt site/INSTALL.mysql.txt site/INSTALL.pgsql.txt site/LICENSE.txt site/MAINTAINERS.txt site/UPGRADE.txt</span></li>
<li><span style="font-family: courier new,courier;">$ rm drupal-6.13.tar.gz </span></li>
</ol>
</li>
<li>Activar los módulos (<span style="font-family: courier new,courier;">?q=admin/build/modules</span>) y temas (<span style="font-family: courier new,courier;">?q=admin/build/themes</span>) de terceros.</li>
<li>Modificar  la configuración del sitio poniéndolo en línea nuevamente: <span style="font-family: courier new,courier;">?q=admin/settings/site-maintenance</span>.</li>
</ol>
<p>Con esta actualización se introducen las siguientes modificaciones al esquema de actualizaciones de Drupal que se había estado siguiendo hasta la fecha.</p>
<ul>
<li>Los archivos del usuario, diferentes a los de la distribución de Drupal, y a los cuales se les debe realizar copia de seguridad se encuentran en las siguientes ubicaciones.
<ul>
<li><span style="font-family: courier new,courier;">sites/all/libraries</span>.  Librerías que aplican a todos los sitios.</li>
<li><span style="font-family: courier new,courier;">sites/all/modules</span>.  Módulos de terceros que aplican a todos los sitios.</li>
<li><span style="font-family: courier new,courier;">sites/all/themes</span>.  Temas de terceros que aplican a todos los sitios.</li>
<li><span style="font-family: courier new,courier;">sites/default/files</span>.  Archivos de usuario de un sitio específico (<em>default</em>).</li>
<li><span style="font-family: courier new,courier;">sites/default/settings.php</span>.  Configuración de un sitio específico (<em>default</em>).</li>
</ul>
</li>
<li>Si no se utiliza la convención bajo <span style="font-family: courier new,courier;">sites</span> los directorios <span style="font-family: courier new,courier;">libraries</span>, <span style="font-family: courier new,courier;">modules</span>, <span style="font-family: courier new,courier;">themes</span> y <span style="font-family: courier new,courier;">files</span> se ubicarán en el directorio raíz de la distribución de Drupal, esto debe tenerse muy en cuenta ya que deberán agregarse como pasos durante la copia de seguridad y deberá tenerse extremo cuidado para evitar conflictos con los archivos del núcleo de la distribución que utilizan la mayoría de estos directorios.</li>
</ul>
<h2>Enlaces.</h2>
<ul>
<li>HowTo: Updating Drupal 6.x to newer minor version.<br />
<a href="http://drupal.org/node/390448" target="_blank">http://drupal.org/node/390448</a></li>
<li>Upgrading - more sophisticated approach.<br />
<a href="http://drupal.org/node/323089" target="_blank">http://drupal.org/node/323089</a></li>
<li>Setup of /sites directory for multi-site.<br />
<a href="http://drupal.org/node/53705" target="_blank">http://drupal.org/node/53705</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.jorgeivanmeza.com/2009/07/actualizacion-de-portales-web-basados-en-drupal-a-la-version-6-13/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
