Actualmente me encuentro inmerso en un proyecto en el trabajo que requiere una programación a medida en WordPress, en un principio me fijé en CPOThemes de forma que se me ocurrió programar un framework desde cero y usarlo para los proyectos que vayan surgiendo de ahora en adelante pero siempre hay un problema con este tipo de cosas: El tiempo.
Como me siento muy cómodo trabajando con Genesis Framework la opción B era la de crear mi propia plantilla, pero para este sistema, ya que se programa bastante más rápido y hay una buena comunidad detrás para consultar dudas y resolver problemas, además está tan bien estructurado que leyendo el código del propio framework puedes aprender bastantes cosas.
Estructura de Clases
El primer problema que se me planteó fue el de crear una página de configuración del tema, si bien la propia de Genesis es bastante completa yo quería algo más y crear una página para introducir los datos de la empresa, contacto, email, teléfono y más adelante aspectos sobre tipografía, licencia y algunas cosas más.
Fue cuando barajé varias opciones como una programación a medida desde cero o usar Frameworks de opciones como ReduX pero fijándome en el código de Genesis me percaté que existe una clase abstracta que se llama Genesis_Admin_Boxes y la podemos encontrar en el fichero admin.php dentro de lib/classes del framework.
NOTA: Una clase abstracta es una clase que contiene métodos abstractos que deben ser implementados en una clase que herede de la clase abstracta.
Esta clase contiene el siguiente método que debemos sobrescribir:
metaboxes(): Función que se encargará de crear los metaboxes con funciones add_meta_box().
La clase Genesis_Admin_Boxes es una clase hija de otra clase abstracta más general, la clase Genesis_Admin que también tiene otros métodos que deben ser declarados y sobrescritos en la clase heredera de Genesis_Admin_Boxes.
He creado un pequeño diagrama para que se entienda:
Simplemente tenemos que crear una clase que herede de Genesis_Admin_Boxes y en su constructor configurar los atributos para hacer una llamada al método create y por último en el hook de la acción genesis_admin_menu llamar a una función que instancie la nueva clase.
El proceso paso a paso
Creamos un fichero en una carpeta de nuestro child theme, aconsejo una buena estructura de carpetas, por lo que todos estos elementos los podemos tener, como en mi caso bajo el directorio includes/admin. En mi caso a esta clase la he llamado Jiac_Child_Settings por lo que al fichero php lo he llamado jiac-child-settings.php.
Constructor de la clase Jiac_Child_Settings
function __construct() { // Unique page id, used for identifing the page $page_id = 'jiac_child_settings'; // Page options. All the options for configure the theme $menu_ops = array( 'submenu' => array( 'parent_slug' => 'genesis', 'page_title' => __( 'JiacThemes - Settings', 'jiac' ), 'menu_title' => __( 'JiacTheme Settings', 'jiac' ) ) ); // Options identifier, must be unique $settings_field = 'jiac_child_settings'; $page_ops = array(); // Options by default $default_settings = array( 'company' => 'My Company', 'phone' => '', 'email' => '', 'address' => '', 'city' => '', 'name' => '', 'latitude' => '', 'longitude' => '', 'hours' => '' ); // Creates the page under genesis menu $this->create($page_id, $menu_ops, $page_ops, $settings_field, $default_settings); // Initialize the Sanitization Filter add_action( 'genesis_settings_sanitizer_init', array( $this, 'sanitization_filters' ) ); }
Bien, vamos a ir función a función explicando qué es cada cosa.
- $page_id: Es el identificador único de la página de opciones.
- $menu_ops: Es un array que contiene los elementos del menu. En el primer nivel del array puede contener los elementos ‘main_menu’, ‘submenu’ o ‘first_submenu’. Dependiendo de estos valores nos podemos encontrar con que si es main_menu podemos pasar los elementos ‘page_title’, ‘menu_title’, ‘capability’, ‘icon_url’, ‘position’. Si estamos con un firs_submenu podemos pasar los elementos ‘page_title’, ‘menu_title’ y ‘capability’. Por último si es submenu podemos pasar los mismos elementos que en el caso anterior pero sumándole el ‘parent_slug’ para indicar de que menú debe colgar.
- $settings_fileld: De este campo recuperaremos las opciones cuando las queramos mostrar.
- $page_ops: Nos sirve para configurar los textos de los botones del panel de administración.
- $default_settings: Los campos de configuración.
NOTA: Os recomiendo seguir el rastro de la función create de la clase Genesis_Admin para indentificar todos los parámetros que se aceptan.
Función de filtros para los campos:
// Function for sanitize settings fields function sanitization_filters() { genesis_add_option_filter('no_html', $this->settings_field, array( 'company', 'phone', 'email', 'address', 'city', 'name', 'latitude', 'longitude', 'hours' )); genesis_add_option_filter('email_address', $this->settings_field, array( 'email' )); }
Genesis incluye unos filtros para que los campos de configuración no cuelen elementos no deseados, estos filtros los podéis encontrar en el fichero lib/classes/sanitization.php.
- one_zero
- no_html
- absint
- safe_html
- requires_unfiltered_html
- url
- email_address
Crear los metaboxes y sus formularios
// Functin for creating the boxes with the fields function metaboxes() { add_meta_box('contact-information', 'Información de la empresa', array( $this, 'contact_information' ), $this->pagehook, 'main', 'high'); } function contact_information() { echo '<p>'.__('Company name','jiac').':<br />'; echo '<input type="text" name="' . $this->get_field_name( 'company' ) . '" id="' . $this->get_field_id( 'company' ) . '" value="' . esc_attr( $this->get_field_value( 'company' ) ) . '" size="50" />'; echo '</p>'; echo '<p>'.__('Contact name','jiac').':<br />'; echo '<input type="text" name="' . $this->get_field_name( 'name' ) . '" id="' . $this->get_field_id( 'name' ) . '" value="' . esc_attr( $this->get_field_value( 'name' ) ) . '" size="50" />'; echo '</p>'; echo '<p>'.__('Phone','jiac').':<br />'; echo '<input type="text" name="' . $this->get_field_name( 'phone' ) . '" id="' . $this->get_field_id( 'phone' ) . '" value="' . esc_attr( $this->get_field_value( 'phone' ) ) . '" size="50" />'; echo '</p>'; echo '<p>'.__('Email','jiac').':<br />'; echo '<input type="text" name="' . $this->get_field_name( 'email' ) . '" id="' . $this->get_field_id( 'email' ) . '" value="' . esc_attr( $this->get_field_value( 'email' ) ) . '" size="50" />'; echo '</p>'; echo '<p>'.__('Addres','jiac').':<br />'; echo '<input type="text" name="' . $this->get_field_name( 'address' ) . '" id="' . $this->get_field_id( 'address' ) . '" value="' . esc_attr( $this->get_field_value( 'address' ) ) . '" size="50" />'; echo '</p>'; echo '<p>'.__('City','jiac').':<br />'; echo '<input type="text" name="' . $this->get_field_name( 'city' ) . '" id="' . $this->get_field_id( 'city' ) . '" value="' . esc_attr( $this->get_field_value( 'city' ) ) . '" size="50" />'; echo '</p>'; echo '<p>'.__('Opening Hours','jiac').':<br />'; echo '<input type="text" name="' . $this->get_field_name( 'hours' ) . '" id="' . $this->get_field_id( 'hours' ) . '" value="' . esc_attr( $this->get_field_value( 'hours' ) ) . '" size="50" />'; echo '</p>'; echo '<p>'.__('Latitude','jiac').':<br />'; echo '<input type="text" name="' . $this->get_field_name( 'latitude' ) . '" id="' . $this->get_field_id( 'latitude' ) . '" value="' . esc_attr( $this->get_field_value( 'latitude' ) ) . '" size="50" />'; echo '</p>'; echo '<p>'.__('Longitude','jiac').':<br />'; echo '<input type="text" name="' . $this->get_field_name( 'longitude' ) . '" id="' . $this->get_field_id( 'longitude' ) . '" value="' . esc_attr( $this->get_field_value( 'longitude' ) ) . '" size="50" />'; echo '</p>'; }
Haciendo uso de la función add_meta_box la creamos y le asociamos un contenido. En este caso he creado los inputs a pelo pero estaría mejor encapsularlos de alguna manera.
El último paso. En functions.php
Por último y fuera de la clase, en el functions.php y tras haber requerido el fichero de la clase debemos poner.
add_action( 'genesis_admin_menu', 'jiac_add_child_theme_settings' ); /** * Add the Theme Settings Page * * @since 1.0.0 */ function jiac_add_child_theme_settings() { global $jiac_child_settings; $jiac_child_settings = new Jiac_Child_Settings(); }
Mucho mejor que ponernos a programar un sistema de gestión de opciones.
Genesis nos ofrece todo lo necesario para hacer esto de forma rápida sin calentarnos demasiado la cabeza, simplemente tenemos que entender cómo funcionan las relaciones entre las clases.
¡Ah! Se me olvidaba enseñaros como quedaría toda esta implementación.
¡Quedo a vuestra disposición para lo que queráis y para resolver vuestras dudas!