El desarrollo, promoción y uso de aplicaciones bajo la filosofía del Software libre es una de las metas de humanOS y es por eso que en nuestro blog pueden leerse temas relacionados con blender, android, wordpress y otro sinnúmero de temáticas que abordamos cotidianamente …siempre sin olvidar claro está, que en humanOS “le ayudamos a descubrir Ubuntu, NOVA y mucho más” 😉 …aclarado el punto, comenzamos!!

Toda aquella persona que en algún momento ha cacharreado (como se dice en el buen cubano) WordPress debe haberse percatado que es una excelente plataforma CMS para la publicación de contenidos. Personalmente hay cosas que no me gustan como por ejemplo: no usa el patrón MVC, no trae integrado un ORM y otras cosillas …nada, que parece que estoy usando mucho Symfony 🙂 …el próximo cambio es migrar a Symfony jejeje …creo que al jacko entonces si le da 😀

Calentando motores

Los menús son una parte fundamental de todo sitio web, puesto que les sirve a los usuarios del sitio como sistema de navegación entre los contenidos. Cuanto mejor estructurado sea el diseño del menú, más satisfactoria será la navegación para los usuarios. Hagamos las cosas fáciles para nuestros visitantes, lo van a agradecer (un consejo para todos los desarrolladores).

¿Cómo crear un menú para wordpress?

Crear un menú en wordpress es una tarea sencilla solo tienes que seguir los siguientes pasos:

Paso 1: Haz clic en Apariencia > Menú

wordpress-menu

Paso 2: Adiciona un nuevo menú desde el enlace “Create new menu” (en inglés la instalación)

wordpress-menu-new

Paso 3: Introduce el nombre y guarda los cambios

wordpress-menu-new-2

Paso 4: Adiciona los elementos deseados, esto pueden ser: Páginas, Enlaces personalizados, Categorías u otras

Paso 5: Ordena los elementos seleccionados para el menú con un simple “drag and drop” (arrastra y suelta)

Paso 6: Guarda los cambios realizados al menú

wordpress-menu-principal

Hasta aquí tenemos un menú básico de wordpress completamente funcional.

Personalizando el menú

IMPORTANTE: La complejidad de esta parte del tutorial es medio-alto por lo que el autor considera que se tienen conocimientos de HTML, CSS, jQuery, PHP y experiencia en el desarrollo para WordPress.

Para continuar con la personalización de nuestro menú es necesario activar en Opciones de pantalla las siguientes opciones avanzadas del menú.

wordpress-menu-options

¿Para qué vamos a usar estas opciones avanzadas? La respuesta es sencilla: con las clases CSS vamos a poder definir un icono por cada uno de los elementos del menú y con la Descripción pues, la descripción de cada uno de los elementos.

Una vez marcada estas opciones, un elemento del menú puede quedar de la siguiente manera:

wordpress-menu-item

NOTA: Para el desarrollo del tema de humanOS, aparte de Twitter Bootstrap usamos Font Awesome 3.2.1 para los iconos del blog. Font Awesome es una suite muy completa de iconos basados en letras …como su descripción lo indica “the iconic font designed for Bootstrap”.

Adicionando soporte para la Descripción y las Clases CSS en el menú

Por algún motivo que todavía desconozco, la descripción y las clases CSS no vienen soportadas en el tema Shoestrap …me parece que las clases CSS no la usan muchos temas de wordpress actualmente …el motivo, como antes dije, no lo se, pero si queremos que nuestro menú lo soporte solo tienes que realizar los siguientes cambios:

Incluyendo el valor del campo descripción

Los cambios que tenemos que realizar son sobre el fichero wp-content/themes/shoestrap/lib/nav.php y sustituir la clase Shoestrap_Nav_Walker por el siguiente código:

class Shoestrap_Nav_Walker extends Walker_Nav_Menu {
  function check_current($classes) {
    return preg_match('/(current[-_])|active|dropdown/', $classes);
  }

  function start_lvl(&$output, $depth = 0, $args = array()) {
    $output .= "\n
    \n"; } /** * Start the element output. * * @param string $output Passed by reference. Used to append additional content. * @param object $item Menu item data object. * @param int $depth Depth of menu item. May be used for padding. * @param array $args Additional strings. * @return void */ function start_el(&$output, $item, $depth = 0, $args = array(), $id = 0) { $item_html = ''; $classes = empty ( $item->classes ) ? array () : (array) $item->classes; for ($i=(count($classes) - 1); $i >= 0 ; $i--) { //para quitar la clase de los iconos de bootstrap $tmp = explode('icon-', $classes[$i]); if (count($tmp) == 2) { $classes[$i] = 'li-'.$classes[$i]; } } if (!empty ( $item->classes )) { // actualizando el listado de clases $item->classes = $classes; } parent::start_el($item_html, $item, $depth, $args); // insert description for top level elements only you may change this $description = ( ! empty ( $item->description ) and 0 == $depth ) ? '' : ''; if (!empty($description)) { $item_html = str_replace('', $description.'', $item_html); } if ($item->is_dropdown && ($depth === 0)) { $item_html = str_replace('', ' ', $item_html); } elseif (stristr($item_html, 'li class="divider')) { $item_html = preg_replace('/]*>.*?<\/a>/iU', '', $item_html); } elseif (stristr($item_html, 'li class="nav-header')) { $item_html = preg_replace('/]*>(.*)<\/a>/iU', '$1', $item_html); } $output .= $item_html; } function display_element($element, &$children_elements, $max_depth, $depth = 0, $args, &$output) { $element->is_dropdown = ((!empty($children_elements[$element->ID] ) && (($depth + 1 ) < $max_depth || ( $max_depth === 0 )))); if ($element->is_dropdown) { if ($depth === 0) { $element->classes[] = 'dropdown'; } elseif ($depth === 1) { $element->classes[] = 'dropdown-submenu'; } } parent::display_element($element, $children_elements, $max_depth, $depth, $args, $output); } }

Si usan una herramienta como meld para ver la diferencias entre archivos se pueden percatar que la función modificada es start_el; el cambio que hacemos es adicionar “li-” a la clase definida en la interfaz del menú en WordPress y adicionar la descripción definida.

Adicionando iconos a los elementos del menú

El uso del atributo clases CSS de WordPress puede ser tan variado como se desee (aquí puedes adicionar cualquier clase y mediante CSS personalizar cada uno de tus elementos del menú); en nuestro caso lo que queremos es adicionar un icono de Font Awesome distinto para cada uno de los elementos del menú. La solución que realicé a esta idea fue realizar lo siguiente:

Al dispararse el filtro nav_menu_link_attributes adicionar a $args->link_before la estructura HTML definida por Twitter Bootstrap y Font Awesome para los iconos …el código viene siendo el siguiente:

/**
 * Adicionando la estructura  delante del link si se le adiciono 
 * al menu una clase de boostrap
 */
function shoestrap_nav_menu_link_attributes($atts, $item, $args) {
    $classes = empty ( $item->classes ) ? array () : (array) $item->classes;
    $change = false;

    for ($i=(count($classes) - 1); $i >= 0 ; $i--) { //para quitar la clase de los iconos de bootstrap
      $tmp = explode('li-icon-', $classes[$i]);
      if (count($tmp) == 2) {
        $change = true;
        $args->link_before = ' ';
      }
    }

    if (!$change) {
      $args->link_before = '';
    }

    return $atts;
}
add_filter( 'nav_menu_link_attributes', 'shoestrap_nav_menu_link_attributes', 10, 3 );

Por supuesto, es posible que se pueda mejorar esta función o incluso buscar una mejor alternativa, pero esta funciona 😀

¿Dónde adiciono este código? Pues bueno, tienes dos opciones; puedes adicionarlo a tu fichero functions.php o seguir la misma lógica de Shoestrap y adicionarlo en wp-content/themes/shoestrap/lib/nav.php. Si vas a usar la segunda alternativa debes tener cuidado al actualizar automáticamente el tema puesto que perderías el cambio realizado. En mi caso, como no voy a hacer una actualización automática del tema y he tenido cuidado en los cambios que he realizado sobre el tema base, lo adicioné en el fichero nav.php.

Hasta aquí ya puedes tener un menú igual al que tiene nuestro blog, pero como dije antes, personalizaciones y mejores ideas pueden salir de estos códigos solo tienes que poner tu imaginación a trabajar 😉

¿Cómo hacer la parte de las opciones al lado del menú?

Bueno, esta parte ya no tiene mucho que ver con la personalización del menú pero como ya estamos hablando del tema, vamos a tocarlo también.

El diseño actual del blog viene definido para que el menú superior sea ancho y que sea fijo en la parte superior. Pues bueno, como gustos y colores hay muchos no todos nuestro lectores, por X o Y motivo, desean tener el menú ocupando ese espacio (en pantallas pequeñas el espacio es vital, por ejemplo). La solución fue bastante sencilla.

Buscamos el fichero wp-content/themes/shoestrap/templates/header-top-navbar.php y sustituimos el código:

por el siguiente:

Hacemos un poquito de magia negra con javascript 😀 y…

/*opciones del menu superior*/
        $('ul.nav-options li.menu-size a').click(function(e) {
            e.preventDefault();

            var $icon = $(this).find('i');
            if ($icon.hasClass('icon-resize-small')) {
                $('#banner').addClass('nav-small');
                $icon.removeClass().addClass('icon-resize-full');

                setCookieNav('1', null, null);
            } else {
                $('#banner').removeClass('nav-small');
                $icon.removeClass().addClass('icon-resize-small');

                setCookieNav('0', null, null);
            }
        });
        $('ul.nav-options li.menu-fixed a').click(function(e) {
            e.preventDefault();

            var $icon = $(this).find('i');
            if ($icon.hasClass('icon-remove')) {
                $('#banner').addClass('nav-no-fixed');
                $icon.removeClass().addClass('icon-pushpin');

                setCookieNav(null, '1', null);
            } else {
                $('#banner').removeClass('nav-no-fixed');
                $icon.removeClass().addClass('icon-remove');

                setCookieNav(null, '0', null);
            }
        });

        var hOS_nav = $.cookie('hOS_nav');
        if (hOS_nav != undefined) {
            hOS_nav = hOS_nav.split(':');
            if (hOS_nav[0] == 1) {
                $('ul.nav-options li.menu-size a').click();
            }
            if (hOS_nav[1] == 1) {
                $('ul.nav-options li.menu-fixed a').click();
            }
        }

        setTimeout(function() {
            $('#banner').css('opacity', 0).removeClass('hide').stop().animate( {'opacity':1}, {duration:600});
        }, 100);

        $('[data-toggle="tooltip"]').tooltip();
        $('li.menu-settings [data-toggle="popover"]').clickover({
            'title': 'Personaliza el blog',
            'content': '
', 'html': true, 'animation': true, 'placement': 'bottom', 'container': '#nav-main' }); $('#pre-wrap, #nav-main').on('click', 'ul.custom-theme li', function(evt){ var tmp = ($(this).attr('class')).split(' '); $(this).parent().find('li.active').removeClass('active'); $(this).addClass('active'); evt.preventDefault(); $( document.createElement('link') ).attr({ href: '/wp-content/themes/shoestrap/assets/css/custom/child-app-'+$.trim(tmp[0])+'.css', media: 'screen', type: 'text/css', rel: 'stylesheet' }).appendTo('head'); setCookieNav(null, null, $.trim(tmp[0])); }); var setCookieNav = function(resize, fixed, custom) { var cook = ($.cookie('hOS_nav')); if (cook != undefined) { cook = cook.split(':'); if (resize == null) { resize = cook[0]; } if (fixed == null) { fixed = cook[1]; } if (custom == null) { custom = (cook.length == 3) ? cook[2] : 'default'; } } else { resize = (resize != null) ? resize : '0'; fixed = (fixed != null) ? fixed : '0'; custom = (custom != null) ? custom : 'default'; } $.cookie('hOS_nav', resize+':'+fixed+':'+custom, { expires: 730, path: '/' }); }

Explicación del código

El primer fragmento del código js que define el evento clic sobre “ul.nav-options li.menu-size a” lo que hace es adicionar/quitar al #banner la clase CSS nav-small …los detalles de esta clase pueden verlo en el código CSS que se muestra al final.

Algo similar hacemos para el evento clic sobre “ul.nav-options li.menu-fixed a”, pero ahora adicionamos/quitamos la clase nav-no-fixed en #banner.

Todos estos cambios lo guardamos en una cookie que se llama hOS_nav que guarda la estructura SIZE:FIXED:COLOR

La parte que le sigue al código es ejecutar estas dos eventos para que el menú se vea como anteriormente el usuario había definido …le adicionamos un setTimeout de 100ms para que no se viera un cambio brusco y en lugar de eso hicimos una animación con jQuery para que apareciera el menú como el usuario dejó en su última entrada al blog.

Cambiando los colores del blog

Para cambiar los colores extendimos el funcionamiento del plugins Popover de Bootstrap y en su lugar adicionamos el plugins bootstrapx-clickover.js; la parte del código donde creamos el pequeño popup con los cuadritos de colores es $(‘li.menu-settings [data-toggle=”popover”]’).clickover({/*CÓDIGO*/}) …aquí creamos una lista con una opción por cada personalización que definimos de nuestro tema.

opciones-blog-humanos-2

Para finalizar definimos $(‘#pre-wrap, #nav-main’).on(‘click’, ‘ul.custom-theme li’, function(evt){/*CÓDIGO*/}); sobre las opciones de personalización del Popover y lo que hacemos es crear un nuevo nodo del DOM con el CSS seleccionado.

Bueno, al final el tutorial me quedó más largo de los esperado, pero creo que ha valido la pena explicar todo el proceso …espero que me disculpen 😀

y para finalizar, otro poquito de CSS y la descarga de los recurso mencionados en el tutorial.

/*INICIO - opciones del menu superior*/
#banner.nav-small #site-logo {
    width: 80%;
}

#banner.nav-no-fixed {
    position: absolute;
}

#banner.nav-small .nav-description {
    display: none;
}

#banner.nav-small li.menu-settings {
    display: none;
}

div.popover.bottom {
    margin-top: 3px;
    right: 0;
    left: initial!important;
    width: 163px;

    -webkit-border-radius: 0 0 4px 4px;
    -moz-border-radius: 0 0 4px 4px;
    border-radius: 0 0 4px 4px;
}

div.popover.bottom .arrow {
    display: none;
}

#banner.nav-small .menu-principal a {
    height: 25px;
}

.navbar .menu-principal {
    margin: 0 5px 0 0;
    border-right: 1px dotted #AAA;
    padding-right: 5px;
}

#banner ul.nav-options {
    margin: 0;
    opacity: .4;
}

#banner:hover ul.nav-options {
    opacity: 1;
}

#banner ul.nav-options li {
    line-height: 20px;
}

#banner ul.nav-options li a {
    padding: 0 5px;
}

#banner ul.nav-options a:hover {
    text-decoration: none;
}

div.popover.bottom ul.custom-theme {
    margin: 0;
}

div.popover.bottom ul.custom-theme li {
    width: 20px;
    height: 20px;
    border: 2px solid #E1E1E1;
    padding: 0;
    margin: 0 3px 3px 0;
    cursor: pointer;
}

div.popover.bottom ul.custom-theme a {
    font-size: 0;
}

ul.custom-theme li.android { background-color: #005907}
ul.custom-theme li.arch { background-color: #1794D1}
ul.custom-theme li.debian { background-color: #055082}
ul.custom-theme li.default { background-color: #772953}
ul.custom-theme li.kubuntu { background-color: #0084AA}
ul.custom-theme li.mint { background-color: #005907}
ul.custom-theme li.nova { background-color: #055082}
ul.custom-theme li.red { background-color: #B94346}
ul.custom-theme li.retro { background-color: #000}
ul.custom-theme li.suse { background-color: #296128}
/*FIN - opciones del menu superior*/
Shoestrap Recursos (306 descargas)

NOTA: La descarga de estos recursos puede hacerse de sus respectivas páginas oficiales puesto que no se les hizo ninguna modificación.