El siguiente objetivo que tenía marcado era crear un panel de administración en WordPress para el theme que estoy desarrollando. Os recomiendo que antes de seguir leyendo os paséis por el primer post de esta serie.
Decir que esto es como un bebé que está naciendo, y como todos los bebés cuando nacen está arrugadillo y hasta un poco feo. El código que voy a compartir y las explicaciones que voy a dar son sobre un trabajo que está pendiente de refactorizar, reordenar, limpiar, mejorar, etc.
Empecemos por mostrar cual era el objetivo.
En la imagen de abajo podéis ver los archivos que he creado en la carpeta admin de la estructura del framework.
- fieldset.php: He creado las funciones que contienen los campos a mostrar.
- main.php: Es el fichero principal que configura el menú de administración.
- settings.php: En este fichero se hace todo el proceso de muestra del formulario y guardado del mismo.
Empecemos por el fichero main.php.
[php]
require_once( get_template_directory().’/kernel/admin/settings.php’ );
/*
* Creating the configuration admin menu
*/
add_action( ‘admin_menu’, ‘jiac_setup_admin_menu’);
function jiac_setup_admin_menu( ) {
// Main menu title
$page_title = __( ‘General Configuration’, ‘jiac’ );
$menu_title = __( ‘Configuration’, ‘jiac’ );
$capability = ‘edit_theme_options’;
$menu_slug = ‘general-configuration’;
add_menu_page( $page_title, $menu_title, $capability, $menu_slug, », », 81 );
// Submenu. Framework settings
// All themes with this framework allows configure this
$sub_page_title = __( ‘Framework Settings’, ‘jiac’ );
$sub_menu_title = __( ‘General’, ‘jiac’ );
$sub_menu_slug = ‘framework-configuration’;
$sub_menu_function = ‘jiac_framework_configuration’;
add_submenu_page( $menu_slug, $sub_page_title, $sub_menu_title, $capability, $sub_menu_slug, $sub_menu_function );
remove_submenu_page( $menu_slug, $menu_slug );
}
[/php]
- Requerimos el fichero de settings del que hablaremos a continuación.
- Creamos un hook de acción asociado a admin_menu.
- Creamos la función que configurará el menú.
- Con add_menu_page añadimos el apartado Configuration.
- Con add_submenu_page añadimos el subapartado, importante la variable $sub_menu_function pues contiene la función de callback que muestra el contenido de la página de configuración. Fijaos que se llama jiac_framework_configuration.
- Con remove_submenu_page borramos el submenú la página principal, lo puse como prueba por ver como funcionaba la función, pero realmente no es necesaria, de hecho lo borraré y dejaré solamente una página de configuración sin necesidad de realizar el paso 5.
Veamos ahora el grueso de la cuestión, el fichero settings.php:
[php]
/*
* Requires the fieldset functions
*/
require_once( get_template_directory().’/kernel/admin/fieldset.php’ );
if ( !function_exists( ‘jiac_framework_configuration’ ) ) {
function jiac_framework_configuration( ) {
echo ‘<div class="wrap">’;
if ( isset($_GET[‘tab’]) ) jiac_tabbed_settings($_GET[‘tab’]);
else jiac_tabbed_settings();
echo ‘</div>’;
}
}
if ( !function_exists( ‘jiac_tabbed_settings’ ) ) {
function jiac_tabbed_settings( $current = ‘branding’ ) {
$prefix = ‘jiac_framework_’;
// Saving the form
if (isset($_POST[‘jiac_framework_configuration_submit’])) {
$fields = ($_POST[‘tab’] == ‘branding’)? jiac_framework_branding_fields(): jiac_framework_footer_fields();
foreach ($fields as $name => $attributes)
jiac_update_option($_POST[$name], $prefix.$name, ‘jiac_framework_options’);
}
// Saving end
echo ‘<div id="icon-themes" class="icon32"></div>’;
echo ‘<h2>’.__( ‘Framework Configuration’, ‘jiac’ ).'</h2>’;
echo ‘<h2 class="nav-tab-wrapper">’;
$framework_configuration_tabs = jiac_framework_configuration_tabs();
foreach ($framework_configuration_tabs as $tab => $title) {
$class = ( $tab == $current ) ? ‘nav-tab-active’ : »;
echo ‘<a href="?page=’.$_GET[‘page’].’&tab=’.$tab.’" class="nav-tab ‘.$class.’">’.$title.'</a>’;
}
echo ‘</h2>’;
?>
<form method="post" action="<?php echo admin_url(‘admin.php?page=’.$_GET[‘page’]).’&tab=’.$current; ?>">
<?php
switch ($current) {
case ‘branding’:
jiac_print_form_fields(jiac_framework_branding_fields(), $prefix);
break;
case ‘footer’:
jiac_print_form_fields(jiac_framework_footer_fields(), $prefix);
break;
}
?>
<input type="hidden" name="tab" value="<?php echo $current; ?>"/>
<input type="submit" name="jiac_framework_configuration_submit" value="<?php _e(‘Submit’, ‘jiac’); ?>"/>
</form>
<?php
}
}
if (!function_exists(‘jiac_print_form_fields’)) {
function jiac_print_form_fields($fieldset, $prefix = ‘jiac_framework_’) {
foreach ($fieldset as $name => $attributes) {
$value = (jiac_get_option($prefix.$name, ‘jiac_framework_options’) != FALSE)? jiac_get_option($prefix.$name, ‘jiac_framework_options’) : »;
switch ($attributes[‘type’]) {
case ‘text’:
?>
<div class="field-container">
<div class="field-label">
<?php echo ($attributes[‘label’]);?>
</div>
<div class="field-input">
<input type="<?php echo ($attributes[‘type’])?>" name="<?php echo $name?>" value="<?php echo $value?>"/>
</div>
</div>
<?php
break;
case ‘textarea’:
?>
<div class="field-container">
<div class="field-label">
<?php echo ($attributes[‘label’]);?>
</div>
<div class="field-input">
<textarea name="<?php echo $name?>"><?php echo trim($value);?></textarea>
</div>
</div>
<?php
break;
}
}
}
}
[/php]
Empecemos por el principio 🙂
Función jiac_framework_configuration:
- Sí, es la que hemos llamado desde add_submenu_page que hemos comentado antes.
- La función detecta si el parámetro tab está definido en la URL, si no lo está se llama a la función jiac_tabbed_settings sin parámetros (en su definición tiene el parámetro por defecto branding), en el caso que sí esté definido se llama a la función con la pestaña que debe mostrar.
Función jiac_tabbed_settings:
- Se declara la función para que si no pasamos parámetros la pestaña activa sea la de branding.
- Se declara el prefijo de las opciones que se guardarán en la base de datos.
- Se mira si se ha pulsado sobre el botón de guardar formulario y desde que pestaña se hizo para guardar unas opciones u otras en la base de datos con la función que declaramos en el post anterior.
- Se crea la estructura de las pestañas identificando cual está activa para aplicarle la clase correspondiente. Las pestañas vienen dadas por la función jiac_framework_configuration_tabs.
- Se crea el formulario cuya acción será la URL actual.
- Dependiendo si es una pestaña u otra la activa, mostramos unos campos u otros con la función con la función jiac_print_form_fields.
Personalmente no me gusta como queda estructurado a estas alturas, tengo que separar bien las funciones y organizarlas además de pensar una manera más genérica para tratar todos los formularios.
Función jiac_print_form_fields:
- En esta función pasamos como parámetros un array de campos que se explicará a continuación y el prefijo de las opciones guardas en la base de datos.
- La función se encarga de «escupir» el HTML de los campos basándose en sus parámetros, hasta el momento y como prueba soporta inputs de tipo text y textareas.
- Básicamente recorre el array de campos y dependiendo de sus parámetros y su tipo muestra el HTML.
- Al comienzo de la función en la variable value se guarda, si existe, el parámetro actual de ese campo obtenido de la base de datos.
Por último el fichero fieldset.php:
[php]
function jiac_framework_configuration_tabs( ) { return array(‘branding’ => __( ‘Branding’, ‘jiac’ ), ‘footer’ => __( ‘Footer’ , ‘jiac’));}
function jiac_framework_branding_fields( ) {
return array(‘name’ => array(‘label’ => __(‘Name’, ‘jiac’),’type’ => ‘text’),
‘contact_name’ => array(‘label’ => __(‘Contact Name’, ‘jiac’),’type’ => ‘text’),
‘phone’ => array(‘label’ => __(‘Phone’, ‘jiac’),’type’ => ‘text’),
‘email’ => array(‘label’ => __(‘Email’, ‘jiac’),’type’ => ‘text’),
‘address’ => array(‘label’ => __(‘Address’, ‘jiac’),’type’ => ‘text’),
‘city’ => array(‘label’ => __(‘City’, ‘jiac’),’type’ => ‘text’),
‘country’ => array(‘label’ => __(‘Country’, ‘jiac’),’type’ => ‘text’) );
}
function jiac_framework_footer_fields( ) {
return array(‘analytics’ => array(‘label’ => __(‘Tracking Code’, ‘jiac’),’type’ => ‘textarea’));
}
[/php]
Este fichero contiene tres funciones:
- jiac_framework_configuration_tabs: Contiene un array con los slugs de las pestañas y su título.
- jiac_framework_branding_fields: Devuelve un array de arrays con los campos de la pestaña Branding. Las claves principales son los name de los inputs, el array secundario contiene la etiqueta y el tipo.
- jiac_framework_footer_fields: Hace lo mismo que la función anterior pero para la pestaña Footer.
Hasta aquí esta versión inicial, con semejanzas a, como decía, un bebé feo recién nacido, ahora tiene que crecer cada vez se irá poniendo más guapetón. El objetivo de la semana que viene es reorganizar todo esto y plantear una serie de parámetros configurables finales, que serán los que soporte el tema de base.
Como digo, este es el primer código que escribo para realizar esto. Me he basado en código explicado por Smashing Magazine y soy consciente de que se puede mejorar. Pero chicos … HAZ Y MEJORA.
¿Comentarios? ¿Críticas? Seguro que alguna habrá 😉