Deja que tus usuarios elijan su propio estilo

Escrito por | 01 Julio 2014 | Publicado en Julio 2014
Imagina: Tu usuario se registra y elige la combinación de colores y estilos que desea tener cuando se loguee en tu sitio. No es nada complicado. Un pequeño plugin que explote el potencial de crear perfiles de usuarios, disponible a partir de j2.5 y unos cuantos archivos css nos pueden dar excelentes resultados.

Dentro de los servicios que puedes ofrecer a los usuarios de tu sitio está el dejar que ellos elijan de qué forma quieren ver el sitio cuando inician sesión. En este ejercicio vamos a tratar solo los colores, pero puedes generar toda clase de estilos, layouts personalizados, etc.

Para realizar este ejercicio vamos a usar la última versión de Joomla! 3.x con la plantilla “protostar”. En general son los mismos pasos para todas las plantillas, aunque quizá haya algunas plantillas comerciales que requieran un tratamiento diferente, para lo cual deberás consultar con el soporte de la plantilla que tengas.

Los pasos son los siguientes:

  1. Crear e instalar un plugin que guardará la preferencia del usuario y que permitirá que esta preferencia se pueda modificar al editar el perfil.
  2. Modificar el index.php de tu plantilla para que detecte el estilo de cada usuario y llame al archivo css que corresponda a cada estilo.
  3. Crear los archivos CSS con los estilos necesarios para cada opción. 

PRIMERO EL PLUGIN

En el siguiente link de la documentación oficial de Joomla encontrarás los pasos para generar un plugin que permite AGREGAR CAMPOS PERSONALIZADOS AL REGISTRO DE USUARIOS dentro de Joomla.

http://docs.joomla.org/Creating_a_profile_plugin

Los archivos que se proponen en este link los he modificado para los fines que nos convienen. Para hacerlo más práctico, no agregue los archivos de idioma pero es muy recomendable que los agregues.

Primero crea la siguiente estructura de archivos dentro de la carpeta “plugins/user/profile_style”. “profile_style” es como nombraremos a nuestro plugin.

  • profiles/profile.xml
  • index.html
  • profile_style.php
  • profile_style.xml

El archivo “profile.xml” dentro de la carpeta profiles, se encargará de plasmar el campo (o los campos, si decides agregar más de uno) que adicionaremos al perfil. Este es su contenido.

<?xml version="1.0" encoding="utf-8"?> 
<form>
        <fields name="profile_style">
                <fieldset name="profile_style"
                        label="Estilo favorito"
                >
                        <field
                                name="profile_style"
                                type="list"
                                id="profile_style"
                                description="Elije un estilo para el sitio"
                                label="Elije un estilo para el sitio ">
                                <option value="0">Original</option>
                                <option value="1">Verde</option>
                                <option value="2">Azul</option>
                                <option value="3">Rosa</option>
                        </field>
                </fieldset>
        </fields>
</form>

El archivo index.html permanece en blanco. Solo nos servirá como medio de control para que no se pueda acceder directamente a la carpeta del plugin. También vale la pena poner un archivo igual dentro de la carpeta “plugin”.

El archivo “profile_styile.php” es el que lleva toda la lógica de nuestro plugin. Está encargado de plasmar el campo dentro del formulario de registro y edición de perfil así como de registrar los cambios que realicemos al mismo. No ahondaré en detalles. En el link que indico arriba, encontrarás información detallada (en inglés) sobre su funcionamiento. Dejo los comentarios originales.

<?php
 /**
  * @version            
  * @copyright  Copyright (C) 2005 - 2010 Open Source Matters, Inc. All rights reserved.
  * @license            GNU General Public License version 2 or later; see LICENSE.txt
  */
 
 defined('JPATH_BASE') or die;
 
  /**
   * An example custom profile plugin.
   *
   * @package           Joomla.Plugins
   * @subpackage        user.profile
   * @version           1.6
   */
  class plgUserProfile_style extends JPlugin
  {
        /**
         * @param       string  The context for the data
         * @param       int             The user id
         * @param       object
         * @return      boolean
         * @since       1.6
         */
        function onContentPrepareData($context, $data)
        {
                // Check we are manipulating a valid form.
                if (!in_array($context, array('com_users.profile','com_users.registration','com_users.user','com_admin.profile'))){
                        return true;
                }
 
                $userId = isset($data->id) ? $data->id : 0;
 
                // Load the profile data from the database.
                $db = JFactory::getDbo();
                $db->setQuery(
                        'SELECT profile_key, profile_value FROM #__user_profiles' .
                        ' WHERE user_id = '.(int) $userId .
                        ' AND profile_key LIKE \'profile_style.%\'' .
                        ' ORDER BY ordering'
                );
                $results = $db->loadRowList();
 
                // Check for a database error.
                if ($db->getErrorNum()) {
                        $this->_subject->setError($db->getErrorMsg());
                        return false;
                }
 
                // Merge the profile data.
                $data->profile_style = array();
                foreach ($results as $v) {
                        $k = str_replace('profile_style.', '', $v[0]);
                        $data->profile_style[$k] = json_decode($v[1], true);
                }
 
                return true;
        }
 
        /**
         * @param       JForm   The form to be altered.
         * @param       array   The associated data for the form.
         * @return      boolean
         * @since       1.6
         */
        function onContentPrepareForm($form, $data)
        {
                // Load user_profile plugin language
                $lang = JFactory::getLanguage();
                $lang->load('plg_user_profile_style', JPATH_ADMINISTRATOR);
 
                if (!($form instanceof JForm)) {
                        $this->_subject->setError('JERROR_NOT_A_FORM');
                        return false;
                }
                // Check we are manipulating a valid form.
                if (!in_array($form->getName(), array('com_users.profile', 'com_users.registration','com_users.user','com_admin.profile'))) {
                        return true;
                }
                if ($form->getName()=='com_users.profile')
                {
                        // Add the profile fields to the form.
                        JForm::addFormPath(dirname(__FILE__).'/profiles');
                        $form->loadFile('profile', false);
 
                        // Toggle whether the profile_style field is required.
                        if ($this->params->get('profile-require_profile_style', 1) > 0) {
                                $form->setFieldAttribute('profile_style', 'required', $this->params->get('profile-require_profile_style') == 2, 'profile_style');
                        } else {
                                $form->removeField('profile_style', 'profile_style');
                        }
                }
 
                //In this example, we treat the frontend registration and the back end user create or edit as the same.
                elseif ($form->getName()=='com_users.registration' || $form->getName()=='com_users.user' )
                {               
                        // Add the registration fields to the form.
                        JForm::addFormPath(dirname(__FILE__).'/profiles');
                        $form->loadFile('profile', false);
 
                        // Toggle whether the profile_style field is required.
                        if ($this->params->get('register-require_profile_style', 1) > 0) {
                                $form->setFieldAttribute('profile_style', 'required', $this->params->get('register-require_profile_style') == 2, 'profile_style');
                        } else {
                                $form->removeField('profile_style', 'profile_style');
                        }
                }                       
        }
 
        function onUserAfterSave($data, $isNew, $result, $error)
        {
                $userId = JArrayHelper::getValue($data, 'id', 0, 'int');
 
                if ($userId && $result && isset($data['profile_style']) && (count($data['profile_style'])))
                {
                        try
                        {
                                $db = JFactory::getDbo();
                                $db->setQuery('DELETE FROM #__user_profiles WHERE user_id = '.$userId.' AND profile_key LIKE \'profile_style.%\'');
                                if (!$db->query()) {
                                        throw new Exception($db->getErrorMsg());
                                }
 
                                $tuples = array();
                                $order  = 1;
                                foreach ($data['profile_style'] as $k => $v) {
                                        $tuples[] = '('.$userId.', '.$db->quote('profile_style.'.$k).', '.$db->quote(json_encode($v)).', '.$order++.')';
                                }
 
                                $db->setQuery('INSERT INTO #__user_profiles VALUES '.implode(', ', $tuples));
                                if (!$db->query()) {
                                        throw new Exception($db->getErrorMsg());
                                }
                        }
                        catch (JException $e) {
                                $this->_subject->setError($e->getMessage());
                                return false;
                        }
                }
 
                return true;
        }
 
        /**
         * Remove all user profile information for the given user ID
         *
         * Method is called after user data is deleted from the database
         *
         * @param       array           $user           Holds the user data
         * @param       boolean         $success        True if user was succesfully stored in the database
         * @param       string          $msg            Message
         */
        function onUserAfterDelete($user, $success, $msg)
        {
                if (!$success) {
                        return false;
                }
 
                $userId = JArrayHelper::getValue($user, 'id', 0, 'int');
 
                if ($userId)
                {
                        try
                        {
                                $db = JFactory::getDbo();
                                $db->setQuery(
                                        'DELETE FROM #__user_profiles WHERE user_id = '.$userId .
                                        " AND profile_key LIKE 'profile_style.%'"
                                );
 
                                if (!$db->query()) {
                                        throw new Exception($db->getErrorMsg());
                                }
                        }
                        catch (JException $e)
                        {
                                $this->_subject->setError($e->getMessage());
                                return false;
                        }
                }
 
                return true;
        }
 
 
 }

Por último “profile_style.xml”. Es el archivo encargado de ayudarnos a parametrizar nuestro plugin. Si lo observas bien, verás que nos muestra las opciones para mostrar como obligatorio u opcional el campo al momento del registro o al editar el perfil.

<?xml version="1.0" encoding="utf-8"?>
        <!-- $Id:  -->
<extension version="3.1" type="plugin" group="user">
        <name>plg_user_profile_style</name>
        <author>Joomla! Project</author>
        <creationDate>January 2008</creationDate>
        <copyright>(C) 2005 - 2013 Open Source Matters. All rights reserved.</copyright>
        <license>GNU General Public License version 2 or later; see LICENSE.txt</license>
        <authorEmail>Esta dirección de correo electrónico está siendo protegida contra los robots de spam. Necesita tener JavaScript habilitado para poder verlo.</authorEmail>
        <authorUrl>www.joomla.org</authorUrl>
        <version>3.0.0</version>
        <description>Plugin para que el usuario elija su estilo favorito</description>
 
        <files>
                <filename plugin="profile_style">profile_style.php</filename>
                <filename>index.html</filename>
                <folder>profiles</folder>
        </files>
         <config>
                <fields name="params">
 
                        <fieldset name="basic">
                                <field name="register-require-user" type="spacer"
                                        label="Registro"
                                />
 
                                <field name="register-require_profile_style" type="list"
                                        description="Campo requerido"
                                        label="Campo requerido al registro"
                                >
                                        <option value="2">JOPTION_REQUIRED</option>
                                        <option value="1">JOPTION_OPTIONAL</option>
                                        <option value="0">JDISABLED</option>
                                </field>
 
                                <field name="profile-require-user" type="spacer"
                                        label="Editar perfil"
                                />
 
                                <field name="profile-require_profile_style" type="list"
                                        description="Campo requerido al editar perfil"
                                        label="Campo requerido"
                                >
                                        <option value="2">JOPTION_REQUIRED</option>
                                        <option value="1">JOPTION_OPTIONAL</option>
                                        <option value="0">JDISABLED</option>
                                </field>
 
                        </fieldset>
 
                </fields>
        </config>
 </extension>

Lo siguiente será instalar nuestro plugin. Una opción es comprimir nuestra carpeta en un archivo zip e instalarla de la forma normal utilizando el gestor de extensiones. Si creaste la carpeta, como lo indico arriba, dentro de la careta plugins de tu instalación de Joomla!, debes ir al gestor de extensiones y después en “descubrir”. Te aparecerá una lista con las extensiones disponibles para instalar, elijes el plugin “profile_style” y das clic en “instalar”. Lo siguiente será ir al gestor de plugins y activar el plugin que recién instalarmos. 

PASO 2, Modificar el index.php del template

Lo siguiente es ir a la carpeta “templates/protostar” y ubicar el archivo index.php. Por ahí de la línea 49 encontrarás el siguiente código:

// Add current user information
$user = JFactory::getUser(); 

Esta línea recopila la información del usuario que está logueado en ese mometo incluyendo el campo que genera nuestro plugin.

Justo debajo de esta línea agregaremos lo siguiente:

function get_style($userId){ //esta función recopila la información del estilo de perfil
                //abrir la base de datos
                $db = JFactory::getDbo();
                $db->setQuery(
                        'SELECT profile_key, profile_value FROM #__user_profiles' .
                        ' WHERE user_id = '.(int) $userId .
                        ' AND profile_key LIKE \'profile_style.%\'' .
                        ' ORDER BY ordering'
                );
                $results = $db->loadAssoc();
                $results1=explode('"',$results['profile_value']);
               // adquirir el estilo de perfil .
                $profile_style = $results1[1];
 
                return $profile_style;
}
if ($user->id>0) $profile_style=get_style($user->id); //usamos la función para obtener el estilo del perfil
if (isset($profile_style)>0) //validamos que el valor sea mayor a cero para aplicar el estilo necesario
$doc->addStyleSheet('templates/'.$this->template.'/css/profile_style'.$profile_style.'.css'); //incluímos el archivo css necesario  

Lo que hará este código es asegurarse de que tenemos el campo “profile_style” (donde sse almacenará la preferencia del usuario) disponible y de ser así indicamos con la función “addStyleSheet” que cargue el archivo css que corresponda. En nuestro caso cargará el archivo que comience con “template” más el valor del estilo que el usuario eligió y seguido de la extensión css.

PASO 3, los archivos css

Lo único que resta es agregar los archivos CSS para cada uno de los estilos que necesitemos, en nuestro caso, template1.css (para el color verde), template2.css (para el color azul) y template3.css (para el color rosa). Estos archivos debemos agregarlos dentro de la carpeta css de nuestro template. El código de cada archivo es el siguiente. Solo tenemos que modificar el color para cada caso.

body{
background-color: green !important; // camiar green por blue o pink;
}
a{
color: green !important;
}
h1,h2,h3,h4,h5{
color: green !important;
}
//Puedes agregar los estilos que necesites, media queries, etc.

Y listo. Ahora cada que el usuario se registre en el sitio verá algo como esto:

profile style1

Y dependiendo del color que el usuario elija, cuando se inicie sesión en el sitio podría ver algo como esto:

profile style2

Este plugin se puede usar también para agregar campos personalizados al perfil del usuario, lo que nos permitiría prescindir de otros componentes y hacer más limpia y ligera nuestra instalación de joomla. Con este detalle recibirás muchos aplausos de tus usuarios y les dara una mejor experiencia. Espero que te sea de utilidad y muchas gracias por tus comentarios e ideas.

Visto 3576 veces Etiquetado como Spanish, Desarrollador
Luciano Martínez

Luciano Martínez

Desde Ciudad de México. 

Licenciado en Sistemas de Computación Administrativa por la Universidad del Valle México. Programador php desde 2009 y usuario apasionado de Joomla! desde el mismo año. 

Desarrollo sitios web con Joomla desde el 2010. 

Actualmente participo activamente con recomendaciones y ayuda a otros usuarios dentro del JUG de la Ciudad de México en Facebook.

Mi objetivo dentro del Jooma Magazine es aportar artículos sobre las experiencias y retos que he tenido con Joomla y cómo, quizá de la manera menos elegante, he dado con una solución eficaz y que me ha dejado mucho aprendizaje. 

Al pertenecer a esta comunidad, también deseo aprender. Creo firmemente que el aprendizaje es el camino del éxito y es mejor si este aprendizaje es recíproco.