Breve revista para los nuevos en el mundo de la seguridad informatica
Descripción: educacion
Descripción completa
manual
Mate
introduccion a la programacion desde ceroDescripción completa
Aprendiendo PythonDescripción completa
Descripción: Aprende Java desde cero con este tutorial.
Descripción completa
Manual Access Desde CeroDescripción completa
introduccion a la programacion desde cero
php y mysqlDescripción completa
introduccion a la programacion desde cero
ideologiaDescripción completa
Descripción: Aprenda Excel sin saber nada
Arduino con programación y proyectosDescripción completa
libro Windows 7 Desde CeroDescripción completa
Taller para aprender a crear Themes WordPress desde cero
En 20 clases te explicamos la base para poder explotar todas las capacidades de esta potente y popular plataforma para gestionar contenidos.
2013 - Summarg.com
Introducción Este taller pretende introducir a la creación de themes WordPress a aquellos con poca experiencia en el tema, por ende utilizaremos un nivel básico en lo referente al tema. Apuntamos a que el lector aprenda a instalar un servidor local y pasar un diseño de PSD (Photoshop) a theme WordPress compuesto por diversos formatos de archivos (PHP, JS, CSS, imágenes, etc.). Para modificaciones de nivel medio y superior, pueden chequear nuestra sección de WordPress que continúa en constante actualización. Existen varios tutoriales en la red que ofrecen crear themes en pocos pasos, en 15 minutos o sin esfuerzo. Nosotros elaboramos un temario que consiste en varias clases puesto que nuestra intención es que el lector aprenda a crear los themes entendiendo cada paso del proceso para poder tener la libertad de iniciarse luego en temas mas complejos y para lograr resultados cada vez mas interesantes. Las siguientes herramientas serán necesarias para poder seguir el tutorial: • Notepad++ (gratuito) u otro editor de código como Dreamweaver. • Photoshop u otro editor de imágenes. • XAMPP (gratuito) servidor local. • FileZilla (opcional – gratuito) o cualquier aplicación FTP para subir tu trabajo a un servidor remoto. • JS Screen Ruler (opcional – gratuito) regla para tu pantalla, ayuda a ajustar detalles. Abarcaremos todos los temas listados de a uno por clase, insertando los enlaces en cada entrega semanal. El temario está sujeto a cambios según lo veamos conveniente.
2
Indice de clases Clase 1: Introducción: Instalar WordPress en un servidor local ------------- Pag 5 • XAMPP • Generar una base de datos desde PhpMyAdmin • Contenido de pruebas para la plataforma Clase 2: Cómo encarar el diseño a partir de un archivo PSD ----------------- Pag 8 • Presentamos nuestra plantilla. • Introducción a las partes de un theme. Clase 3: ¡Comenzamos a maquetar! --------------------------------------------------- Pag 11 • Comenzamos a maquetar el index.php • Funciones básicas de header.php • El archivo de estilos CSS Clase 4: El bucle y jerarquías de templates ----------------------------------------- Pag 21 • El bucle • Funcionamiento de la jerarquía de templates • El bucle en los templates Clase 5: El bucle avanzado: Query_posts ------------------------------------------- Pag 25 • Múltiples bucles en la misma página • Uso básico de the_post_thumbnail Clase 6: El archivo header.php y los menús en WordPress ------------------- Pag 29 • Función de wp_head() • Introducción a condicionales de template • Aplicaciones de bloginfo • Menús con wp_nav_menu Clase 7: Implementar Nivo-slider sin plugins --------------------------------------- Pag 36 • Trabajar con jQuery • Insertar Nivo-Slider y adaptarlo al theme Clase 8: Sidebar y widgets ---------------------------------------------------------------- Pag 40 • Qué son y cómo funcionan los widgets? • Añadir mas sidebars • Clase Anexo: Añadir una sidebar horizontal -------------------------------- Pag 45 Clase 9: El archivo footer.php ------------------------------------------------------------ Pag 48 • Función y usos frecuentes • Añadir área de widgets • Añadir menú secundario y link al inicio
3
Clase 10: La plantilla de entrada y de comentarios ------------------------------- Pag 54 • Single.php, layout y contenidos • Los comentarios Clase 11: La plantilla de página ---------------------------------------------------------- Pag 64 • Páginas personalizadas • Páginas y subpáginas • Plantilla de páginas con query_posts Clase 12: archive.php y plantillas por categoría, fecha, autor, taxonomía, etiqueta ---------------------------------------------------------------------------------------------- Pag 72 • Extra: Mostrar favicon y tags para Facebook • Template Conditionals: Categorías por id • Template Conditionals: Autor, Etiquetas Clase 13: Página de búsquedas: search.php e integración con Google CSE ------------------------------------------------------------------------------------------------------- Pag 80 • Search.php y personalización de la plantilla • Incorporar búsquedas con Google CSE Clase 14: Paginación, breadcrumbs y página de error 404.php -------------- Pag 85 • Snippets para paginar y para colocar breadcrumbs sin usar plugin Clase 15: Framework para opciones administrativas e inserción de anuncios ------------------------------------------------------------------------------------------------------- Pag 90 • Inserción de anuncios • Inserción de campos de texto Clase 16: Custom Post Types: Portfolio y plantilla single-cpt.php --------- Pag 97 • Metabox: Los custom fields de forma fácil • La plantilla single-cpt.php Clase 17: Custom Post Types: Portfolio y plantilla de taxonomía ---------- Pag 108 • Plantilla de Taxonomía • Página personalizada para el portfolio con jQuery Isotope Clase 18: Custom Post Types: Formulario de búsqueda ---------------------- Pag 116 Clase 19: Plugins y snippets recomendados -------------------------------------- Pag 121 Clase 20: Conclusiones y descarga del taller completo ----------------------- Pag 129
4
Clase 1: Instalar WordPress en XAMPP, un servidor local WordPress es un CMS que necesita de un servidor Apache y una base de datos MySQL para funcionar. Para aprender a construir themes WordPress servirá mucho poder instalar un servidor en nuestra propia PC, ya que nos ahorraremos el tiempo que demora en subir cada archivo modificado a un hosting y podremos llevar nuestro WordPress a todas partes sin necesidad de conexión a Internet.
5
Instalador de XAMPP Con esta finalidad instalaremos XAMPP, un servidor disponible para varios sistemas operativos y cuya instalación es muy sencilla. 1. Descargamos la versión de XAMPP que corresponda a nuestro sistema operativo desde aquí: http://sourceforge.net/projects/xampp/files/. El primer link que ofrecen es el del último instalador para Windows disponible. 2. Lo ejecutamos y corremos la instalación. Al finalizar, corremos la aplicación y nos aseguramos de que estén corriendo los servicios Apache y MySQL. Ingresamos a http://localhost/ en nuestro navegador.
Es necesario saber que XAMPP es un servidor pensado en desarrolladores y no es recomendable para producción (es decir, no se recomienda utilizar para abrir un website al público desde nuestra computadora). 3. phpMyAdmin es una aplicación que nos permite gestionar todo lo referente a nuestras bases de datos, es una de las mas populares y gran parte de los hostings generalmente la ofrecen en sus paneles, así que es buena idea familiarizarse con la misma. Primero cambiaremos la contraseña, por defecto el campo viene vacío. Abrimos con nuestro Notepad++ el archivo c:/xampp/ phpmyadmin/config.inc.php, colocamos un usuario, su contraseña y cambiamos el valor de AllowNoPassword a false. $cfg[‘Servers’][$i][‘user’] = ‘root’; $cfg[‘Servers’][$i][‘password’] = ‘****’; $cfg[‘Servers’][$i][‘AllowNoPassword’] = false; Ahora ingresamos a http://localhost/phpmyadmin y nos preparamos para crear una base de datos. Le asignaremos un nombre y cambiamos el cotejamiento de la base de datos a utf8_unicode_ci (es el último select de la lista).
4. Nuestra base de datos será ‘wordpress’, el usuario ‘root’ y la contraseña la que hayamos definido en el config.inc.php arriba mencionado. Con esto completado ya podemos descargar la última versión de WordPress desde el sitio oficial y descomprimirlo dentro del directorio c:/xampp/ htdocs/. Abrimos el archivo wp-config-sample.php y editamos los siguientes datos. /** El nombre de tu base de datos de WordPress */ define(‘DB_NAME’, ‘wordpress’); /** Tu nombre de usuario de MySQL */ define(‘DB_USER’, ‘root’); /** Tu contraseña de MySQL */ define(‘DB_PASSWORD’, ‘tucontraseña’); Guardamos el archivo con el nombre wp-config.php e ingresamos a http://localhost en nuestro navegador, nos llevará directo a la pantalla de instalación de WordPress, en donde completamos
6
con los datos requeridos y ya estaremos listos.
7
5. Para completar nuestra clase de hoy cargaremos algún contenido de pruebas en nuestro WordPress, de modo de que tengamos algunas entradas, categorías y páginas con diferentes formatos de texto para visualizar cuando trabajemos cada plantilla. En esta nota ya habíamos hablado de este recurso que pueden descargar directamente de aquí https://wpcom-themes.svn.automattic. com/demo/test-data.2011-01-17.xml En nuestro panel de administrador nos dirigimos a herramientas > importar > wordpress. Subimos el archivo y aceptamos. Con esto ya tendremos nuestro WordPress instalado en un servidor local y podremos empezar a trabajar en él en nuestra próxima clase.
Activar permalinks en XAMPP
La activación de los permalinks de WordPress en nuestro servidor local XAMPP, WAMPP o AppServ puede resultar fundamental para trabajar con comodidad. Por lo general bastará con activar los Permalinks desde Ajustes > Enlaces permanentes y crear el .htaccess con el contenido que WordPress nos facilita. En algunos casos el módulo rewrite no está activado por lo que tendremos que buscar el archivo httpd.conf dentro de apache/conf/. La carpeta apache puede llamarse apache2 dependiendo del software que utilicemos. Utilizamos un editor como Notepad++ y buscamos la siguiente línea: #LoadModule rewrite_module modules/mod_rewrite.so Removemos el signo #. Luego buscamos las siguientes líneas: AllowOverride All## Controls who can get stuff from this server.#Order allow,denyAllow from all Y nos aseguramos de que AllowOverride All no tenga numeral. Guardamos y reiniciamos XAMPP.
Clase 2: Cómo encarar el diseño a partir de un archivo PSD Bienvenidos a la segunda clase de Taller para crear un theme WordPress desde cero. En esta clase veremos como tomar un template en formato PSD (Adobe Photoshop) y convertirlo en un theme WordPress. Utilizaremos un template que hemos creado especialmente para este taller, lo bautizamos ThemeTaller. Está dividido en capas y agrupadas por secciones con un nombre descriptivo, pueden descargarlo y modificarlo libremente. Este template estará sujeto a modificaciones a lo largo del taller según lo veamos conveniente. Les mostramos y entregamos el home de nuestro diseño. Descargar ThemeTaller: ThemeTaller
8
El set de íconos sociales es Socialis21 y pueden encontrar el link de descarga aquí: Socialis21 En el pie de página pueden encontrar la paleta de colores utilizada para el theme y la compartimos para que puedan crear nuevas secciones dentro de la plantilla haciendo uso de la misma. Antes de empezar a maquetar conozcamos un poco lo que vamos a hacer. Los themes WordPress utilizan varios archivos a la vez para formar una página, que son llamados por funciones específicas de la plataforma para facilitar las cosas. Son similares a la función include de PHP y nos evitan tener que escribir la misma porción de código en varias plantillas. Por ejemplo, la sección del encabezado del sitio siempre es igual, llevará un logo y una botonera que no deseamos que cambie. En un sitio construido íntegramente en HTML deberíamos copiar este código en cada una de las páginas. Pero en WordPress bastará con escribir todo el código del encabezado dentro de header.php y luego solicitar el encabezado en cada sección que lo necesite-
mos. Lo mismo cuenta para la barra lateral (sidebar.php) y el pié de página (footer.php). De ese modo cuando se lista el index de un sitio WordPress, éste estará compuesto de los archivos header.php, index.php, sidebar.php y footer.php. Para el caso de listar una página los archivos serán: header.php, page.php, sidebar.php y footer.php. ¿Qué cambió? El inicio utiliza index. php para mostrar su contenido principal y una página utiliza el archivo page.php. Para “solicitar” desde el index.php los archivos en cuestión utilizaremos las funciones: get_header(); get_sidebar(); get_footer(); Entonces dividiremos el home (index.php) en 4 archivos que los marcamos a la derecha en la siguiente imagen (en el zip de descarga del theme encontrarán la imagen en tamaño grande).
9
A la izquierda indicamos los elementos que consideramos necesario nombrar, con sus respectivos atributos class e id. De este modo el archivo header.php contendrá, entre cosas, el elemento #header, que dentro de sí contendrá el un #menu-top, el #logo y el #menu. El contenido de la página (el fondo blanco con bordes redondeados) se llamará #content y el ancho del diseño será fijo (960px). Todos los colores y bordes pueden definirse directamente desde el CSS, aunque si quieren ser fieles al diseño sólo deberán recortar un rectángulo pequeño con el fondo de la barra del menú y el fondo gris de los productos destacados:
Para recortar las partes del theme en Photoshop, deberán utilizar la herramienta máscara y seleccionar la sección. En nuestro caso seleccionamos el logo. Luego seleccionan image > crop y guardan el resultado utilizando la opción save for web & devices (guardar optimizado para la web) como logo.png. También necesitarán repetir el proceso con los íconos sociales.
10 La clase que viene comenzamos a maquetar esta página. Descarguen el archivo PSD y empiecen a ver como está compuesto.
Clase 3: ¡Comenzamos a maquetar! En la clase anterior estuvimos observando como se compone cada plantilla de WordPress, así que en vez de maquetar nuestra página de inicio en una sola página como si fuera un HTML común, arrancaremos utilizando 4 archivos PHP y la plantilla de estilos CSS por separado. Dentro de nuestro directorio /wp-content/themes/, creamos un directorio llamado /themetaller/. Dentro de /themetaller/ colocaremos un subdirectorio /scripts/, que en principio estará vacío, y otro llamado /images/ en donde colocamos las imágenes recortadas en la clase anterior.
11
Creamos los siguientes archivos en nuestro directorio /themetaller/: index.php, footer.php, header. php, sidebar.php y style.css.
Y respetando la división de establecimos la clase pasada, comenzamos a crear el código del header.php. Vamos a agregar en el encabezado, entre etiquetas el siguiente código: >
<meta http-equiv=”Content-Type” content=”; charset=” /> | | Archivo por autor | | | Archivo por Categoria | | Archivo por Mes | | Resultados | Archivo por Tag | ” media=”screen” /> ” /> ” /> El código para el encabezado contiene información sobre el DOCTYPE, HTML, los meta, el charset, se vincula la plantilla de estilos, se indican los links de los feeds y del pingback, se colocan varios condicionales para el title (dependiendo de la sección que se visualiza, mostrará un título diferente) y finalmente la función wp_head(), que es la función que utiliza la plataforma para cargar scripts desde plugins y otra información adicional. Ahora si, maquetamos lo que vimos en la imagen de la clase pasada:
Para esta primera etapa no utilizaremos funciones WordPress, por lo que la ruta al logo es una ruta absoluta y los links de nuestros menús totalmente inventados, a modo de relleno para que nuestro primer trabajo posea algo de contenido y podamos ver la forma que toma. Para las imágenes de relleno utilizaremos el servicio de lorempixum.com, que nos permite tomar imágenes al azar indicando en el link el tamaño de las mismas. El index.php comprendía esta sección: 13
Al inicio de nuestro archivo vamos a “llamar” al header.php utilizando la función get_header(), y al final del mismo debemos insertar el archivo sidebar.php (con get_sidebar() ) y el archivo footer. php (con get_footer() ).
Quiere saber mas?
”Neque porro quisquam est qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit...”
Quiere saber mas?
”Neque porro quisquam est qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit...”
Quiere saber mas?
”Neque porro quisquam est qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit...”
Un post que se destaca...
Sed pharetra risus eu nisi molestie aliquet. Donec ipsum eros, sodales ut convallis ac, posuere vitae orci. Leer más p>
Un post que se destaca...
Sed pharetra risus eu nisi molestie aliquet. Donec ipsum eros, sodales ut convallis ac, posuere vitae orci. Leer más p>
El código de sidebar.php:
Ultimas noticias
Una noticia en la
Una noticia en la
Una noticia en la
Una noticia en la
Y el de footer.php, que llevará la función wp_footer(), similar a wp_header().
Hasta aquí el resultado será una página con datos sin nada de estilo. Vale aclarar que todos los
que abrimos, llevan su correspondiente
de cierre con un comentario: . Esta práctica nos ayuda a tener mayor control sobre nuestras etiquetas, puesto que un sitio web puede volverse realmente complejo a medida que añadimos elementos. Cuantos mas comentarios tengamos, mas facil será para nosotros luego encontrar errores cuando surjan. Además recomendamos en todo momento hacer uso de la indentación, separando los bloques de código según corresponda. Si colocamos themeTaller como el theme por defecto de nuestro WordPress en localhost ya deberíamos ver todos los datos e imágenes, uno debajo del otro. Para que realmente tome forma tenemos que añadir el estilo, al cual debemos colocarle los datos del theme y un reset de estilo. /*Theme Name: themeTaller Theme URI: www.summarg.com Author: Nekko Description: themeTaller */ /* RESET */ html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, font, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td { margin: 0; padding: 0; border: 0; outline: 0; font-weight: inherit; font-style: inherit; font-size: 100%; font-family: inherit; vertical-align: baseline; } :focus { outline: 0; } body { line-height: 1; color: black; background: white;
15
} ol, ul { list-style: none; } table { border-collapse: separate; border-spacing: 0; } caption, th, td { text-align: left; font-weight: normal; } blockquote:before, blockquote:after, q:before, q:after { content: “”; } blockquote, q { quotes: “” “”; } Ahora si, procedemos a colocar el color de fondo de la página , establecer las dimensiones, el color de fondo y los bordes redondeados de content-wrapper. Para este punto indicamos que nos ayudamos con aplicaciones online como css3generator.com para generar el código CSS3 correspondiente a cada motor de navegador. body { background-color: #2d435a; font-family: arial, sans serif; font-size:12px; } #content-wrapper { width:960px; margin: 10px auto; background-color:white; -webkit-border-radius: 10px; -moz-border-radius: 10px; border-radius: 10px; overflow:hidden; display:block; } Escribimos el código para los elementos del header: #header { padding: 5px 20px; } #logo img { float:left; width: 261px;
16
height: 53px; padding: 10px 0; } ul#menu-top { height:25px; width:220px; margin-top:0; float:right; } ul#menu-top li a { list-style-type:none; text-decoration:none; float:left; color: #7ec5ff; font-weight:bold; padding: 7px 10px; } ul#menu-top li a:hover { text-decoration:none; background-color: #7ec5ff; color:#fff; font-weight:bold; padding: 7px 10px; } ul#menu { float:left; width: 920px; margin: 0 auto; height:30px; background-image: url(images/menu_bg.png); background-repeat: repeat-x; background-color: #7ec5ff; } ul#menu li a{ float:left; list-style-type:none; text-decoration:none; color:#fff; font-weight:bold; padding: 10px 20px; border-left: 1px solid white; } ul#menu li a:hover { text-decoration:none; background-color: 8ed6ff; color: #f4f4f4; padding: 10px 20px; } Vayan visualizando el sitio para confirmar que cada paso esté dado en la dirección correcta.
17
Ahora procedemos a dar estilo al espacio del slider, los bloques de productos-servicios destacados y de las noticias. #nivoslider { float:left; margin: 10px 20px; width: 920px; height: 310px; } #featured { float:left; width: 918px; height: 100px; margin: 0 20px; border: 1px solid #7b7b7b; border-right:none; background-image: url(images/destacado_bg.png); background-repeat: repeat-x; background-color: #dedddd; } .item { width: 295px; padding: 5px; height: 90px; overflow:hidden; border-right: 1px solid #7b7b7b; float:left; } .item h3 { font-family: arial, sans serif; font-weight:bold; font-size: 16px; line-height:30px; color: #7b7b7b; text-align:center; } .item p { font-family: arial, sans serif; font-weight:bold; font-size: 12px; line-height:20px; color: #7b7b7b; text-align:center; } Aquí hacemos un pequeño alto para introducir una aclaración. Si ustedes visualizan el theme hasta aquí, verán que la tipografía ya no se ve igual que en nuestro PSD, en donde utilizamos la fuente Myriad Pro. Vale aclarar que en clases futuras podemos introducir fuentes mucho más elegantes utilizando cufón o bien utilizar el servicio de fuentes de Google y @font-face. Seguimos
18
con el estilo de la sección de noticias. .news { width: 293px; padding: 20px 0 10px 20px; float:left; } .news h2 { font-family: arial, sans serif; font-size: 22px; margin-top:10px; color: #7b7b7b; } .news p { font-family: arial, sans serif; font-size: 12px; line-height:18px; color: #7b7b7b; } Pasamos a dar estilo a los elementos de la sidebar. #sidebar { width: 293px; padding: 20px 20px 10px 0px; float:right; } #sidebar h3 { font-family: arial, sans serif; font-size: 18px; margin-bottom:10px; color: #7b7b7b; } #sidebar ul { list-style-type:none; } #sidebar ul li { padding: 5px 10px; border-bottom: 1px solid #7b7b7b; color: #7b7b7b; } Y finalmente el estilo del footer. #footer { float:left; background: #e6e6e6;
19
width: 920px; padding: 20px; height:100px; } ul.social { list-style-type:none; float:right; width:150px; } ul.social li{ float:left; } Para ir viendo la evolución del trabajo instalamos un WordPress en SummArg en www.summarg. com/demos/themetaller. Les dejamos los archivos del ejercicio de hoy aquí ThemeTaller clase 3. Sientanse libres de plantear cualquier duda o comentarnos cómo lo harían ustedes tanto aquí como en nuestro foro. Nos vemos en la próxima clase!
20
Clase 4: El bucle y jerarquía de plantillas El bucle (en inglés The Loop) es el proceso de efectuar búsquedas de determinados parámetros a través de ciertas condiciones. El bucle mas simple que existe en WordPress es el siguiente: Lo que hace es verificar que en la sección en donde se ejecuta existan entradas. En caso de ser positivo entonces se ejecuta la sentencia de PHP while, que se encarga de recorrer la base de datos en busca de nuestras entradas mientras have_posts() sea verdadero. Cuando have_posts() ya no encuentre entradas en la sección, termina el bucle. Cuando mencionamos “la sección”, nos referimos a si estamos en la página inicial de nuestro WordPress, una categoría, una búsqueda por fechas, por autor, o tags. Ahora veamos este mismo bucle en su forma completa. Código que se ejecuta mientras have_posts() sea verdadero. Código a ejecutarse para el caso de que have_posts() sea falso, es decir que no contenga entradas. Fin del bucle ¿Qué código podría ejecutarse mientras have_posts() sea verdadero? En el caso de que existan entradas, lo que podría interesarnos es, por ejemplo, obtener el título de la entrada con link a la misma, el contenido, la fecha de publicación y el autor. Para ello utilizamos las siguientes funciones:
Cada una de estas funciones posee su documentación en el Codex de WordPress.org, un documento fundamental para aprender a utilizar la enorme cantidad de funciones de la plataforma con sus respectivos parámetros (opciones). El bucle completo quedaría de la siguiente manera:
Lo sentimos, no se han encontrado entradas. La cantidad de entradas por página se pueden configurar desde Escritorio > Opciones > Lectura. El bucle expuesto si es ejecutado en la plantilla de inicio de nuestro sitio, arrojará la información indicada (título, link, contenido, fecha y autor) de las últimas 10 entradas, de cualquier categoría, una debajo de la otra y de la mas reciente a la mas antigua. Este mismo bucle en otras plantillas, arrojará diferentes resultados. Por ejemplo, para el caso de
21
ser ejecutado el bucle en una plantilla de categoría, buscará las últimas entradas de esa categoría específica. El mismo caso se dará en la plantilla de archivo por fecha (date), archivo por autor (author), etc. Un dato interesante es que WordPress tiene un sistema de jerarquía de plantillas, en donde primero busca una plantilla específica y si no la encuentra cae en buscar una plantilla mas general para esa misma sección. En caso de no existir una plantilla determinada, finalmente utilizará la plantilla index.php para mostrar el resultado del bucle de esa sección.
22
Este esquema es una versión muy simplificada del complejo sistema de plantillas que posee WordPress 3.0 y que pueden visualizar aquí. Para poner en práctica lo visto hoy, insertaremos en nuestro ThemeTaller un bucle sencillo en la plantilla archive.php y veremos como reacciona cuando solicitamos diferentes categorías, archivos por fecha, por autor y tags. Mas adelante nos ocuparemos de personalizar algunas categorías en particular, hacer dos o tres templates diferentes para páginas y varias cuestiones mas. Para poder probar la efectividad del ejercicio tenemos que tener contenidos cargados en nuestro WordPress (en la primer clase vimos como importar algunos contenidos de prueba). Creamos el archivo archive.php y dentro colocaremos:
Lo sentimos, intente utilizar nuestro formulario de búsquedas.
En este código hemos cambiado the_content() que lista el contenido completo de una página, por the_excerpt(), que trae por defecto las primeras 55 palabras sin formato de la entrada. En el CSS añadimos las siguientes líneas: #wrapper {margin-left:20px;margin-top:20px;float:left;width:606px;} .dos-tercios {float:left;margin-bottom:20px;padding: 5px;width:596px;} .listado {border-bottom: 1px solid #7b7b7b;} Esta plantilla servirá para ver: categorías, entradas por tags, entradas por autor, entradas por fecha, entradas por taxonomía y por post type. Podemos probar las siguientes URLs en nuestro servidor de pruebas (nosotros colocamos las URLs a nuestro WP de pruebas): http://www.summarg.com/demos/themetaller/?tag=post-formats http://www.summarg.com/demos/themetaller/?author=3 http://www.summarg.com/demos/themetaller/?cat=45 El mismo contenido sirve para los archivos single.php y page.php. Probemos colocar el mismo contenido de archive.php en page.php y en single.php cambiando the_excerpt() por the_content() y solicitemos una página. Como resultado tendremos una página con su respectivo título, contenido completo, fecha y autor. http://www.summarg.com/demos/themetaller/?page_id=501 Y para avanzar un poco mas con el estilo del theme, podemos añadir valores para las propiedades básicas que ubicaremos luego de body. Estas serán los headings (h1 a h6), p, a, cite, pre, ul, ol, li, table, etc. a, a:visited {color:#7ec5ff;text-decoration:underline;} a:hover {text-decoration: none;color:#8ed6ff;} small {font: normal 10px “arial”, Sans-serif;} img {border: none;margin: 3px;} p {font: normal 12px “arial”, Sans-serif;line-height:18px;padding: 0px 0px 15px 0px;margin: 2px 0;} table, td, tr {font: normal 12px “arial”, Sans-serif;line-height:18px;} td {padding:5px;} th {font: bold 13px “arial”, Sans-serif;line-height:18px;padding: 5px;} h1, h2, h3, h4, h5, h6 {color:#7ec5ff;padding:0px;} h1 {font: normal 26px/30px “arial”, Sans-serif;margin:0 0 5px 0;letterspacing:-1px;} h2 {font:normal 22px/24px “arial”, Sans-serif;letter-spacing:1px;margin:0 0 5px 0;} h3 {font:normal 20px/22px “arial”, Sans-serif;margin:0 0 10px 0;} h4 {font:bold 16px/24px “arial”, Sans-serif;margin:0;} h5 {font:bold 14px/22px “arial”, Sans-serif;margin:0;} h6 {font:normal 12px “arial”, Sans-serif;margin:0;} h1 a, h1 a:visited, h2 a, h2 a:visited, h3 a, h3 a:visited {color: #7ec5ff;text-decoration: none;} h1 a:hover, h2 a:hover, h3 a:hover {color: #7ec5ff;text-decoration: none;} h3 a, h3 a:visited, h4 a, h4 a:visited {color: #417394;textdecoration:none;}
23
form {margin:0px;padding:0px;} blockquote {padding: 10px 10px; margin:10px 0px 10px 0px; liststyle:none; border:1px solid #7ec5ff; background-color:#8ed6ff;font: normal 120%/100% Arial, sans serif; } ul{font: normal 12px “arial”, Sans-serif;list-style:circle;padding:0px; margin:0px;} ol{font: normal 12px “arial”, Sans-serif;list-styletype:decimal;padding:0px; margin:0px 0px 10px 10px; } li{margin: 0px 0px 0px 10px; padding: 0px;} table, tr, td {font-size:12px;} strong {font-weight:bold;}cite,em,i {font-style: italic;border: none;} pre{font-family:”Courier New”, Courier, monospace;font-size:12px;lineheight:15px;} En la próxima clase veremos como hacer consultas avanzadas con query_posts() para poder llenar los bloques de información del index.php que ya llevamos empezado. Ver el demo de esta clase | Descargar el theme con el ejercicio de esta clase 24
Clase 5: El bucle avanzado: query_posts. Una de las formas mas fáciles de armar un bucle que cumpla con determinadas condiciones es utilizando query_posts. Una consulta con esta función altera el bucle a continuación y puede utilizarse para múltiples bucles si utilizamos correctamente wp_reset_query(). ’; the_title(); echo ‘’; endwhile; // Reset wp_reset_query(); ?> En nuestra clase de hoy vamos a insertar dentro de themeTaller tres bucles nuevos: • Uno para invocar el contenido de tres entradas de la categoría “Productos destacados” y colocarlos debajo de nuestro slider. • Buscaremos dos entradas de la sección noticias para colocar debajo de los productos destacados. • En la barra lateral colocaremos las últimas cuatro entradas de la categoría blog. • • • • • • •
Tomamos la primer sección en donde colocaremos los productos destacados y encontramos este código HTML según lo que trabajamos en la Clase 3:
25
Quiere saber mas?
”Neque porro quisquam est qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit...”
Quiere saber mas?
”Neque porro quisquam est qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit...”
Quiere saber mas?
”Neque porro quisquam est qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit...”
Creamos la categoría “Producto Destacado” e insertamos tres entradas con título y un poco de texto (sólo unas líneas). Ahora reemplazamos por el bucle con query_posts, en donde los parámetros serán seleccionar tres posts (posts_per_page=3) de la categoría “Producto Destacado” (category_name=Producto Destacado):
Guardamos y probamos que nuestro theme nos muestre, efectivamente, nuestras tres entradas. Ahora procedemos a elaborar el segundo bucle que será un poco mas complicado debido a que tiene imágenes con un tamaño específico. Para nuestras imágenes vamos a utilizar la función the_post_thumbnail disponible a partir de WP 3+ y que nos ofrece la posibilidad de gestionar miniaturas de tamaños personalizados sin necesidad de plugins. Para activar la función deberemos indicarlo en nuestro archivo functions.php, que hasta ahora no vimos, así que creamos un archivo llamado functions.php y dentro colocamos el siguiente contenido: Con add_image_size indicamos a la plataforma que necesitamos un tamaño personalizado al que llamaremos homepage-thumb y que deseamos que mida 290px de ancho por 130 de alto. Además la imagen será recortada y no redimensionada (el valor true final activa el crop, o re-
26
corte), de este modo evitamos que algunas imágenes se deformen. Ahora procedemos a crear la categoría “Noticias” y subimos dos entradas las cuales tendrán una imagen que definiremos como destacada. En nuestro archivo index.php buscamos el siguiente código:
Un post que se destaca...
Sed pharetra risus eu nisi molestie aliquet. Donec ipsum eros, sodales ut convallis ac, posuere vitae orci. Leer más p>
Un post que se destaca...
Sed pharetra risus eu nisi molestie aliquet. Donec ipsum eros, sodales ut convallis ac, posuere vitae orci. Leer más p>
Y lo reemplazaremos por nuestro segundo bucle, el cual modificaremos para que busque sólo dos entradas en la categoría “Noticias”.
Verán que en el caso de los títulos que llevan links ahora los vemos en color celeste y con subrayado debajo. Eso se debe a que nunca definimos desde el style.css como debían verse, así que pasaremos a hacerlo. .news h2 a {color: #7b7b7b;text-decoration:none;} #sidebar ul li a{text-decoration:none;color: #7b7b7b;} Verificamos que se vea todo correctamente en nuestro servidor de pruebas y listo. http://www.summarg.com/demos/themetaller/ themeTaller clase 5
28
Clase 6: el archivo header.php y los menús en WordPress En la clase 3 hablamos un poco sobre el código básico que debe ir en el archivo header.php, el cual incluye DOCTYPE, HTML, metas, charset, lenguaje, etc. Además se vinculan las plantillas de estilo y cualquier script que necesitemos cargar entre etiquetas . Toda página necesita tener un título para ser identificada. Vamos a colocar el nuestro utilizando la función bloginfo(). Dicha función es de uso frecuente en la construcción de themes WordPress y los parámetros mas utilizados (entre otros) son: bloginfo(‘name’) = Devuelve el nombre del blog (se modifica desde Ajustes > General). bloginfo(‘description’) = Devuelve la descripción del blog (se modifica desde Ajustes > General). bloginfo(‘site_url’) = Devuelve el directorio en donde WP está instalado. bloginfo(‘stylesheet_url’) = Devuelve la ruta a la plantilla de estilos. bloginfo(‘template_url’) = También puede utilizarse ‘template_directory’, devuelve la ruta al directorio del theme. Siguiendo con el título, si bien ya estuvimos viendo condicionales, hoy necesitamos profundizar un poquito mas en el tema. En PHP la estructra de un condicional es de la siguiente manera: Entonces con esto presente pasaremos a elaborar un código utilizando conditional tags, que son etiquetas cuya finalidad es ayudarnos a construir condicionales según sección que se está mostrando. Nuestro condicional debe decir: “Si estamos en el inicio de página (is_home) entonces que muestre el nombre del blog, imprimimos ‘ | ‘ y luego la descripción del blog. Si estamos en una categoría (is_category), entonces imprimir el título de la misma, imprimimos ‘ | ‘ y el nombre del blog. Si estamos en una entrada (is_single) o en una página (is_page), entonces mostrar el título de la entrada, imprimimos ‘ | ‘ y el nombre del blog. Si ninguna condición es verdadera, entonces imprimir el título que corresponda (utilizaremos wp_ title()).” Otra función que debemos colocar en nuestro header.php es wp_head(), un hook (gancho) que debe ir entre etiquetas y que es utilizado por WordPress para colocar links a recursos y código en general que necesita la plataforma o cualquiera de los plugins que nosotros vayamos instalando. Dicha función tiene su equivalente para el pié de página, llamado wp_foot-
29
er(), y son de caracter obligatorios si pretendemos el correcto funcionamiento de nuestra plataforma. Se coloca de la siguiente manera: Aprovechando esta oportunidad, recordemos que en la Clase 3 colocamos la ruta a nuestro logo, en el header.php, de la siguiente manera:
Ahora que tenemos conocimiento de como funciona bloginfo(), podemos aprovechar y ponerlo en práctica. Reemplazaremos la parte de la ruta que corresponde al theme por la función:
/images/logo.png” />
De este modo la imagen se mostrará correctamente sin importar en que dominio se encuentra instalado el theme.
Crear menús con wp_nav_menu()
Finalmente pasaremos a los menús que ahora podemos crear desde el panel de control de forma muy sencilla. Por defecto la función no viene activada, sino que debemos hacerlo desde el functions.php de nuestro theme con register_nav_menu (para registrar un único menú) o con register_nav_menus (múltiples menús). Necesitamos dos menús, uno para el #menu-top y otro para el #menu. Así que vamos a registrarlos en el functions.php de la siguiente manera: register_nav_menus( array( ‘menu-top’ => ‘Menu superior’, ‘menu’ => ‘Menu principal’ )); Guardamos y ahora en el Escritorio nos dirigimos a Apariencia y veremos que aparece la sección Menús. Creamos dos menús, clickeando en el signo mas en el cuadro derecho. Uno se llamará “Menu Top” y el otro “Menu Principal”.
30
Luego definimos las ubicaciones de cada menú. En nuestro caso el nombre coincide con la ubicación. Guardamos al finalizar.
Y finalmente les colocamos algo de contenido. En nuestro caso, vamos a copiar la estructura que hicimos en el PSD inicial. Recuerden guardar cada menú luego de colocados los links. Utilicen las cajas de la izquierda (debajo de “Ubicación del tema”) para añadir páginas, categorías o links personalizados.
Para mostrar nuestros menús en la plantilla header.php necesitamos de la función wp_nav_ menu(). Recordemos la estructura de nuestros menús dentro del HTML generado en la clase 3.
Necesitamos reemplazar las listas desordenadas por nuestros menús recién creados. Comenzaremos por borrar nuestra lista con id #menu-top (desde el
de apertura hasta su
de cierre) y reemplazarla por la función wp_nav_menu() con los siguientes parámetros: false, ‘items_wrap’ => ‘
%3$s
’, ‘theme_location’ => ‘menu-top’ )); ?> Estos parámetros, y muchos otros que podemos utilizar, están explicados en el codex el cual les recomendamos aprender a utilizar por ser la fuente principal de aprendizaje para cualquier desarrollador de themes y plugins. Container nos permite definir el tipo de contenedor en que se coloca al menu, permite elegir entre div, nav y false, el cual deshabilita la función (fue nuestra elección. Items_wrap nos permite indicarle al menú las características que tendrá la etiqueta que envuelva al menú y Theme_location nos permite seleccionar el menú que colocaremos en esta posición (definido en el functions.php). Ahora haremos lo mismo con el menú principal. false, ‘items_wrap’ => ‘
%3$s
’, ‘theme_location’=> ‘menu’, )); ?> Dentro de uno de los items del menú, en nuestro caso de Blog, añadiremos algunas categorías o páginas hijas.
32
Para que funcione correctamente, utilizaremos un poco de jQuery, librería que podemos descargar desde jQuery.com. En el archivo functions.php, hacia el final, añadimos: /* Mi jQuery */ function my_init_method() { if (!is_admin()) { wp_deregister_script( ‘jquery’ ); wp_register_script( ‘jquery’, ‘/wp-content/themes/themetaller/scripts/ jquery.min.js’); wp_enqueue_script( ‘jquery’ ); } } add_action(‘init’, ‘my_init_method’); Colocaremos el archivo jquery.min.js en nuestra carpeta scripts, y luego añadimos dentro de las etiquetas las siguientes líneas: <script type=’text/javascript’> $(document).ready(function() { $(“#menu ul”).css({display: “none”}); $(“#menu li”).hover(function(){ $(this).find(‘ul:first’).css({visibility: “visible”,display: “none”}). show(300); },function(){ $(this).find(‘ul:first’).css({visibility: “hidden”}); }); }); Y en nuestro CSS eliminamos las líneas antiguas que hacían referencia a #menu y las reemplazamos por estas: /* Menu desplegable */ #menu { float:left; width: 940px; margin: 0; padding:0px; height:35px; background-image:url(images/menu_bg.png); background-repeat: repeat-x; background-color: #7ec5ff; position:relative; z-index:300; list-style-type:none; } #menu ul { list-style-type:none; } #menu a { float:left; display:block; text-decoration:none;
33
color:#fff; font-weight:bold; padding: 10px 25px 10px 10px; border-right: 1px solid white; } #menu a:hover { color:#fff; background: #8ed6ff; } #menu li { float:left; position:relative; } #menu ul { position:absolute; display:none; width:160px; top: 35px; left: -10px; } #menu ul a { float:left; background: #7ec5ff; border: 1px solid white; border-top:none; } #menu li ul{ border-top: 1px solid white; } #menu li ul a { width:150px; height:auto; } #menu ul ul { top:auto; } #menu li ul ul { margin:0px 0 0 10px; } #menu li:hover ul ul, #menu li:hover ul ul ul, #menu li:hover ul ul ul ul { display:none; } #menu li:hover ul, #menu li li:hover ul, #menu li li li:hover ul, #menu li li li li:hover ul { display:block; } Ahora el nuevo menú debería estar funcional. Clase 6
34
35
Clase 7: Insertar un slider sin utilizar plugins En esta clase aprenderemos a insertar un slider si la necesidad de echar mano a ningún plugin. Consideramos que esta lección conforma un excelente punto de partida para aprender a utilizar los cientos de recursos jQuery realmente asombrosos que circulan por la web. Antes que nada vale mencionar que jQuery es un framework (una librería) para facilitar animaciones y funciones del lado del cliente. Es totalmente gratuito y ya viene en el core de la mayoría de los CMS. Generalmente agregando un plugin (un slider, un news ticker o un menú) insertamos un mundo nuevo de funciones con muy poco trabajo. Los plugins de jQuery no se instalan desde el apartado Plugins de WordPress, sino que bastará con colocar el o los archivos en nuestro theme y linkearlos desde el header.php, footer.php o functions.php. Tenemos dos versiones para descargar en jQuery.com: una llamada de producción y la otra de desarrollo. En nuestro caso no estamos interesados en desarrollar nada, simplemente utilizaremos recursos ya fabricados, así que descargamos la versión de producción que está minimizada y comprimida. El archivo jquery-1.7.2.min.js (actual) posiblemente se abra en nuestro navegador y nosotros procederemos a guardarlo en una carpeta llamada /scripts/ dentro de nuestro theme. En la clase anterior utilizamos jQuery para el menú, así que en nuestro proyecto ya está almacenado. También indicamos a WordPress que deseamos utilizar nuestro archivo jQuery desde el functions.php. /* Mi jQuery */ function my_init_method() { if (!is_admin()) { wp_deregister_script( ‘jquery’ ); wp_register_script( ‘jquery’, ‘/wp-content/themes/themetaller/scripts/ jquery-1.7.2.min.js’); wp_enqueue_script( ‘jquery’ ); } } add_action(‘init’, ‘my_init_method’); Notarán que my_init_method comienza con un condicional en donde especifica que si no estamos en el área de administrador, entonces carga nuestro jQuery. Esto se debe a que WordPress ya trae la librería y, como dijimos anteriormente, y lo utiliza para el Escritorio. Si nosotros linkeasemos la librería desde el header.php del theme sin ningún miramiento ni condicionales, posiblemente algunas secciones del Escritorio dejen de funcionar con normalidad, ya que cargaría dos versiones de jQuery y ésto produciría errores.
Nivo-Slider, uno de los sliders jQuery mas populares
36
En el sitio oficial de Nivo-Slider promocionan la venta de un plugin para WordPress que es por demás fantástico. También en el repositorio oficial vimos algún que otro plugin para insertar el slider en WordPress bastante bien logrado. Pero nosotros no tomaremos esos caminos, sino que nos ensuciaremos un poco para entender como se aplican estos fantásticos recursos a nuestro theme. Primero descargamos Nivo Slider desde su sitio (desde aquí, selecciona la primer opción llamada jQuery Plugin) y copiaremos la carpeta themes, el archivo jquery.nivo.slider.pack.js y nivo-slider. css a nuestra carpeta /scripts/.
37
Y ahora linkeamos nivo-slider.css y el estilo themes/default.css desde nuestro header.php utilizando parte de la ruta hasta nuestro theme con bloginfo(), como vimos en clases pasadas. /scripts/nivo-slider.css” media=”screen” /> / scripts/themes/default/default.css” type=”text/css” media=”screen” /> Y en el footer.php vamos a linkear el archivo JS, justo antes del cierre de la etiqueta . También vamos a dejar preparado el script indicándole que queremos que se active en el
con id #nivoslider. <script type=”text/javascript” src=”/ scripts/jquery.nivo.slider.pack.js”> <script type=”text/javascript”> $(window).load(function() { $(‘#nivoslider’).nivoSlider(); }); Antes de continuar vamos a establecer el tamaño de las imágenes que utilizaremos con the_ post_thumbnail(). En functions.php ubicamos nuestra sección destinada a las imágenes. add_theme_support( ‘post-thumbnails’ ); add_image_size( ‘homepage-thumb’, 290, 130, true ); Y debajo añadimos un tamaño mas, con el nombre de homepage-slider. add_image_size( ‘homepage-slider’, 920, 310, true ); Guardamos y subimos al servidor. Ahora al subir una imagen, WordPress recortará este tamaño extra. Generamos la categoría “slider” y subimos dentro tres o mas entradas con su respectivo título y una imagen que mínimo sea de 920px de ancho por 310px alto, las cuales marcaremos
como destacadas. No es necesario que las insertemos en la entrada, con sólo marcarlas como destacadas ya alcanza.
38 Procedemos a abrir nuestro archivo index.php en donde vamos a trabajar desarrollando las primeras líneas:
El slider trae un archivo demo.html para que podamos copiar la estructura que necesita para funcionar. Lo copiamos dentro de nuestro id #nivoslider y vamos dejando libre la sección en donde colocaremos el código PHP para generar una consulta que traiga nuestras imágenes recién subidas.
Necesitamos efectuar una consulta que nos traiga tres entradas de la categoría slider, y cuando lo haga deberá mostrarnos la miniatura del tamaño que le especificamos (homepage-slider) en el functions.php usando add_image_size. Además la imagen debe estar entre etiquetas y el link debería dirigirnos a la entrada que se esté mostrando. El código finalmente quedará de la siguiente manera:
39 Finalmente podemos observar que el theme por defecto de Nivo Slider nos agrega debajo un control para navegar, lo eliminaremos abriendo su archivo de estilos ubicado dentro de nuestro theme/scripts/theme/default/default.css, buscamos la línea 30 y le añadimos un “display:none” para ocultarlo. .theme-default .nivo-controlNav { display:none; position:absolute; left:50%; bottom:-42px; margin-left:-40px; } Esperamos que les haya resultado fácil de entender esta clase y les recomendamos que utilicen el complemento Firebug (para Firefox) para ejercitar con otros scripts similares a Nivo Slider para afianzar conocimientos. Clase 7
Clase 8: Sidebars y widgets Hoy vamos a trabajar con el archivo sidebar.php y con áreas de widgets. Los widgets son pequeños módulos que se pueden añadir en sectores de nuestra elección y que tienen múltiples funciones. Por defecto WordPress nos ofrece un widget con un calendario, uno para mostrar páginas creadas, otro para categorías, menús, texto plano u HTML, links del blogroll, suscripción a feeds, campo de búsqueda, links administrativos, etc. Nosotros podemos añadir muchos mas mediante plugins.
40
Los widgets pueden agregarse a cualquier plantilla de nuestra web y combinado con condicionales, los cuales vimos en la Clase 6, nos dan un sinfín de posibilidades para nuestro sitio. Para añadir un widget hace falta primero declararlo en nuestro functions.php, y luego insertarlo en la plantilla deseada. Vamos a generar un área de widgets básico para la sidebar. register_sidebar(array( ‘name’ => ‘Sidebar’, ‘before_widget’ => ‘
’, ‘after_widget’ => ‘
’, ‘before_title’ => ‘
’, ‘after_title’ => ‘
’, )); El primer parámetro, name, asigna un nombre a nuestro widget que figurará luego en nuestro escritorio bajo “Widgets” para poder identiticarlo. before_widget y after_widget añade etiquetas al inicio y al final del mismo, en nuestro caso abrimos un div con class widget y lo cerramos. Finalmente repetimos la misma operación pero para el título con before_title y after_title. La función register_sidebar también admite los parámetros id (para colocar un ID al widget) y description (descripción). Guardamos el archivo functions.php con estas líneas que acabamos de explicar y vemos si aparece el nuevo área de widgets en Apariencia > Widgets. Hoy vamos a generar tres áreas de widgets para utilizar en tres secciones diferentes: una sidebar en el inicio, otra para la plantilla de categorías y otra para una página. Las haremos idénticas entre si pero con diferentes nombres.
’, )); Hasta ahora venimos trabajando con una sola sidebar y vamos a explotar su uso todo lo que podamos. Abrimos el archivo y colocamos luego del listado de entradas que colocamos y antes del
de cierre del div #sidebar: Con eso sólo estamos insertando los widgets que cargemos dentro de la sección “Sidebar Home”, pero faltaría indicarle que queremos que se cargue dichos widgets si y sólo si estamos visualizando el home. Echamos mano a los Condicional Tags, como ya mencionamos. Entonces reemplazamos el código por este nuevo. Probamos añadir un campo de búsqueda o lo que sea para ver si se visualiza en el home y comprobamos que no se visualice en la vista por categorías o en una página.
41
Perfecto! Ahora generamos el código con sus respectivos condicionales para el área de widgets a mostrarse en el caso de estar en una categoría (is_category) y en una página (is_page). Guardamos, activamos diferentes widgets en cada área y confirmamos que cada sidebar muestre lo que nosotros queremos. De acuerdo a lo que escribimos en nuestro functions.php el código HTML de cada widget quedó de la siguiente manera:
Busqueda
Aplicamos un estilo diferente al widget para diferenciarlo de otros contenidos añadiendo un margen inferior, color de fondo, color de borde, borde redondeado y padding. .widget { margin-bottom: 20px; -webkit-border-radius: 5px; border-radius: 5px; background: #f4f4f4; border: 1px solid #ececec; padding: 5px; }
Doble sidebar
A nuestro template de página le vamos a agregar una segunda sidebar, sólo por el gusto de ver como funciona el asunto. Abrimos el archivo page.php y observamos que en la anteúltima línea se utiliza una función para incluir la sidebar allí. Duplicaremos dicha función pero esta vez insertando entre comillas simples el nombre de nuestra nueva sidebar, que en este caso se llamará “dos”.
get_sidebar(‘dos’); ?>
Ahora necesitamos crear el archivo de dicha sidebar y para nombrarlo debemos tener en cuenta que primero colocamos sidebar-nombreelegido.php. El “nombreelegido” es lo que colocamos entre comillas simples cuando invocamos al archivo con get_sidebar. En nuestro caso el archivo deberá llamarse sidebar-dos.php. Coloquemos dentro el siguiente contenido.
42
Dos’) ) : endif; ?>
Generamos esta nueva área de widgets en el functions.php. register_sidebar(array( ‘name’ => ‘Sidebar Dos’, ‘before_widget’ => ‘
’, ‘after_widget’ => ‘
’, ‘before_title’ => ‘
’, ‘after_title’ => ‘
’, )); Y para que haya un poco de coherencia en el diseño, vamos a modificar los ids de page.php para generar un CSS para este layout.
Lo sentimos, intente utilizar nuestro formulario de búsquedas.
Añadimos en el CSS las propiedades para #wrapper-dos y #sidebar-dos. #wrapper-dos { width:392px; float:left; margin-top:20px; margin-left:20px; } #sidebar-dos{ width: 215px; margin-top:20px; margin-right:20px; float:right; } Y vamos a darle un poco de formato a las listas dentro de widget, ya que nuestros widgets las usan mucho. .widget li { list-style-type:none; padding: 0 0 0 10px; }
43
Nuestro ejercicio de hoy no ha quedado muy bonito que digamos, pero espero que la idea haya sido lo mas clara posible. Pueden agregar tantas áreas de widgets como quieran y tantas sidebars como sean necesarias.
44
Clase 8
Clase 8 Anexo: Sidebar horizontal A pedido de uno de los lectores que viene siguiendo el curso, añadimos un anexo a la clase 8, dedicada a sidebars, para explicar como maquetar una tercera sidebar pero de modo horizontal. Vamos a seguir experimentando con las sidebars dentro de la plantilla page.php que ya tiene dos sidebars dispuestas de la siguiente manera. Antes de continuar les recomendamos leer un poco sobre la propiedad float (aquí hay un buen tutorial en español). Básicamente esta propiedad es la encargada de indicarle a un contenedor hacia donde debe ubicarse, lo que requiere para su correcta ubicación es un ancho fijo y espacio libre en la dirección deseada.
45
En el trabajo que ya tenemos hecho, nuestras dos sidebars tienen ancho fijo y flotan hacia la derecha (float:right). Es importante remarcar que las sidebars se ubican en el primer espacio libre encontrado en la dirección indicada desde float. Nosotros ubicamos el contenido a la izquierda, por eso queda disponible el espacio derecho para nuestros widgets. #sidebar { width: 293px; margin-top:20px; margin-right:20px; float:right; } #sidebar-dos{ width: 215px; margin-top:20px; margin-right:20px; float:right; } Al tener las sidebars los anchos que deseamos, los contenedores con class .widget no lo necesitan, ya que flotarán con el mismo ancho de su contenedor padre en dirección vertical. .widget { margin-bottom: 20px; -webkit-border-radius: 5px; border-radius: 5px; background: #f4f4f4;
border: 1px solid #ececec; padding: 5px; } Ahora lo que tenemos que lograr es insertar una tercera sidebar, debajo de todo el contenido pero arriba del footer, que ocupe todo el ancho de la página y que tenga tres widgets adentro.
46
La tercera sidebar se ubicará dentro de un archivo que llamaremos sidebar-horizontal.php y la llamada a la misma dentro de page.php se realiza de la siguiente forma: Dentro de sidebar-horizontal.php colocaremos dos áreas con contenido de pruebas y en el tercer espacio repetiremos un área de widgets (¡ustedes ya saben como agregar áreas nuevas!).
Area uno
Contenido de prueba
Contenido de prueba
Contenido de prueba
Contenido de prueba
Contenido de prueba
Area dos
Contenido de prueba
Contenido de prueba
Contenido de prueba
Contenido de prueba
Contenido de prueba
if ( !function_exists(‘dynamic_sidebar’) || !dynamic_sidebar(‘Sidebar Categoria’) ) : endif; ?>
Y finalmente el toque “mágico” para que tome la forma deseada: el código CSS. Primero damos el ancho total que va a tener el área contenedor de los widgets, los márgenes (20px de cada lado excepto del izquierdo) y le indicamos que se ubique en el primer espacio libre a la izquierda que encontramos puesto que de lo contrario los elementos dentro de ubicarán fuera del área deseada. #sidebarHorizontal{ width: 920px; margin:20px; float:left; } Luego procedemos a indicarle al elemento .widget que, sólo cuando se encuentra dentro del área #sidebarHorizontal, debe tener un determinado ancho fijo, ubicarse en el primer espacio libre a la izquierda (float:left;) y tener un margen a la izquierda de 20px. #sidebarHorizontal .widget { width:281px; float:left; margin-left:20px; } Y listo! Pueden experimentar colocar esta nueva sidebar debajo del header, en la plantilla index. php o en donde se les ocurra. Clase 8 Anexo
47
Clase 9: el archivo footer.php El archivo footer.php cumple una función similar al header.php en cuanto a que sirve para cargar scripts y archivos pertenecientes a plugins, tal como indicamos en la Clase 6. En dicho archivo colocamos tres cosas fundamentales: la función wp_footer(), el cierre de la etiqueta y el cierre de la etiqueta . La función wp_footer() es utilizada por muchos plugins para cargar plugins y scripts en general que deban ir al final de la página por sus características de programación o para no demorar la carga de determinados contenidos de la página. La mayoría de los diseños web tienen un pie de página bien definido en donde casi siempre podemos encontrar: • El copyright y/o leyenda del diseñador • Últimos comentarios • Últimas noticias • Últimos mensajes en redes sociales • Información de contacto (e incluso algún formulario de contacto pequeño) • Una barra de navegación secundaria • Publicidades • etc. Nosotros vamos a intentar incorporar un área de widgets, en uno de los cuales insertaremos nuestros íconos sociales, un menú al final de la página que sea réplica del menú princial pero con un estilo diferente, y un link para volver al inicio que animaremos con jQuery.
Area de widgets
Hasta ahora en el div #footer tenemos lo siguiente:
48
Vamos a modificarlo para que dentro haya tres áreas de widgets. En la primera colocaremos cualquier contenido a modo de pruebas, en la segunda colocaremos un área de widgets que crearemos para esta sección y en la tercera dejaremos los íconos sociales. Primero colocamos el código para crear nuestro área de widgets en el functions.php. register_sidebar(array( ‘name’ => ‘Widget Footer’, ‘before_widget’ => ‘
’, ‘after_widget’ => ‘
’, ‘before_title’ => ‘
’, ‘after_title’ => ‘
’, )); Y ahora todo el contenido del #footer. Las rutas a los íconos sociales deben arreglarse para que funcionen cuando el theme esté instalado en cualquier sitio web, por lo que necesitamos usar la función bloginfo() para lograr que éstas sean dinámicas.
El resultado es un área de widgets que tiene fondo gris, como los que agregamos anteriormente en las sidebars.
Sería bueno que los widgets del footer tengan su propio estilo, por lo que añadimos un nuevo estilo para todo .widget que se encuentre dentro de #footer de la siguiente manera: #footer .widget { width:281px; float:left; margin-left:20px; background:none; border:none; padding:0; } #footer .widget h3{ color: #7b7b7b; border-bottom: 2px solid #fff; padding-bottom: 5px; margin-bottom:5px; width:281px; float:left; margin-left:20px; text-shadow: 0px 0px 2px #bdbdbd; filter: dropshadow(color=#bdbdbd, offx=0, offy=0); } #footer .widget p, #footer .widget a, #footer .widget li{ color: #7b7b7b; text-decoration:none; } #footer .widget a:hover { text-decoration:underline; } Al título h3 del widget notarán que le agregué text-shadow. Pueden agregar toda clase de efectos geniales con CSS3 usando este generador de código css3generator.com. Quienes tengan navegadores actualizados a las últimas versiones podrán ver los nuevos efectos, y quienes tengan navegadores mas antiguos verán simplemente el texto sin el efecto, completamente funcional. Los íconos sociales quedaban en dos líneas porque el contenedor resultaba muy angosto, por lo
50
que aumentamos el width y ya caben perfectamente. ul.social { list-style-type:none; float:right; width:190px; padding:0px; margin:0px; }
51
Menú adicional
No resulta mala idea añadir un menú al pie de página. Ayuda a que el sitio resulte mas fácil de navegar. Por eso vamos a repetir nuestro “Menú Principal” debajo pero definitivamente debemos modificar el estilo del mismo. Vamos a utilizar el id #menuFooter para la etiqueta
, así que modificamos y pegamos el siguiente código antes del cierre del div #footer. false, ‘items_wrap’ => ‘
%3$s
’, ‘theme_location’=> ‘menu’, )); ?> Para este segundo menú no vamos a colocar los submenús desplegables debido a que para que funcione correctamente necesitamos pasar un valor fijo para un alto que no conocemos, por lo que ahora evitaremos entrar en un script para calcular cuanto debe trasladarse el submenú y que se abra como corresponde. Hecha esta aclaración, le damos estilo a la nueva clase #menuFooter. #menuFooter { -webkit-box-shadow: inset 0px 3px 1px 0px #ccc; box-shadow: inset 0px 3px 1px 0px #ccc; width: 960px; background: #e1e1e1; border:none; margin: 10px 0 0 0; -webkit-border-radius: 0px 0px 10px 10px; border-radius: 0px 0px 10px 10px; list-style-type:none; float:left; height:35px; } #menuFooter a {
float:left; display:block; text-decoration:none; color:#666; font-weight:bold; margin-left:10px; padding: 10px; border-right: none; background: none; } #menuFooter a:hover { color:#666; background: #f4f4f4; } #menuFooter ul { background:none; list-style-type:none; } #menuFooter li ul { display:none; } #menuFooter ul a { float:left; } Y modificamos el padding de #footer. #footer { float:left; background: #e6e6e6; width: 960px; padding: 20px 0 0 0; }
Volver arriba
El usuario hizo scroll luego de revisar mucho texto y llegó hasta nuestro footer, si necesita volver al inicio de la página para usar el menú desplegable completo o el menú top, nosotros podemos hacerle la tarea mas fácil si le ofrecemos al pié un link que diga “volver arriba” o similar. En nuestro caso, deseamos colocar el link en la misma barra en donde está el menú del footer, sólo que alineado a la derecha para separarlo de los items del menú. Para eso lo agregamos como un elemento mas de la lista #menuFooter pero con una clase diferente. Modificamos las líneas en donde insertamos el menú de la siguiente manera:
’, ‘theme_location’=> ‘menu’, )); ?> De este modo al final de la lista que conforma el menú, metemos el elemento con clase .toTop y dentro un link con href #top. Aprovechando que estamos en la plantilla footer.php, añadimos las siguientes líneas de jQuery luego de las que ya figuran de nivoslider entre etiquetas <script>. $(document).ready(function() { $(‘a[href=#top]’).click(function(){ $(‘html, body’).animate({scrollTop:0}, ‘slow’); return false; }); }); Y finalmente necesitamos indicar en nuestro CSS que el
con class .toTop debe flotar a la derecha. .toTop { float:right; }
Clase 9
53
Clase 10: La plantilla de entrada y de comentarios Las plantillas de vista de entrada son parte esencial del look and feel de un sitio y deben tener un espacio amplio para poder colocar dentro cualquier tipo de contenido (texto, imágenes, videos, descargas, etc). Esta clase, con un poco de suerte, les resultará muy fácil de entender ya que estuvimos viendo los conceptos que trataremos a continuación pero aplicado a otras plantillas. Al visualizar una entrada, WordPress buscará primero la plantilla single.php, y en caso de no encontrarla pasará a mostrar el contenido utilizando la plantilla index.php. Les recuerdo que pueden encontrar una muy buena gráfica sobre jerarquías de plantilla en el sitio oficial.
Single.php, layout y contenido
Es la plantilla para la vista individual de una entrada y su estructura básica es como muestra la siguiente imagen.
54
Pasamos en limpio lo que vamos a hacer: llamamos al header, en el área de contenidos usamos las funciones the_title (el título) y the_content (el contenido), luego llamamos a la sidebar y finalmente al footer. Para que the_title y the_content puedan “traernos” contenido desde la base de datos correspondiente al ID de la entrada que estamos consultando, necesitamos colocarlos dentro del bucle. Esto se traduce en el siguiente contenido (que es el que ya tenemos desde la clase 4).
Lo sentimos, intente utilizar nuestro formulario de búsquedas.
55
La función the_content nos trae todo el contenido publicado en una entrada: su texto, imágenes, galerías, listas, etc. Y para aprovechar la oportunidad aquí es en donde necesitamos definir la alineación de las imágenes que, tal como el editor de WordPress lo señala al subir una imagen, la posición de las mismas puede ser centrada respecto del texto, a la izquierda del texto, a la derecha del texto o sin bordear por texto. Esto se traduce en el siguiente CSS. /* alignments */ .center {text-align: center;} img.center, img[align=”center”] {display: block;margin-left: auto;margin-right: auto;} .alignleft {float: left;} img.alignleft, img[align=”left”] {float:left;margin: 2px 10px 5px 0px;} .alignright {float: right;} img.alignright, img[align=”right”] {float:right;margin: 2px 0px 5px 10px;} .clear {clear:both;} hr.clear {clear:both;visibility: hidden;margin: 0px;padding: 0px;height:0px;} Generalmente en la vista de entrada también se suele colocar información como la fecha de publicación, en qué categoría se encuentra, etiquetas, cantidad de comentarios y el autor. Y para esta sección nos vamos a ayudar con algunos íconos para que la sección luzca lo mejor posible. En este caso nos decidimos por este set de íconos genial llamado gcons. Vamos a construir debajo del cierre del contenedor .dos-tercios, un contenedor con class .metabox en donde colocaremos todas las funciones dentro de etiquetas span para luego insertarles algún ícono. Utilizaremos las siguientes funciones: the_category, the_time, the_author_posts_link, comments_popup_link y the_tags (cada función tiene su link al codex, aprendan a consultarlo).
Publicado el de | Por |
| En la categoría | Con las siguientes etiquetas
El resultado, sin ningún tipo de estilo aplicado:
Los íconos gcons tienen un set en color azul. Tomamos algunos para utilizar en nuestros spans y los llevamos a tamaño 16px x 16px con Photoshop o algún programa de edición. Al .metabox le colocamos un color azul oscuro, tipografía de color blanco, bordes redondeados y un padding para que no queden pegados al borde los elementos que ubicamos dentro. .metabox { padding: 10px; background: #2d435a; color:white; -webkit-border-radius: 10px; border-radius: 10px; margin: 10px 0; display:block; float:left; } La clase .meta se repetirá luego dentro de cada span, los cuales tienen dos clases (ej. class=”category meta” suma dos clases, .category y .meta), por eso colocamos las propiedades background-repeat y background-position, que modificarán el ícono que insertaremos luego en la otra clase de cada span. Colocamos también un padding-left para que el texto deje un espacio para que se vea el ícono. .meta { background-repeat: no-repeat; padding-left:20px; margin-bottom: 4px; float:left; height:16px; background-position: center left; } Y colocamos el link a cada ícono. .time { background-image: url(images/calendar.png); } .author{
Ahora podemos insertar el llamado a la plantilla de comentarios. Bastará con colocar la siguiente función dentro del bucle (o sea, antes del endwhile). Y automáticamente veremos el siguiente contenido.
Si nos fijamos en el código, el HTML generado es el siguiente:
Claro que podemos simplificar un poco si sabemos a lo que apuntamos y podemos ignorar algunas clases muy específicas como .bypostauthor en nuestra etiqueta
. La estructura básica que vamos a tomar es la siguiente:
¿Qué sucedió? Simplificamos. Eliminamos clases que no necesitabamos declarar así como una etiqueta div que contenia a todo el comentario y que resultaba innecesario para un estilo básico.
58
Ahora colocamos las clases y etiquetas correspondientes en el CSS. Al inicio de mi nueva sección coloco entre /* y */ un comentario para utilizar de referencia a futuro. Lo único que agregué que no estaba en el HTML es la clase .comment-awaiting-moderation, que aparece cuando un mensaje está pendiente de moderación, tal como lo dice su nombre. /* Comments! */ ol.commentlist {} ol.commentlist li {} .comment-author {} .comment-author img {} .fn {} .says {} .comment-meta {} .comment-awaiting-moderation {} .comment-meta a {} ol.commentlist li p {} .reply a {} Es importante destacar que vamos a trabajar con comentarios anidados (o sea que puedo responder al comentario de alguien y mi comentario aparecerá debajo del mismo) y del modo en que lo estamos maquetando aparecerá un comentario dentro del otro. Así que lo mejor es utilizar anchos que no sean fijos, sino relativos (o sea que cubran determinado porcentaje del contenedor padre). /* Comments! */ ol.commentlist { list-style-type: none; width:600px; } ol.commentlist li { width:95%; position:relative; overflow:hidden; background: #e1e1e1; -webkit-border-radius: 10px; border-radius: 10px; border: 1px solid #ccc; padding:10px; margin: 10px 0; } .comment-author { width: 60%; float:left; height:40px; } .comment-author img { float:left; border: 1px solid #ccc; margin: 2px; } .fn { color: #2d435a; font-weight:bold;
Claro que no se diferencian bien las respuestas del original. Pero como vimos antes el comentario tiene una clase de acuerdo a su nivel dentro de los comentarios anidados, basta con leer el código HTML generado por esta página:
Existen, entonces, varios niveles de “profundidad” (depth) en nuestros comentarios. Eliminemos el background de ol.comments li y colocamos las siguientes clases con diferentes tonos de gris por fondo: .depth-1 {background: #e1e1e1;} .depth-2 {background: #f1f1f1;} .depth-3 {background: #f9f9f9;} Y obtendremos: 61
Todo esto sin necesidad de generar en ningún momento la plantilla comentarios, utilizando sólo el código por defecto que WordPress genera. Para el caso de que queramos modificar drásticamente nuestra sección de comentarios podemos generar un archivo comments.php o bien podemos hacerlo vía hooks desde el functions.php. En este taller no vamos a ir mas allá, ya que en SummArg constantemente sacamos notas con trucos para personalizar algunas plantillas de modo original. Pero a cambio les vamos a dejar de ejemplo el código que estamos usando en nuestra plantilla para mostrar los comentarios por si les sirve de referencia. En nuestro functions.php colocamos la siguiente función para mostrar los comentarios con código personalizado.
.fn a, .fn{ font-size:12px; font-weight:bold; color: #fff; float:right; text-decoration: none; } .comment-text { background: url(images/comments-arrow.png) no-repeat; background-position: left top; border: 2px solid #405e76; background-color: #f1f1f1; width:407px; float:right; padding: 5px 5px 5px 20px; -moz-border-radius-topleft: 0px; -moz-border-radius-topright: 5px; -moz-border-radius-bottomright: 5px; -moz-border-radius-bottomleft: 0px; -webkit-border-radius: 0px 5px 5px 0px; border-radius: 0px 5px 5px 0px; } La única imagen que agregamos es comments-arrow.png, que no es mas que el triángulo que está al lado del cuadro azul con el avatar y el nombre del comentador. El resultado es el siguiente:
Esperamos que la clase de hoy les haya resultado esclarecedora. Como siempre, les dejamos el demo funcionando y los archivos de la clase para descargar. Clase 10
63
Clase 11: La plantilla de página Las páginas en WordPress se utilizan para publicar contenido estático, fuera del ordenamiento de las entradas, y soportan una estructura de páginas y subpáginas, con un ilimitado número de hijos. También soportan los templates personalizados que nos sirven para aplicar variaciones en el layout con muy pocas modificaciones a nuestras plantillas. Es importante saber que no aparecen en los feeds del sitio. En la clase 8 y la clase 8 anexo, dedicadas a las sidebars, jugamos un poco con la plantilla page. php y le dejamos la siguiente estructura.
64
Esa página es nuestra plantilla por defecto según la última actualización al theme. Por eso vamos a aprender a agregar páginas personalizadas y veamos que opciones tenemos para ello. Por último, vale la pena destacar que las plantillas de páginas soportan comentarios y si bien en esta clase no vamos a colocarlos, pueden seguir los mismos pasos que realizamos en la clase 10 para agregarlos.
Páginas personalizadas
Por un lado podemos optar por colocar desde el nombre del archivo la directiva para que se aplique la plantilla a una determinada página ya sea por su ID o por su slug.
• •
page-{id}.php page-{slug}.php
De este modo, por ejemplo, si colocamos una plantilla con nombre page-10.php, WordPress intentará aplicar dicha plantilla automáticamente a la página con ID 10. Lo negativo de este método es que no permite aplicar una plantilla en particular a varias páginas de forma práctica, pero suele resultar bastante práctico para aplicar un estilo determinado a una única página. Para crear una plantilla que luego se pueda aplicar a diferentes páginas según le indiquemos desde el editor, primero debemos dar al archivo un nombre descriptivo. Nosotros vamos a crear una plantilla de página en donde el contenido abarcará 3/4 del layout y el restante lo usaremos para una sidebar. También removeremos la sidebar horizontal, siendo nuestro objetivo lograr la siguiente estructura.
65
Primer paso: El archivo
Creamos un archivo llamado page-unasidebar.php. No es obligatorio colocar el prefijo page- en el nombre del archivo, simplemente lo hacemos para ser lo mas descriptivos posibles. Para evitar conflictos con el nombre, recuerden revisar el cuadro de Template Hierarchy y verán cuales son los nombres que WordPress se reserva para plantillas en particular. Colocamos en su encabezado el siguiente código comentado dentro de llaves de php.
Segundo paso: El código
La mayoría del código ya lo tenemos, podemos copiar el contenido anterior de page.php, eliminar las dos sidebars extras y modificar el ID del contenedor del texto de #wrapper-dos a #wrapper que ya tiene las medidas necesarias.
Lo sentimos, intente utilizar nuestro formulario de búsquedas.
Tercer paso: Aplicar la plantilla a una página existente
Generar una plantilla por si misma no se refleja en ningún cambio en nuestro WordPress hasta que no asignamos la plantilla a una página existente. Para esto, nos dirigimos a nuestro panel de control y a una página existente le añadimos la plantilla. Guardamos la página al finalizar el cambio.
Páginas y subpáginas
Como mencionamos al principio, las páginas pueden tener subpáginas para ayudarnos a organizar mejor nuestra información. Para generar una subpágina, desde nuestro editor asignamos una página superior a nuestra página actual.
66
Guardamos y vamos a la sección de Páginas en el escritorio. Allí observaremos como se refleja el sistema de jerarquías de página según la página superior asignada en cada caso.
Por último, en la sección de Atributos de Página, cuando estamos en el editor de la página, podemos ver un casillero llamado Orden. El mismo soporta valores numéricos para asignar un orden a las páginas que tengan la misma jerarquía. Ya que las páginas no se destacan por su orden cronológico, como las entradas, es muy útil poder asignar mediante este método el orden en el que deseamos que se muestren nuestras páginas. 67
Mostrar las subpáginas que tiene una página
La ubicación mas utilizada para mostrar subpáginas generalmente es en algún sitio de la sidebar, por lo que vamos a colocar un condicional para nuestra sidebar.php. En el mismo necesitamos comprobar si existen hijos de la página actual, caso contrario no debe mostrarse nada. Si el condicional resulta afirmativo (es una página y no una entrada o una categoría, y además resulta tener hijos), entonces se mostrará el título “Subpáginas” y desplegamos debajo el resultado de $children, en donde usamos la función wp_list_pages. El código debe ir luego de abrir el div #sidebar. ID.'&echo=0'); if ($children) { ?>
Subpáginas
Agregaremos un poco de estilo para que se muestre un poco mas prolijo. ul.subpages { margin:0; margin-left:10px; } .subpages li { list-style-type: circle; margin: 4px 0 4px 10px; text-indent:-5px; border-top: 1px solid #f9f9f9; padding: 2px 0 0 5px;; } ul.subpages li ul {
margin:0; } .subpages li a { text-decoration:none; } Realizamos un cambio en la plantilla de estilos en donde eliminamos los elementos #sidebar ul y #sidebar li, y creamos la clase .sidebarNews en nuestra lista de noticias en la Sidebar.
La nueva clase en el CSS. ul.sidebarNews { list-style-type:none; margin-bottom:20px; } ul.sidebarNews li { padding: 5px 10px; border-bottom: 1px solid #7b7b7b; color: #7b7b7b; } ul.sidebarNews li a{ text-decoration:none; color: #7b7b7b; } De ese modo podemos dar estilos diferentes a los listados que aparezcan dentro de la sidebar. Añadimos varios elementos hijos y nietos a la página con la que iniciamos las pruebas de esta clase y obtuvimos el siguiente resultado.
Pueden ver el ejercicio en funcionamiento en el demo online.
Plantillas de página con query_posts
Nada nos impide que usemos las plantillas de página para colocar consultas con query_posts, tal como vimos en la clase 5, y en esta oportunidad vamos a ver como crear una página en donde mostrar una categoría de productos de un modo diferente al que usaremos luego en las plantillas
68
de categoría. Primero generamos una categoría llamada “Productos”. Antes de subir contenidos a dicha categoría, vamos a establecer en el functions.php el tamaño de la miniatura, para no tener que regenerarlas luego. add_image_size( ‘producto’, 195,195,true ); Subimos los artículos que necesitemos para ir probando nuestro theme y recordamos marcar como destacadas las imágenes que asignemos. Creamos un archivo llamado page-misproductos. php y en su interior colocaremos el código que explicaremos por partes. Primero el encabezado del template. Abrimos un contenedor con id #wrapper-full y colocamos el primer bucle, destinado a buscar el contenido de la página y tomar de él el título y el contenido. Cerramos el bucle.
Finalmente colocamos los links de navegación, cerramos el contenedor y llamamos al footer.
Siguientes’,’
Anteriores
’); ?> div>
69
Ahora vamos a darle un poco de estilo a la página. Primero definimos las propiedades que va a tener el contenedor de la página, que ocupa todo el ancho, el título y la descripción. #wrapper-full { width:920px; float:left; margin: 20px; } #wrapper-full h1 { text-align:center; padding: 20px 0 5px 0; border-bottom: 3px solid #7ec5ff; font-size:32px; } .descripcion p{ text-align:center; font-size:13px; line-height:18px; color: #7ec5ff; font-weight:bold; } .descripcion { margin: 0 0 10px 0; } Ahora daremos forma a los contenedores de producto añadiendo color de fondo, de bordes, sombras y un tamaño específico para el título. .producto { float:left; width: 205px; height:225px; padding: 5px; margin: 6px; -webkit-border-radius: 5px; border-radius: 5px; border: 1px solid /*#2d435a; #7ec5ff;*/ #e9e9e9; background-color: #f4f4f4; -webkit-box-shadow: 0px 0px 1px 1px #999; box-shadow: 0px 0px 1px 1px #999; } .producto img { border: 1px solid #b4b4b4; -webkit-border-radius: 5px; border-radius: 5px; } .producto h2 { font-size:14px; text-align:center; line-height:22px;
70
font-weight:bold; } .producto h2 a { color: #999; } Finalmente damos estilo a la paginación para que aparezca siempre abajo. .navigation { width: 920px; margin:20px 0; height:20px; display:block; float:left; } El resultado será el siguiente. 71
Encontrarán el ejercicio en nuestro demo online. Pueden descargar el theme completo desde aquí: themeTaller11
Clase 12: archive.php y plantillas por categoría, fecha, autor, taxonomía, etiqueta. Antes de arrancar con las plantillas de archivo en general, vamos a actualizar un poco el header. php de nuestro theme en función de adaptarlo a los requerimientos actuales con Facebook. Antes que nada, incluyamos un favicon, porque sino el theme se ve aburrido en nuestros navegadores.
72
Acto seguido, vayamos colocando algunas etiquetas para que Facebook tome la información como nosotros queremos en cuanto al home, los interiores los dejaremos para que naturalmente tome los datos del cuerpo del contenido. <meta property='og:locale' content='es_ES'/> <meta property='og:type' content='website'/> <meta property='og:title' content='themeTaller'/> <meta property='og:description' content='Un theme WordPress para aprender'/> <meta property='og:url' content='http://www.summarg.com/demos/themetaller/'/> <meta property='og:site_name' content='themeTaller'/> <meta property="og:image" content="/images/avatar.png"> Por avatar.png debemos subir una imagen de mas de 350px x 350px. Para ver la información que Facebook toma de nuestras urls podemos usar la herramienta llamada Depurador.
Y constantamos en Facebook compartiendo el link en cuestión:
73
Listo! Ahora si, vamos a lo nuestro. Como ya vimos en la clase 4, la plantilla archive.php agrupa todos los listados de posts por: categorías, autor, fechas, etiquetas, custom post types archive y custom taxonomies. Esto significa que si solicitamos un listado de entradas de la categoría con id 4 (miblog.com/?cat=4), WordPress primero buscará la plantilla para esa categoría específica, que sería category-4.php. Al no encontrarla, busca la plantillas de categorías en general, category.php. Si no existe, utiliza archive.php, si a su vez tampoco existe entonces buscará index.php. Lo mismo sucede para etiquetas, autor, fecha, y las demás. Existe una jerarquía que WordPress recorre en un orden específico. Tomemos el caso de dos categorías de nuestra instalación de prueba, la categoría productos (id 111) y la categoría blog (id 45). Podríamos crearles una plantilla para cada uno generando el archivo category-productos.php y category-blog.php, respetando la primera forma que busca WordPress que es category-$slug.php. O bien podríamos llamarlos caregory-111.php y el category-45. php, con el formato category-$id.php. Pero vamos a usar archive.php con Conditional Tags, sólo por el placer de usar tantos condicionales. En un sitio normal con muchas visitas no nos conviene tener un archivo con tantos condicionales como lo vamos a crear ahora, y resulta mas efectivo crear tantos archivos como sea necesario. Pero estamos aprendiendo y esto es un gran experimento. Esto es lo que tenemos hasta ahora en nuestro archive.php:
Lo sentimos, intente utilizar nuestro formulario de búsquedas.
Vamos a tener dos objetivos simples. El primero es que cuando se muestre la categoría de productos se vea tal como está en la página de productos, así que tomaremos gran parte del código que está en la página personalizada que construimos la clase anterior. El header y el footer se mantienen, en todas las plantillas necesitamos de estos dos, así que vamos a manejarnos en el medio de ese espacio. Colocamos debajo de la llamada al header nuestro condicional con el correspondiente else. Cabe mencionar que necesitamos colocar un exit a cada if, ya que cuando se cumpla la condición dada (ej. estamos en la categoría 111) se va a mostrar ese código y adicionalmente también se va a mostrar el que coloquemos dentro del else, ya que ambas condiciones se cumplen de algún modo. El exit corta o escapa a todo el conjunto una vez que una se cumple.
Antes de la llamada al footer hay que colocar otra llave cerrando todo. Cabe destacar que lo que tendríamos que lograr es que no haya tantas aperturas y cierres de php, por lo que la línea anterior bien la podríamos convertir en esto: Pero como dijimos antes, estamos aprendiendo y la intención es que les resulte bien claro lo que vamos haciendo. Lo importante es que tengan presente que lo que ven acá es un pantallazo para entender como funciona el tema y de ahí progresar. Ahora si vamos a nuestra categoría de productos, podemos ver el listado de productos de la categoría “productos” y de sus subcategorías, en el formato que escogimos. Podemos ver el resultado en el demo online. Pasemos a darle un formato diferente a las entradas en la categoría blog para que quede del siguiente modo, sin barra lateral:
74
En la línea superior a la del else, colocamos la nueva condición y le daremos un formato distinto a nuestros contenedores.
Y en el CSS definimos este nuevo contenedor para que tenga su propio estilo. .blog { width: 435px; height: 210px; float:left; margin: 5px; padding:5px; -webkit-border-radius: 5px; border-radius: 5px; border: 1px solid #e9e9e9; background-color: #f4f4f4; } .blog a { text-decoration:none;
75
color: #333; } .blog img { float:left; margin: 5px 10px 0 0; border: 2px solid #e9e9e9; } .blog h2 { margin-top:5px; font-size:20px; line-height:24px; } .blog a h2 { text-decoration:none; color: #333; } .blog:hover { background-color: #ccc; } Podemos ver el resultado del ejercicio en esta ubicación. Ahora hagamos una plantilla para mostrarse cuando el usuario solicite las entradas de un autor. Al igual que en el caso de las categorías, cuando se solicite el listado por autor, WordPress dará prioridad a la búsqueda de plantillas de la siguiente manera: 1. author-$nicename.php: En donde $nicename es el nombre de usuario del autor solicitado. 2. author-$id.php: En donde $id es el id de usuario del autor. 3. author.php: Plantilla genérica para todos los autores 4. archive.php: El nuestro! 5. index.php Vamos a usar nuevamente un condicional tag y a pensar en cómo queremos mostrar la página. Nuestro objetivo será colocar arriba del listado (fuera del loop) la información que podamos sobre el autor solicitado. Y aquí tenemos un problema puesto que todas las funciones con get_the_author() y similares funcionan dentro del loop. Pero una de las maravillas de WordPress es su documentación y la enorme comunidad que escribe sobre estos temas, así que le echamos una leída al snippet que publicó Kevin Muldon en WPHub y tomamos lo que necesitamos para construir nuestro recuadro de autor.
76
Luego del recuadro de autor (identificado con la class authorInfo) procedemos a colocar el bucle como siempre, con unos contenedores que esta vez contemplarán el espacio que necesita la sidebar para mostrarse. El código PHP quedará de la siguiente manera:
El CSS para esta nueva sección quedaría de la siguiente manera: .authorInfo { width: 586px; padding: 10px; float:left; margin: 0 0 20px 20px; -webkit-border-radius: 5px; border-radius: 5px; border: 1px solid #e9e9e9; background-color: #f4f4f4; } .authorInfo h2 { color: #7ec5ff; } .unTercio { width: 285px;
77
float:left; margin: 0 0 20px 20px; border-bottom:1px solid #e9e9e9; } .unTercio a { text-decoration:none; color: #333; } .unTercio img { float:left; margin: 5px 10px 0 0; border: 2px solid #e9e9e9; } .unTercio h2 { margin-top:5px; font-size:20px; line-height:24px; } .unTercio a h2 { text-decoration:none; color: #333; } .unTercio:hover { background-color: #f4f4f4; } Y el resultado puede verse en el siguiente ejemplo con un autor de nuestro demo. Finalmente vamos a construir una plantilla para tags (etiquetas) que sea prácticamente igual a la de autor con la diferencia de que queremos que se muestre la nube de etiquetas arriba de todo en un estilo que se adapte a nuestro trabajo.
El código PHP deberá utilizar el tag single_tag_title() para llamar al nombre del tag y utilizarlo en nuestro título, luego colocamos la función wp_tag_cloud() sin parámetros para mostrar la nube de tags y el bucle sigue igual que en el de autor.
Para el CSS unicamente añadimos lo siguiente: .authorInfo, .tagCloud { width: 586px; padding: 10px; float:left; margin: 0 0 20px 20px; -webkit-border-radius: 5px; border-radius: 5px; border: 1px solid #e9e9e9; background-color: #f4f4f4; } .tagCloud a{ text-decoration:none; } Comprobamos que la nube y el listado se muestren correctamente en este link. Pueden descargar el theme desde aquí: themeTaller 12
79
Clase 13: Página de búsquedas e integración con Google Custom Search Engine Por defecto WordPress utiliza el template search.php para mostrar sus resultados de búsquedas, si no encuentra dicha plantilla entonces utiliza index.php. Vamos a colocar un pequeño formulario de búsqueda en el encabezado del sitio. Buscaremos lograr lo que se muestra en la siguiente imagen:
Para ello utilizaremos el siguiente código que podremos después del primer menú:
Para el estilo, primero añadiremos a #header un nuevo selector position:relative; #header { padding: 5px 20px; width:920px; height:110px; position:relative; } De este modo ahora todos los elementos que estén dentro de las etiquetas de #header pueden utilizar posicionamiento en relación al padre. Procedemos a darle estilo a nuestro formulario. #search { width: 185px; border:1px solid #7ec5ff; position:absolute; right:20px; bottom:20px; -webkit-border-radius: 3px; border-radius: 3px; } #search form input#s { width:180px; height:20px; font-size:11px;
80
font-style:italic; padding: 0 0 0 5px; background-image:url(images/lupa.png); background-position:right center; background-repeat:no-repeat; border:none; } #search form input[type=button] { display:none; } Verán que nuestro #search utiliza el selector position y con el valor absolute nos permite definir un top y un right. Les recomiendo que lean la documentación sobre positioning aquí y aquí. El archivo de lupa.png se encuentra dentro del nuevo paquete para descargar con la presente clase al pie de página. El botón necesitamos que exista, pero no necesitamos que se vea, por lo que le damos la indicación para que no se muestre. Cuando el usuario ingrese su búsqueda y presione enter, la búsqueda se iniciará sin necesidad alguna de clickear un botón. WordPress buscará la plantilla search.php a la cual le colocaremos un layout estandar.
Lo sentimos, intente utilizar nuestro formulario de búsquedas.
Siguientes','
Anteriores
'); ?>
Utilizamos la función the_search_query para mostrar en el título el término de búsqueda que introdujo el usuario. Con esto ya nos queda la función de búsquedas de WordPress bastante completa.
Custom Search Engine de Google
Introduzcamos un formulario de búsquedas personalizadas de Google en nuestro theme. Las razones son varias: • Posibilidad de monetizar nuestras búsquedas: Google CSE permite el uso de Google Adsense. • Mejoras en el rendimiento del servidor al ahorrarnos las consultas a la base de datos. • Permite buscar en varios sitios a definir por nosotros. • Es de Google, necesitamos decir mas?
81
Para crear una cuenta para nuestro sitio nos dirigimos a www.google.com/cse, le damos nombre a nuestro buscador, definimos el idioma, los sitios en los que habrá de buscar y activamos Adsense si lo deseamos. Lo que necesitamos de todo este proceso es la ID del motor de búsqueda generado.
82
Ahora bien, no queremos destruir el formulario de búsqueda que hemos agregado recientemente, así que añadiremos nuestro nuevo formulario en una de las sidebars.
En el value del primer input debemos colocar el ID del motor de búsqueda que acabamos de generar. Emprolijamos un poco desde el style.css form#cse-search-box input#s { width: 220px; float:left; } form#cse-search-box input[type=submit] { float:left; border: 1px solid #7ec5ff; background-color: #7ec5ff; color: white;
height:22px; font-weight:bold; font-size:11px; margin: 0 0 0 5px; width:45px; overflow:hidden; } Comprobamos que se muestre correctamente en nuestro theme.
Ahora debemos colocar nuestra plantilla de resultados, que se llamará resultados.php. La misma contiene la estructura básica de cualquier plantilla con la salvedad de que en vez de colocar un bucle sólo colocaremos el script de Google CSE. Además vamos a colocar este archivo fuera del directorio de nuestro theme, directamente en el raíz del sitio, por lo que en la primer línea utilizaremos una llamada para poder utilizar nuestro theme normalmente. resultados.php
<script type="text/javascript"> var googleSearchIframeName = "cse-search-results"; var googleSearchFormName = "cse-search-box"; var googleSearchFrameWidth = 600; var googleSearchDomain = "www.google.com"; var googleSearchPath = "/cse"; <script type="text/javascript" src="http://www.google.com/afsonline/ show_afs_search.js">
Y efectuamos una búsqueda a modo de prueba.
83
Nuestro theme ya tiene dos formularios de búsqueda totalmente funcionales. Podés verlo en nuestro demo online. Descargá la clase: themeTaller 13
84
Clase 14: Paginación, breadcrumbs y página de error 404.php Esta clase podría considerarse la última en lo que a detalles para construir un theme completo y funcional respecta. La paginación, los breadcrumbs (camino de migajas) y la página de error dan la terminación justa a nuestro proyecto. Claro que nos quedan cinco clases mas en donde abordaremos temas mas complejos, como los custom post types y la instalación de un framework que nos permita insertar opciones a nuestro theme. Por favor chequeen el temario y si consideran que quedó fuera algún tema importante, háganlo saber mediante un comentario o un mensaje privado desde nuestro formulario de contacto. Comenzaremos reemplazando la paginación por defecto que WordPress nos ofrece (que consiste en links de anterior y siguiente) y colocaremos algo mas vistoso.
Actualmente el plugin mas utilizado para lograr esto es wp-pagenavi, pero en esta oportunidad insertaremos una paginación sin utilizar ningún plugin. Meramente creamos la función y la insertamos en nuestro functions.php function wp_pagenavi() { global $wp_query, $wp_rewrite; $pages = ''; $max = $wp_query->max_num_pages; if (!$current = get_query_var('paged')) $current = 1; $args['base'] = str_replace(999999999, '%#%', get_pagenum_ link(999999999)); $args['total'] = $max; $args['current'] = $current; $total = 1; $args['mid_size'] = 3; $args['end_size'] = 1; $args['prev_text'] = ''; $args['next_text'] = ''; if ($max > 1) echo '
'; } Las dos imágenes que mencionamos en los argumentos se entregan en el RAR que pueden descargar al pié del tutorial. La función lo que hace es obtener las cantidades máximas de páginas existentes en la query y darle un formato que contenga mas información y nos permita navegar salteando páginas si lo deseamos. Ahora abrimos nuestro archive.php y reemplazamos estas líneas:
-moz-border-radius: 3px; -webkit-border-radius: 3px; display:block; float:left; } .wp-pagenavi img { height:20px; width:25px; margin-top:0px; } Y con ello bastará.
Breadcrumbs, migajas de pan 87 El breadcrumb es útil para permitirle al usuario volver a una instancia anterior dentro de un árbol de categorías, o para saber en donde está y su relación con el inicio. Existen varios plugins para insertar breadcrumbs que ya vienen con estilos y son muy bonitos, pero nosotros crearemos la función en nuestro functions.php, ya que esto nos dará la oportunidad de personalizarlo si lo deseamos. Básicamente lo que hace la función es preguntarse en donde se encuentra mediante conditional tags y en base a ello muestra diferentes funciones, ya sea el título, el árbol de categorías, la fecha, etc. /*Breadcrumbs*/ function the_breadcrumbs() { echo '
'; } /*End of Breadcrumbs*/ Añadimos un estilo muy básico. .breadcrumb { width: 100%; float:left; display:block; } .breadcrumb p a { text-decoration:none; } .breadcrumb p { font-size:12px; } E insertamos la función en archive.php debajo del div id#wrapper y debajo de cada apertura de un div contenedor de modo de atender todos los condicionales: Es un código muy sencillo y no es del todo completo, pero sirve a nuestros propósitos. La función puede insertarse en la plantilla single.php, page.php, search.php, incluso en el home aunque no parece necesario. Es a criterio del desarrollador. Finalmente necesitamos elaborar una página de error 404. Esta página se visualiza cuando el usuario solicita una URL inexistente, ya sea porque se cambió la URL adrede, o bien se borró dicha entrada, o cualquier otro motivo. La plantilla que debemos crear es: 404.php
Error 404
Lo sentimos, el contenido que está intentando visualizar no se encuentra o fue movido a otra parte. Por favor utilice nuestro formulario de búsquedas
88
El formulario es el mismo que el del header, pero debemos cambiar leves detalles (por ejemplo, cambiar el posicionamiento absoluto a un float) y además no podemos usar un id dos veces, así que lo reemplazamos. #searchInner { width: 185px; border:1px solid #7ec5ff; float:left; -webkit-border-radius: 3px; border-radius: 3px; } #searchInner form input#q { width:180px; height:20px; font-size:11px; font-style:italic; padding: 0 0 0 5px; background-image:url(images/lupa.png); background-position:right center; background-repeat:no-repeat; border:none; } #searchInner form input[type=button] { display:none; } Si ingresamos una url cualquiera (ej. http://www.summarg.com/demos/themetaller/asdasdasd) Obtendremos el siguiente resultado:
Si googlean imágenes de “error 404″ van a encontrar ideas muy divertidas y originales para utilizar en este tipo de páginas. Pueden descargar la clase de hoy desde aquí: themeTaller 14
89
Clase 15: Framework para opciones administrativas e inserción de anuncios
Nuestro theme ya está listo, pero ¿cómo podemos hacernos la vida mas simple a la hora de gestionar los anuncios de un sitio? Sabemos que colocar anuncios Adsense acá y allá es cosa de una vez, pero el asunto se vuelve mas complejo si además vendemos espacios de forma mensual y nuestros anunciantes cambian con frecuencia. Vamos a retomar una herramienta que les presentamos hace tiempo, que es gratuita y se integra a nuestro theme muy bien: Options Framework Theme de WP Theming (tiene una versión paga con varias herramientas muy interesantes). Esta herramienta, que podemos descargar desde github, nos permite usar variables personalizadas en situaciones diferentes de las que vamos a plantear en esta clase. Pensemos que nos puede permitir ingresar el código hexadecimal de un nuevo color de fondo, o texto para incluir en un área en donde no queremos usar widgets, trozos de código completos, mensajes globales a usuarios, etc. Lo primero que necesitamos hacer es descomprimir el paquete y colocar el siguiente código al inicio de nuestro functions.php, después de la etiqueta
Ahora editemos el archivo options.php, que es en donde podremos gestionar las pestañas y sus contenidos dentro de Theme Options.
90
Para eliminar el contenido de pruebas debemos borrar desde la línea 105 del options.php hasta la 288. Vamos a buscar añadir dos sectores de publicidad a los que le añadiremos una imagen y su respectivo link, y aprovechamos a completar los tres cuadros de texto que figuran debajo del slider desde las opciones de nuestro theme. 91
Vamos a trabajar insertando las opciones a partir de la línea 105. Primero generamos el encabezado de nuestra sección “Publicidad”. $options[] = array( 'name' => __('Publicidad', 'options_framework_theme'), 'type' => 'heading'); Luego añadimos dos campos de texto que vamos a usar para colocar los links, y dos campos de upload para las imágenes. $options[] = array( 'name' => __('Link Ad Header', 'options_framework_theme'), 'desc' => __('Link conteniendo http://...', 'options_framework_theme'), 'id' => 'link_ad_header', 'type' => 'text'); $options[] = array( 'name' => __('Imagen Ad Header', 'options_framework_theme'), 'desc' => __('400x60px', 'options_framework_theme'), 'id' => 'image_ad_header', 'type' => 'upload'); $options[] = array( 'name' => __('Link Ad Footer', 'options_framework_theme'), 'desc' => __('Link conteniendo http://...', 'options_framework_theme'), 'id' => 'link_ad_footer', 'std' => 'Default', 'type' => 'text'); $options[] = array( 'name' => __('Imagen Ad Footer', 'options_framework_theme'), 'desc' => __('281x100px', 'options_framework_theme'), 'id' => 'image_ad_footer', 'type' => 'upload'); El parámetro name especifica el título de nuestro campo, desc sirve para colocar una descripción que se verá debajo del título, id se utiliza luego para invocar al contenido del elemento, type define el tipo de campo que será. También tenemos adicionalmente class (para elegir algunas variantes de type) y std que sirve para colocar contenido por defecto.
92
Abrimos nuestro header.php y colocamos el siguiente código luego del div#logo:
Con ello establecemos un condicional en el que si encuentra que #image_ad_header (nuestro id de la imagen para el header) tiene contenido, entonces coloca un div.adHeader y en su interior el link con el contenido de #link_ad_header y la imagen del id ya mencionado. Le damos un poco de estilo a la clase que acabamos de crear. .adHeader { width: 400px; height:60px; float:left; margin: 35px 0 0 10px; } Subimos contenido para estos dos campos.
Y confirmamos que se vea como lo deseamos.
Excelente! Ahora procedemos a repetir la operación pero esta vez en el footer. Aprovechamos a comentar que la clase .widget en el footer debería tener 293px de ancho, así que lo corregimos, del mismo modo la imagen del aviso deberá tener ese valor para su ancho. Podemos usar dicha clase para colocar dentro nuestra imagen en caso de que exista.
Finalmente vamos a nuestra sección de destacados. Hasta ahora lo veníamos manejando con publicaciones en la categoría Productos Destacados, pero dado el formato que necesitamos queda algo desprolijo y se nos ocurre que podríamos mejorarlo de este modo. Además suponemos que puede haber muchísimas entradas y que cuando el dueño del sitio decida modificar los destacados puede cometer varios errores, como excederse en la cantidad de texto o colocar una imagen dentro, y eso rompería nuestro home. Este es el código que tenemos ahora.
Vamos a crear en options.php tres campos para cada uno de los destacados, uno para el título, otro para el texto y uno mas para el link. Nos quedarán un total de nueve campos. Les mostramos los primeros tres junto con el separador para que todo esto esté en una pestaña a la que llamaremos “Destacados”. $options[] = array( 'name' => __('Destacados', 'options_framework_theme'), 'type' => 'heading'); $options[] = array( 'name' => __('Titulo destacado 1', 'options_framework_theme'), 'id' => 'titulo_destacado_1', 'std' => 'Default Value', 'type' => 'text'); $options[] = array( 'name' => __('Link destacado 1', 'options_framework_theme'), 'id' => 'link_destacado_1', 'type' => 'text'); $options[] = array( 'name' => __('Texto destacado 1', 'options_framework_theme'), 'id' => 'textarea_destacado_1', 'type' => 'textarea'); Y en el index.php reemplazamos el bucle que llama a los tres elementos por:
Los links que añadimos van a generar un subrayado que no vamos a querer, así que lo eliminamos vía CSS y de paso le cambiamos el color de fondo a cada elemento cuando se le hace un hover. .item a { text-decoration:none; } .item:hover { background-color:#f4f4f4; }
Nuestro panel va a quedar con dos pestañas ahora:
95
Podemos ver el resutado en nuestro demo, y descargar la clase de hoy themeTaller 15. Antes de finalizar queremos destacar que el framework que elegimos contiene las siguientes opciones de campos para incluir: • Campos de texto (pequeños, medianos, largos) • Textarea con el editor • Upload de archivos • Radio buttons • Checkboxes • Selects • Select con las páginas de WordPress • Select con las categorías de WordPress • Select con las etiquetas de WordPress • Color picker • Selector de imágenes precargadas Todas estas opciones nos dan mucho margen de trabajo para hacer un theme amigable y completo. Además de ser fácil de entender, es muy liviano y cuenta con la posibilidad de comprar la licencia para extender sus funciones.
96
Clase 16: Custom Post Types: Portfolio y plantilla single-cpt.php. En esta clase y en las dos siguientes vamos a intentar tocar los aspectos mas relevantes a los Custom Post Types, con los que daremos vida a un portfolio que puede serles de utilidad para exhibir toda clase de productos, películas, libros, etc. Los Custom Post Types son la máxima expresión de contenido personalizado dentro de WordPress, podemos hacer que se comporten como posts o páginas, que usen categorías, taxonomías, etiquetas, todas o ninguna. Tienen su propio lugar en nuestro escritorio de la plataforma y nos dan una amplia flexibilidad a la hora de crear contenidos. También, vale aclarar, nos permite separar estos contenidos de las páginas y las entradas comunes. Pueden comenzar a leer sobre este tema en el codex de WordPress en este link. Nosotros iremos directo al grano y para ello lo primero que vamos a hacer es definir el tipo de contenido “Portfolio” desde el functions.php. add_action( 'init', 'register_cpt_portfolio' ); function register_cpt_portfolio() { $labels = array( 'name' => _x( 'Portfolio', 'portfolio' ), 'singular_name' => _x( 'Portfolio', 'portfolio' ), 'add_new' => _x( 'Agregar', 'portfolio' ), 'add_new_item' => _x( 'Agregar trabajo', 'portfolio' ), 'edit_item' => _x( 'Editar trabajo', 'portfolio' ), 'new_item' => _x( 'Nuevo trabajo', 'portfolio' ), 'view_item' => _x( 'Ver trabajo', 'portfolio' ), 'search_items' => _x( 'Buscar en Porfolio', 'portfolio' ), 'not_found' => _x( 'No se encontraron trabajos', 'portfolio' ), 'not_found_in_trash' => _x( 'No se encontraron en la papelera', 'portfolio' ), 'parent_item_colon' => _x( 'Parent Portfolio:', 'portfolio' ), 'menu_name' => _x( 'Portfolio', 'portfolio' ), ); $args = array( 'labels' => $labels, 'hierarchical' => false, 'description' => 'Trabajos que realizamos recientemente', 'supports' => array( 'title', 'editor', 'thumbnail', 'customfields' ), 'public' => true, 'show_ui' => true, 'show_in_menu' => true, 'show_in_nav_menus' => true, 'publicly_queryable' => true, 'exclude_from_search' => false, 'has_archive' => true, 'query_var' => true, 'can_export' => true, 'rewrite' => true, 'capability_type' => 'post' ); }
register_post_type( 'portfolio', $args );
97
Mediante este código registramos el post type asignándole todos los valores necesarios para que se conviertan en un tipo de entradas que acepta archivo, que se muestra en los menúes, que se puede exportar, que soporta los campos de título, el editor, miniaturas y custom fields, etc. Existe un generador de código muy bueno que elaboró la gente de themergency.com en este link. Al completar el formulario en varios pasos obtenemos el código resultante de nuestras especificaciones. Vamos a querer asignarle categorías a nuestras entradas, y queremos definir las mismas de modo independiente al resto de las entradas comunes, así que para ello seguimos colocando código en nuestro functions.php: function register_portfoliotaxonomies() { $labels = array( 'name' => _x( 'tipos', 'taxonomy general name' ), 'singular_name' => _x( 'tipo', 'taxonomy singular name' ), 'add_new' => _x( 'Agregar tipo', 'tipo'), 'add_new_item' => __( 'Agregar tipo' ), 'edit_item' => __( 'Editar tipo' ), 'new_item' => __( 'Nuevo tipo' ), 'view_item' => __( 'Ver tipo' ), 'search_items' => __( 'Buscar tipos' ), 'not_found' => __( 'No encontrado' ), 'not_found_in_trash' => __( 'No encotrado' ), ); $pages = array('portfolio'); $args = array( 'labels' => $labels, 'singular_label' => __('tipo'), 'public' => true, 'show_ui' => true, 'hierarchical' => true, 'show_tagcloud' => false, 'show_in_nav_menus' => true, '_builtin' => false, 'rewrite' => array('slug' => 'porfoliotax','with_ front' => FALSE ), ); register_taxonomy('portfoliotaxonomies', $pages, $args); } add_action('init', 'register_portfoliotaxonomies'); De este modo generamos las categorías para “Portfolio”. Pueden revisar una descripción de los parámetros de register_taxonomy en el codex. Procedemos a completar con algunas categorías antes de subir material. Necesitamos tener algunas entradas ingresadas para poder trabajar, así que vamos a crear un portfolio de una empresa de marketing y diseño.
98
Ahora si podemos proceder a agregar algunas entradas en diferentes categorías. A medida que lo hagamos veremos que tenemos problemas para visualizar los contenidos (salvo que no estén usando URLs amigables), por lo que debemos recrear los permalinks. El modo mas sencillo es cambiando la configuración un momento a predeterminado y volviéndola a cambiar a la que hayamos elegido.
Metabox: Los custom fields de forma fácil
Vamos a echar mano a un recurso muy útil en esa nueva sección: los metaboxes. Estas cajas son una versión sofisticada para manejar los valores de custom fields, dejando al usuario un entorno mas amigable para completar los campos. Vamos a crear tres campos de texto y un campo con dos radio buttons. Los datos que recabemos con los tres primeros elementos serán usados en clases por venir, pero los radio los vamos a usar hoy mismo.
'context' => 'normal', 'priority' => 'high', 'fields' => array( array( 'name' => 'Cliente', 'desc' => 'Nombre del cliente', 'id' => 'cliente', 'type' => 'text', 'std' => 'Un Cliente' ), array( 'name' => 'Socios', 'desc' => 'Nombre del/los socios', 'id' => 'socios', 'type' => 'text', 'std' => '' ), array( 'name' => 'Descripcion', 'desc' => 'Descripcion corta para la portada', 'id' => 'descripcion', 'type' => 'text', 'std' => '' ), array( 'name' => 'Layout', 'id' => 'layout', 'type' => 'radio', 'options' => array( array('name' => 'Layout1', 'value' => 'Layout1'), array('name' => 'Layout2', 'value' => 'Layout2') ) ) ) ); add_action('admin_menu', 'mytheme_add_box'); // Add meta box function mytheme_add_box() { global $meta_box; add_meta_box($meta_box['id'], $meta_box['title'], 'mytheme_show_box', $meta_box['page'], $meta_box['context'], $meta_box['priority']); } // Callback function to show fields in meta box function mytheme_show_box() { global $meta_box, $post; // Use nonce for verification echo ''; echo '
'; foreach ($meta_box['fields'] as $field) {
100
// get current post meta data $meta = get_post_meta($post->ID, $field['id'], true); echo '
', '
', '
'; switch ($field['type']) { case 'text': echo '', ' ', $field['desc']; break; case 'textarea': echo '', ' ', $field['desc']; break; case 'select': echo ''; break; case 'radio': foreach ($field['options'] as $option) { echo '', $option['name']; } break; case 'checkbox': echo ''; break; } echo '
', '
'; } echo '
';
} add_action('save_post', 'mytheme_save_data'); // Save data from meta box function mytheme_save_data($post_id) { global $meta_box; // verify nonce if (!wp_verify_nonce($_POST['mytheme_meta_box_nonce'], basename(__
Esos radio buttons los vamos a usar para crear dos estilos diferentes de archivo single para nuestro custom post type.
La plantilla single-cpt.php
Arranquemos a generar la plantilla para visualizar un elemento. Recordemos lo referente a jerarquías de plantillas (template hierarchy) y según el mapa de plantillas necesitamos crear un archivo single-portfolio.php. Vamos a crear tres plantillas en una usando condicionales en base a ese campo “Layout”. La primera de ellas contendrá un cuadro con los datos del metabox arriba de todo, y en la barra lateral lista entradas de la misma categoría.
102
Veamos la primera parte de nuestro código en single-portfolio.php. La estructura de colocar al inicio un get_header() seguido de un div que haga de contenedor es igual en todas. Lo que nosotros necesitamos es inmediatamente obtener el valor del custom field layout por lo que primero llamamos a la variable global $post y luego procedemos a usar get_post_meta. Construimos un contenedor con los valores de cliente, socios y descripción, a la que le colocamos una miniatura a la izquierda (para obtener la miniatura pequeña por defecto de WordPress usamos ‘thumb’). Seguidamente, y siempre dentro del bucle, colocamos las funciones para llamar al título y al contenido.
En la segunda parte de nuestro Layout1 queremos encargarnos de colocar en la barra lateral otras entradas de la misma categoría. Esto ya resulta fácil para nosotros, ¿no es cierto? De paso dejo establecidos los condicionales para los otros Layouts, por el momento no se verá nada mas que un texto.
Necesitamos definir el tamaño de la imagen destacada, colocamos el siguiente valor en nuestro functions.php: add_image_size( 'portfolio', 230,130, true ); Y hasta aquí nuestro CSS. .wrapperPortfolio { width: 940px; float:left; margin: 20px 0 20px 20px; } .portfolioUno { width: 670px; float:left; } .sidebarPortfolio { width: 230px; margin: 20px 0 0 20px; float:left; } .itemPortfolio { width: 230px; border:1px solid #7ec5ff; float:left; display:block; margin: 0 0 20px 0; background-color:#7ec5ff; } .itemPortfolio img { margin:0; padding:0; } .itemPortfolio h3 { font-size:16px; line-height:22px; font-weight:bold; text-align:center;
104
margin: 5px 0 0 0; color:white; } .itemPortfolio h3 a { color:white; text-decoration:none; } .portfolioDetalle { width: 650px; padding:10px; margin: 0 0 20px 0; background-color: #f4f4f4; -webkit-border-radius: 5px; border-radius: 5px; display:block; float:left; } .portfolioDetalle img { float:left; margin: 0 10px 0 0; } .detalleTitulo { width: 85px; color: #7ec5ff; font-weight:bold; float:left; text-align:right; margin: 0 5px 0 0; } En “Layout 2″ vamos a disponer de los elementos de un modo ligeramente diferente, construyendo en nuestra barra lateral el área en donde mostraremos los datos del metabox y debajo nuestra imagen destacada. Añadimos al functions.php el nuevo tamaño que usaremos para the_post_ thumbnail();. Insertamos el siguiente valor debajo del último add_image_size(); add_image_size( 'layout2', 340, 300, true); Así quedará nuestro “Layout 2″:
105
Ahora procedemos a completar el single-php.php reemplazando ese texto que colocamos previamente “Otro Layout”. if ( have_posts() ) : while ( have_posts() ) : the_post(); $cliente = get_post_meta(get_the_id(), 'cliente', TRUE); $socios = get_post_meta(get_the_id(), 'socios', TRUE); $descripcion = get_post_meta(get_the_id(), 'descripcion', TRUE); ?>
Este segundo layout es mas sencillo pues tiene un solo bucle. Veamos el CSS: .portfolioDos { width: 560px; float:left; } .portfolioDosDetalle { width:320px; padding:10px; margin: 0 0 20px 0px; background-color: #f4f4f4; -webkit-border-radius: 5px; border-radius: 5px; display:block; float:right; } .sidebarPortfolioDos { width: 340px; margin: 20px 0 0 10px; padding: 0 0 0 10px; border-left: 1px solid #f4f4f4; float:left; } Para el tercer Layout, puesto que ya comprendimos la idea, vamos a insertar parte de la plantilla single.php con la salvedad de que tenemos que eliminar un contenedor y vamos a eliminar el area de información de la entrada.
106
if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>
Clase 17: Custom Post Types: Portfolio y plantilla de taxonomías. En esta clase vamos a encarar la plantilla de taxonomías y, de yapa, vamos a construir una página para ver todo el portfolio de un modo un poco mas interesante. Volviendo, como siempre, a la jerarquía de plantillas, vemos que el formato de archivo que tenemos que usar para poder visualizar nuestros elementos por “tipo” es taxonomy-$taxonomy.php. Entonces daremos a nuestro archivo el nombre de taxonomy-portfoliotaxonomies.php, ya que así lo llamamos en el archivo functions.php.
Lo que hicimos en nuestro template es buscar el contenido de los custom fields “cliente” y “descripcion” y guardarlo en variables. Luego, dentro del bucle, nos fijamos si $cliente tiene algún contenido, de tenerlo entonces imprime lo que está luego del echo. Mismo caso para $descripcion. Como verán añadimos un tamaño de thumbnail mas, así que lo tenemos que añadir a nuestro functions.php, en la sección en donde están los demás tamaños. add_image_size( 'portfolioitem', 230,230, true ); Y ya que estamos podemos añadir un snippet a nuestro functions.php que nos va a facilitar la carga de productos también. Este trozo de código ya lo hemos visto en otras oportunidades en Summarg y resulta muy práctico. Básicamente lo que hace es tomar la primer imagen que encuentre en la entrada y la convierte en destacada, salvo que el usuario haya elegido específicamente una. function autoset_featured() { global $post; $already_has_thumb = has_post_thumbnail($post->ID); if (!$already_has_thumb) { $attached_image = get_children( "post_parent=$post->ID&post_
108
type=attachment&post_mime_type=image&numberposts=1" ); if ($attached_image) { foreach ($attached_image as $attachment_id => $attachment) { set_post_thumbnail($post->ID, $attachment_id); } } } } //end function add_action('the_post', 'autoset_featured'); add_action('save_post', 'autoset_featured'); add_action('draft_to_publish', 'autoset_featured'); add_action('new_to_publish', 'autoset_featured'); add_action('pending_to_publish', 'autoset_featured'); add_action('future_to_publish', 'autoset_featured'); Buscaremos que nuestra plantilla tenga el siguiente formato: 109
Llegado este punto, y si ya tienen varios elementos cargados, necesitan regenerar las miniaturas para que muestre el nuevo formato. Pueden usar el plugin Regenerate Thumbnails que les va a ahorrar mucho tiempo y esfuerzo. Vamos con el CSS. /* plantilla taxonomia */ .portfolioItem { width: 230px; height:230px; float:left; position:relative; margin:0; padding:0; } .portfolioItem a { color:white; text-decoration:none; } .portfolioItem a img { border:none;
margin:0; } Necesitamos que .portfolioItem tenga position:relative ya que el contenedor que le sigue tendrá que superponerse a nuestra imagen para lograr el efecto deseado, para lo cual usará position:absolute y le indicaremos que se posicione en top:0 y left:0. .portfolioItemDetalle { display:none; position:absolute; top:0; left:0; background-image:url(images/darky.png); background-repeat:repeat; padding: 10px; width: 210px; height:210px; color:white; margin:0; } .portfolioItemDetalle h2 { text-align:center; margin-top:20px; color:white; } Al contenedor con el título y los detalles del trabajo le damos un display:none para ocultarlo, ya que queremos que se muestre únicamente cuando el usuario pase el mouse por arriba del elemento y luego se oculte. Con la siguiente línea completamos el truco: .portfolioItem:hover .portfolioItemDetalle { display:block; } ¡Listo! El truco funciona. Aunque… ¿Qué tal si ponemos un poquito de jQuery para animar esas ventanitas un poco? De ese modo podemos suavizar el efecto al pasar el mouse por arriba. Comentemos o eliminemos el último trozo de CSS y coloquemos el siguiente código en la plantilla de taxonomía luego del endif; <script type="text/javascript"> $(function() { $(".portfolioItem").hover(function() { $(this).children(".portfolioItemDetalle").show("fast"); },function(){ $(this).children(".portfolioItemDetalle").hide("fast"); }); }); Con esto ya tenemos un bonito modo de mostrar nuestros items y dejamos las bases bien plantadas para que los lectores puedan tomar su propio rumbo a la hora de usar Custom Post Types. Pueden ver el producto terminado en el demo online.
110
Página personalizada para el portfolio con jQuery Isotope
Todavía podemos hacer algo mas, un poco mas complicado y personalizado pero que va a quedar muy bien para lucir nuestro porfolio. Fuera de programa les vamos a regalar una integración entre el plugin jQuery Isotope y nuestro portfolio. Creamos una página personalizada de nombre page-portfolio.php y colocamos en su interior exactamente lo que ya tenemos para taxonomía con pequeñas diferencias: • Agregamos el encabezado con el template name. • Modificamos los argumentos de la query para que muestre cantidad ilimitada de elementos dentro del post_type que nos interesa. • Eliminamos la línea de paginación ya que no vamos a usar ninguna.
Creamos una página y le asignamos la plantilla que estamos construyendo. Descargamos desde
111
Isotope el plugin y lo anexamos a nuestro header. <script type="text/javascript" language="javascript" src="/scripts/jquery.isotope.min.js"> script> Ahora bien, el plugin nos pide que respetemos una estructura de marcado determinada el menú y para los elementos. Pueden ver aquí la documentación (específicamente en lo que respecta a sorting) y les transcribimos el código del demo de Isotope para que se den una buena idea.
Entonces nosotros intentaremos adaptar esa estructura a nuestro trabajo para que funcione el plugin. Debajo de la llamada de get_header() insertamos el menú desde el que llamaremos a cada una de las taxonomías para que se muestren.
Inmediatamente después de que se inicia el bucle necesitamos obtener el nombre de la taxonomía para colocarla en la clase de cada elemento, de ese modo el plugin puede traer a cada elemento cuando el usuario clickee en el menú. $terms = get_the_terms( $post->ID , 'portfoliotaxonomies' ); foreach ( $terms as $term ) { $isotopeClass = $term->name; }
112
El nombre de la taxonomía se almacena en $isotopeClass, y ahora debemos imprimirla en nuestros elementos.
Con esto ya tenemos el marcado necesario y podemos proceder a añadir el código javascript para que se ejecute el plugin. El siguiente código debe anexarse al que ya habíamos colocado para animar la aparición de los detalles del item. <script type="text/javascript"> $(function(){ var $container = $('#isotopeArea'); $container.isotope({ itemSelector : '.isotopeElement', animationEngine : 'best-available' }); var $optionSets = $('#options .option-set'), $optionLinks = $optionSets.find('a'); $optionLinks.click(function(){ var $this = $(this); // don't proceed if already selected if ( $this.hasClass('selected') ) { return false; } var $optionSet = $this.parents('.option-set'); $optionSet.find('.selected').removeClass('selected'); $this.addClass('selected'); // make option object dynamically, i.e. { filter: '.my-filter-class' } var options = {}, key = $optionSet.attr('data-option-key'), value = $this.attr('data-option-value'); // parse 'false' as false boolean value = value === 'false' ? false : value; options[ key ] = value; if ( key === 'layoutMode' && typeof changeLayoutMode === 'function' ) { // changes in layout modes need extra logic changeLayoutMode( $this, options ) } else { // otherwise, apply new options $container.isotope( options );
113
} return false; }); }); Con el parámetro animationEngine : ‘best-available’ estamos indicando al plugin que utilice animaciones CSS3 cuando el navegador lo permita, y animaciones javascript en caso contrario. Así que en nuestro CSS lo que tenemos que incluir son dichas transiciones. /** Isotope **/ .isotope, .isotope .isotope-item { /* change duration value to whatever you like */ -webkit-transition-duration: 0.8s; -moz-transition-duration: 0.8s; -ms-transition-duration: 0.8s; -o-transition-duration: 0.8s; transition-duration: 0.8s; } .isotope { -webkit-transition-property: height, width; -moz-transition-property: height, width; -ms-transition-property: height, width; -o-transition-property: height, width; transition-property: height, width; } .isotope .isotope-item { -webkit-transition-property: -webkit-transform, opacity; -moz-transition-property: -moz-transform, opacity; -ms-transition-property: -ms-transform, opacity; -o-transition-property: -o-transform, opacity; transition-property: transform, opacity; } /**** disabling Isotope CSS3 transitions ****/ .isotope.no-transition, .isotope.no-transition .isotope-item, .isotope .isotope-item.no-transition { -webkit-transition-duration: 0s; -moz-transition-duration: 0s; -ms-transition-duration: 0s; -o-transition-duration: 0s; transition-duration: 0s; } Y para concluir damos estilo al menú que acabamos de agregar, que dicho sea de paso será igual al #menu-top que construimos al principio del taller. /** Menu isotope **/ ul#filters { margin:20px 20px 0 0; float:right; list-style-type:none;
114
height:30px; width: 920px; } ul#filters li a{ list-style-type:none; text-decoration:none; float:right; color: #7ec5ff; font-weight:bold; padding: 7px 10px; font-size:12px; } ul#filters li a:hover { text-decoration:none; background-color: #7ec5ff; color:#fff; font-weight:bold; padding: 7px 10px; } Nota: para que este código les funcione tal cual está aquí, deben crear exactamente las mismas taxonomías en Portfolio que nosotros publicamos. Sino simplemente efectúen las modificaciones en donde corresponda en el menú. Demo online Descargar clase themeTaller 17
115
Clase 18: Custom Post Types: Formulario de búsqueda. El último detalle que nos falta definir para los custom post types está relacionado con la creación de un formulario de búsqueda en donde podamos listar elementos en base a diferentes parámetros. En nuestro Portfolio hicimos uso de dos custom fields y de taxonomías para clasificar nuestras entradas, y podría interesarnos listar entradas en base a dichos valores.
116
Vamos a crear una página personalizada para esta búsqueda y llamaremos al archivo pagesearch.php.
Ya colocamos las etiquetas de formulario y elegimos usar el layout que contiene dos barras laterales que construimos clases atrás. Lo primero que necesitamos hacer es establecer una diferencia entre este tipo de búsqueda y otros. Podríamos tener varios CPT o mezclar este formulario con la búsqueda general del sitio, así que sería bueno definir que la búsqueda la realizaremos en el Portfolio, así que le vamos a pasar el parámetro con un input hidden (oculto). El primer custom field que utilizamos fue el que definía el layout así que generamos los radio buttons para que el usuario pueda elegir.
Layout1
Layout2
div>
Ahora sería bueno colocar un select que permita seleccionar fácilmente una taxonomía, para lo que generaremos la función colocando el siguiente código al final de nuestro functions.php function taxonomy_dropdown($taxonomy) { ?> '; ?> Dicha función recorre y lista los términos dentro de la taxonomía que le indiquemos. En nuestra page-search.php colocamos la llamada a la función de la siguiente manera:
Finalmente nos sería de utilidad listar los socios de cada proyecto, pues cabe esperar que sea un dato que en mas de una oportunidad se repita. Para ello debemos realizar una consulta a la DB mediante $wpdb
El CSS para esta sección es el siguiente: .radiobuscar { width: 100px; float:left; margin: 0 0 5px 0; }
117
.radiobuscar div{ float:left; } .seccionForm { width: 380px; margin: 0 0 5px 0; float:left; } .selectArea { float:left; margin: 0 0 10px 0; } .searchcpt input[type=button] { float:left; border: 1px solid #7ec5ff; background-color: #7ec5ff; color: white; height:22px; font-weight:bold; font-size:11px; margin: 0 0 0 5px; padding: 5px 10px; overflow:hidden; } Hasta aquí pudimos construir el formulario, pero ahora debemos resolver la búsqueda. De paso podemos aprovechar a partir el formulario de búsquedas en dos archivos. Vamos a nuestro search.php y colocamos las siguientes líneas en la parte superior. Recuerden que deben cerrar la llave que se abre luego del else. $search_refer = $_GET["s"]; if ($search_refer == 'portfolio') { load_template(TEMPLATEPATH . '/ search-custom.php'); } else { En esta sección utilizamos el primer input que colocamos en el formulario, que utilizamos únicamente para indicar que la variable “s” tiene por valor “portfolio”, y para tal caso escapa del template search.php y carga el template search-custom.php. Generamos el archivo search-custom.php y comenzamos a procesar los datos. Como primera medida usamos get_header() para cargar el encabezado y usamos GET para obtener las variables que pasamos por URL desde el formulario.
118
entonces la relación que establecemos es AND y significa que se listarán las entradas que contengan los dos valores que pasamos (ej. que pertenezca a “Socio X” y que su Layout sea Layout1). Si $socio no contiene nada dentro y $layout si, entonces la relación será OR, lo que permite listar las entradas que cumplan una u otra condición. if ($socio && $layout) { $relation = 'AND';} if (!$socio && $layout) { $relation = 'OR';} $args = array( 'post_type' => 'portfolio', 'portfoliotaxonomies' => $cat, 'meta_query' => array( 'relation' => $relation, array( 'key' => 'layout', 'value' => $layout, 'compare' => '=' ), array( 'key' => 'socios', 'value' => $socio, 'compare' => '=' ) ) ); query_posts( $args ); Llegado este punto ya podemos listar el resto de la plantilla con el bucle y los resultados. Para poder comprobar mejor el funcionamiento del formulario vamos a imprimir al pié de cada elemento el valor “socio”, “layout” y la taxonomía.
Lo sentimos, intente utilizar nuestro formulario de búsquedas.
Siguientes','
Anteriores
'); ?> div>
La intención de este trabajo es darles una idea de cómo se pueden explotar los Custom Post Types. Este formulario puede ampliarse introduciendo la posibilidad de ingresar términos o más custom fields. También llegado este punto podríamos elegir cargar los socios como etiquetas y no como custom fields, ya que también pueden introducirse en la query y son mas fáciles de gestionar. Ver el formulario online Descargar clase: themeTaller 18
120
Clase 19: Plugins y snippets recomendados Compartimos con ustedes todos los plugins y snippets que consideramos que todo desarrollador debe tener para sacar el máximo provecho de la plataforma. Estos son los básicos para la construcción de cualquier sitio WordPress aunque obviamente no son todos indispensables, sino que ayudan con diversas tareas.
Plugins •
Askimet: Incluido en WordPress, su misión es combatir el spam en todo el mundo, totalmente gratuito.
•
Google XML Sitemap: Generador automático de sitemaps.
•
All in One WP Security: Medidas básicas de seguridad para tu WP.
•
Contact Form 7: El mejor plugin para formularios, permite el envío de archivos y mucho mas.
•
Efficient Related Posts: Entradas relacionadas, optimizado en vistas de cuidar el consumo de recursos.
•
Regenerate Thumbnails: Plugin obligatorio para los desarrolladores de themes, regenera las miniaturas en base a los tamaños que encuentra en el functions.php.
•
Resize at upload plus: Permite establecer el tamaño máximo de las imágenes (en ancho y alto), y cuando el mismo es superior redimensiona la imagen.
•
WP-Pagenavi: Inserta paginación con números.
•
WP SyntaxHighlighter: Permite insertar código en las entradas y mostrarlo con colores según el lenguaje.
•
WP to Twitter: Envía a Twitter cada artículo al ser publicado.
•
Lightbox Gallery: Añade el efecto lightbox a tus galerías nativas de WordPress.
•
Simple Lightbox: Efecto lightbox a tus imágenes, permite configurar animaciones e incluso un modoslideshow.
•
WP Lightbox 2: Inserta el efecto lightbox a imágenes individuales o a galerías.
•
AWPCP: Another WordPress Classifieds Plugin, completísimo plugin para insertar clasificados en nuestro sitio. Dispone de varios addons premium.
•
Cart66 Lite: Plugin de e-commerce, permite vender productos digitales, genera programas de afiliado, ultra liviano.
•
E-Shop: Potente plugin de e-commerce con varias opciones de listado de producto, cargos por flete, varias pasarelas de pago.
•
Jigoshop: Este es un plugin muy extendido, que cuenta con varios addons premium (ver categoría Jigoshop en Codecanyon), cuenta con la posibilidad de setear diferentes parámetros por producto (ej. talles de ropa, colores, etc). Muy completo.
•
Woocommerce: Uno de los plugins mas poderosos, ya que cuenta con una amplia variedad de addons tanto en el sitio de sus desarrolladores como en Codecanyon.
•
WP-e-commerce: Este es uno de los plugins mas antiguos que todavía sobrevive y se adapta muy bien. Tiene una alta compatibilidad con casi cualquier theme ���������������������������� y además cuenta con sus pro-
121
pios addons premium. •
Simple Advert: Completo gestor de banners que se integra con WordPress ����������������� pero también funciona en cualquier plataforma. Funciones de publicación por tiempo, clicks ������������������� o impresiones. Sistema de estadísticas. Soporta enlaces, imágenes o flash.
•
W3 Total Cache: Uno de los plugins de cache mas completos, acelera la carga de página y economiza recursos del servidor.
•
WP Mobile Edition: Detecta automáticamente a los usuarios que ingresan desde un dispositivo móvil y carga un theme optimizado para dicha resolución.
•
Any Mobile Theme Switcher: Igual al anterior pero dispone de mayor control permitiendo cargar un themepor cada tipo de dispositivo móvil encontrado.
•
WPTouch Mobile Plugin: El plugin para visualizar desde dispositivos móviles mas popular del mercado.
•
WordPress Mobile Pack: El mas completo plugin �������������������������������������������� para desarrolladores, incluye varias adaptaciones para determinados dispositivos, un theme default, un theme para el escritorio de WordPress y mas.
Snippets Añadir custom post types a los feeds. function myfeed_request($qv) { if (isset($qv[‘feed’])) $qv[‘post_type’] = get_post_types(); return $qv; } Cambiar la longitud de the_excerpt function my_excerpt($length) { return 150; } add_filter(‘excerpt_length’, ‘my_excerpt’); Cambiar el texto de “leer mas” del excerpt Colocar imagen destacada automáticamente function autoset_featured() { global $post; $already_has_thumb = has_post_thumbnail($post->ID); if (!$already_has_thumb) { $attached_image = get_children( “post_parent=$post-
122
>ID&post_type=attachment&post_mime_type=image&numberposts=1” ); if ($attached_image) { foreach ($attached_image as $attachment_ id => $attachment) { set_post_thumbnail($post->ID, $attachment_id); } } } } //end function add_action(‘the_post’, ‘autoset_featured’); add_action(‘save_post’, ‘autoset_featured’); add_action(‘draft_to_publish’, ‘autoset_featured’); add_action(‘new_to_publish’, ‘autoset_featured’); add_action(‘pending_to_publish’, ‘autoset_featured’); add_action(‘future_to_publish’, ‘autoset_featured’); Función para colocar una cantidad personalizada de texto /* Original Plugin URI: http://labitacora.net/comunBlog/limit-post.phps Usage: the_content_limit($max_charaters, $more_link) */ function the_content_limit($max_char, $more_link_text = ‘(more...)’, $stripteaser = 0, $more_file = ‘’) { $content = get_the_content($more_link_text, $stripteaser, $more_ file); $content = apply_filters(‘the_content’, $content); $content = str_replace(‘]]>’, ‘]]>’, $content); $content = strip_tags($content); if (strlen($_GET[‘p’]) > 0) { echo “
Añadir texto al final de nuestras entradas en los feeds function feedFilter($query) { if ($query->is_feed) { add_filter(‘the_content’,’feedContentFilter’); } return $query; } add_filter(‘pre_get_posts’,’feedFilter’); function feedContentFilter($content) { $content .= ‘
Texto extra para los feeds...
’; }
return $content;
Añadir iconos según el myme type del adjunto function get_attachment_icons($echo = false){ $sAttachmentString = “
\n”; if ( $files = get_children(array( //do only if there are attachments of these qualifications ‘post_parent’ => get_the_ID(), ‘post_type’ => ‘attachment’, ‘numberposts’ => -1, ‘post_mime_type’ => ‘application/pdf’, //MIME Type condition ))){ foreach( $files as $file ){ //setup array for more than one file attachment $file_link = wp_get_attachment_url($file->ID); //get the url for linkage $file_name_array=explode(“/”,$file_link); $file_name=array_reverse($file_name_array); //creates an array out of the url and grabs the filename $sAttachmentString .= “
”; } } //Word Documents if ( $files = get_children(array( //do only if there are attachments of these qualifications ‘post_parent’ => get_the_ID(), ‘post_type’ => ‘attachment’, ‘numberposts’ => -1, ‘post_mime_type’ => ‘application/msword’, //MIME Type condition
124
))){ foreach( $files as $file ){ //setup array for more than one file attachment $file_link = wp_get_attachment_url($file->ID); //get the url for linkage $file_name_array=explode(“/”,$file_link); $file_name=array_reverse($file_name_array); //creates an array out of the url and grabs the filename $sAttachmentString .= “
”; } } //Powerpoint Documents if ( $files = get_children(array( //do only if there are attachments of these qualifications ‘post_parent’ => get_the_ID(), ‘post_type’ => ‘attachment’, ‘numberposts’ => -1, ‘post_mime_type’ => ‘application/vnd.ms-powerpoint’, //MIME Type condition ))){ foreach( $files as $file ){ //setup array for more than one file attachment $file_link = wp_get_attachment_url($file->ID); //get the url for linkage $file_name_array=explode(“/”,$file_link); $file_name=array_reverse($file_name_array); //creates an array out of the url and grabs the filename $sAttachmentString .= “
”; } } //Excel Documents if ( $files = get_children(array( //do only if there are attachments of these qualifications ‘post_parent’ => get_the_ID(), ‘post_type’ => ‘attachment’, ‘numberposts’ => -1, ‘post_mime_type’ => ‘application/vnd.ms-excel’, //MIME Type condition ))){
125
foreach( $files as $file ){ //setup array for more than one file attachment $file_link = wp_get_attachment_url($file->ID); //get the url for linkage $file_name_array=explode(“/”,$file_link); $file_name=array_reverse($file_name_array); //creates an array out of the url and grabs the filename $sAttachmentString .= “
”; } } //Zipped Files if ( $files = get_children(array( //do only if there are attachments of these qualifications ‘post_parent’ => get_the_ID(), ‘post_type’ => ‘attachment’, ‘numberposts’ => -1, ‘post_mime_type’ => ‘application/zip’, //MIME Type condition ))){ foreach( $files as $file ){ //setup array for more than one file attachment $file_link = wp_get_attachment_url($file->ID); //get the url for linkage $file_name_array=explode(“/”,$file_link); $file_name=array_reverse($file_name_array); //creates an array out of the url and grabs the filename $sAttachmentString .= “
”; } } //Audio Files $mp3s = get_children(array( //do only if there are attachments of these qualifications ‘post_parent’ => get_the_ID(), ‘post_type’ => ‘attachment’, ‘numberposts’ => -1, ‘post_mime_type’ => ‘audio’, //MIME Type condition ) ); if (!empty($mp3s)) :
126
$sAttachmentString .= “
”; foreach($mp3s as $mp3) : $sAttachmentString .= “
”; if(!empty($mp3->post_title)) : //checking to make sure the post title isn’t empty $sAttachmentString .= “
”.$mp3->post_ title.”
”; endif; if(!empty($mp3->post_content)) : //checking to make sure something exists in post_content (description) $sAttachmentString .= “
} add_shortcode(‘attachment icons’, ‘get_attachment_icons’); Acortar el título a determinada cantidad de caracteres: function the_title2($before = ‘’, $after = ‘’, $echo = true, $length = false) { $title = get_the_title(); if ( $length && is_numeric($length) ) { $title = mb_substr( $title, 0, $length, ‘UTF-8’ ); } if ( strlen($title)> 0 ) { if ( strlen($title) == $length ) $title = apply_filters(‘the_title2’, $before . $title . $after, $before, $after); if ( $echo ) echo $title; else return $title; } } Luego en el theme colocar la función con la cantidad de caracteres a imprimir:
128
Conclusión WordPress se popularizó como plataforma para blogs, pero fue convirtiéndose en un potente CMS a la altura de Joomla o Drupal. El diseño de plantillas para WordPress es realmente simple, como pudimos ver, y con los conocimientos previos necesarios nos permite en poco tiempo conquistar la construcción de themes y explotar al máximo las capacidades de la plataforma. No se necesitan grandes conocimientos de php, solo una base sobre la lógica de programación y algunas funciones sueltas aquí y allá. Lo que si resulta importante es tener una buena base de HTML y CSS, y añade un plus especialmente interesante el tener buenos conocimientos de jQuery. La inclusión de los Custom Post Types, además de los menús, las miniaturas personalizables y otros detalles, marcaron en WordPress un antes y un después en lo que respecta a diseñar sitios con organizaciones complejas de contenidos pero manteniendo la simplicidad de uso para el editor y usuario comunes. 129 Una de las cosas que mas nos atrapó de WordPress es que al lado de sus competidores resulta muy liviano para el servidor y dispone de actualizaciones constantes parcheando las vulnerabilidades y bugs que surgen. Cada día emergen mas herramientas para administrar múltiples instalaciones de WordPress, backupeos automáticos, plugins con medidas de seguridad extra y antivirus que detectan e informan de cualquier código extraño que logre filtrarse. Si bien no es imposible de vulnerar un sitio hecho con WordPress, sigue siendo bastante confiable tomando las medidas del caso. La comunidad desarrolladora es cada día mas grande, y esto impacta directamente en el número de plugins y themes disponibles. En resumen, no por nada hoy es la plataforma mas popular del mercado y miles de miles de personas basan su trabajo en WordPress. Esperamos que ustedes disfruten de este taller tanto como nosotros y que puedan sacarle provecho en sus trabajos o como hobbie.
Hola! Este es un comentario