Customizer está siendo fuertemente impulsado no sólo dentro de wordpress.org, sino que hay mucho trabajo independiente en torno. Compañías como Obox han creado un theme que extiende en gran manera sus capacidades, convirtiéndolo en un constructor de sitios muy flexible. Otras como Themify emplean Customizer únicamente con controles propios que tienen mayores capacidades que los estándares.
Para usuarios finales, esto significa una mayor facilidad al configurar el sitio en una interface que muestra directamente el tema aplicado, con la chance de cambiarlo y aplicarlo instantáneamente, y configurar apariencia y hasta opciones en tiempo real apreciando cada cambio.
2. ¿Para qué implementar el
Customizer?
Para previsualizar instantáneamente
cambios que afecten el front-end.
(predefinidos)
3. Inicializando el
Customizer
/**
* Registrar paneles, secciones y controles para el Customizer.
* @param object $wp_customize Instancia de WP_Customizer_Manager.
*/
function queryloop_customize_register( $wp_customize ) {
// Iniciar panels, sections, controls y sus settings.
}
add_action( 'customize_register', 'queryloop_customize_register' );
4. $wp_customize->add_panel( 'panel_id', array(
'title' => __( 'Un Panel', 'queryloop' ),
) );
$wp_customize->add_section( 'section_id', array(
'title' => __( 'Una Sección', 'queryloop' ),
'panel' => 'panel_id',
) );
$wp_customize->add_setting( 'setting_id', array(
'type' => 'theme_mod', // u 'option'
'default' => '', // Valor predeterminado
'transport' => 'refresh', // o postMessage para cambios instantáneos
'capability' => 'edit_theme_options', // capacidad necesaria
'sanitize_callback' => '', // sanear el valor a guardar en el setting
'sanitize_js_callback' => '', // sanear el valor a volcar a la página.
) );
$wp_customize->add_control( new WP_Customize_Control( $wp_customize,
'setting_id', array(
'label' => __( 'Un Control', 'queryloop' ),
'type' => 'text', // 'text' es el predeterminado así que no haría falta
'section' => 'section_id',
'settings' => 'setting_id',
) ) );
6. Customizer puede usar distintos
Settings
option
Options API
https://codex.wordpress.org/Options_API
theme_mod
Theme Modification API
https://codex.wordpress.org/Theme_Modification_API
¿Otros?
(un wrapper de Options API)
7. Para emplear el
Customizer
en
Opciones persistentes
e independientes del theme.
Plugins
$wp_customize->add_setting( 'settings[key]', array(
'type' => 'option',
'capability' => 'customize', // nueva capacidad en 4.0 - Trac #28605
) );
9. Agregamos un parámetro para
saber que es una vista del plugin
// http://ejemplo.com/wp-admin/customize.php?url=URL&return=RETURN&miplugin=true
$link = add_query_arg( 'miplugin', 'true', $link );
Visible en los controles
// http://ejemplo.com/documents/?document_id=true
'url' => urlencode(
add_query_arg( ‘document_id', 'true',
get_post_type_archive_link( 'document' )
)
),
Visible en la previsualización
¡Cuidado aquí que el nombre del parámetro no sea un post type!
10. Mostramos sólo las secciones
de nuestro plugin
/**
* Remueve todas las secciones salvo seccion_1 y seccion_2 de nuestro plugin.
* @param bool Estado de la sección
* @param object Sección a deshabilitar o no.
* @return bool
*/
function queryloop_quitar_secciones( $active, $section ) {
if ( isset( $_GET['document'] ) || ( is_singular( 'document' ) ) ) {
if ( in_array( $section->id, array( 'seccion_1', 'seccion_2' ) ) ) {
return true;
}
return false;
}
return true;
}
add_filter( ‘customize_section_active','queryloop_quitar_secciones', 10, 2 );
11. Cargamos
JavaScript
para los controles
/**
* Cargamos scripts, sus dependencias y pasamos variables.
*/
function queryloop_cargar_js_controles() {
wp_enqueue_script( 'queryloop-controles', UNA_URL . '/js/customizer-
controls.js', array( 'customize-views' ) );
wp_localize_script( 'queryloop-controles', 'queryloopCustomizerControls',
array(
'focus' => 'control_3', // id de un control
) );
}
add_action( 'customize_controls_enqueue_scripts', array( $this,
'queryloop_cargar_js_controles' ) );
12. Enfocamos un control específico
(function($){
$(window).load(function(){
if ( ! _.isUndefined( queryloopCustomizerControls ) ) {
wp.customize.control( queryloopCustomizerControls.focus ).focus();
}
});
})(jQuery);
13. JavaScript en la previsualización
/**
* Carga JavaScript y pasa variables en previsualización.
*
* @since 1.0.0
*/
function queryloop_cargar_js_previa() {
wp_enqueue_script( 'queryloop-customizer', UNA_URL . '/js/ql-customizer-
preview.js', array( 'customize-preview' ) );
$estilos = array();
foreach ( queryloop_obtener_estilos() as $key => $style ) {
$estilos['queryloop_settings[' . $key . ']'] = array(
'selector' => $style['css']['selector'],
'property' => $style['css']['property'],
);
}
wp_localize_script( 'queryloop-customizer', 'queryloopCustomizerPrevia',
$estilos );
}
add_action( 'customize_preview_init', 'queryloop_cargar_js_previa' );
14. Cambios de CSS instantáneos
if ( ! _.isUndefined( queryloopCustomizerPrevia ) ) {
_.each( queryloopCustomizerPrevia, function(rule, key) {
wp.customize( key, function( value ) {
value.bind( function( valor ) {
$( rule.selector ).css( rule.property, '' );
if ( valor ) {
$( rule.selector ).css( rule.property, valor );
}
});
});
});
}
$wp_customize->add_setting( 'setting', array(
‘transport' => 'postMessage',
) );
15. Usamos la personalización en el
Front End
$settings = get_option( 'queryloop_settings' );
if ( isset( $settings['mostrar_titulo_pagina'] ) ) {
// mostrar el título de esta página
} else {
// no mostrar título
}
$mostrar_titulo = get_option( 'queryloop_setting_unico' );
if ( $mostrar_titulo ) {
// mostrar el título de esta página
} else {
// no mostrar título
}
16. Añadimos CSS al front-end con
wp_add_inline_style
/**
* Genera CSS y carga luego del estilo principal.
*/
function queryloop_agregar_estilo() {
$css = '';
foreach ( queryloop_obtener_estilos() as $key => $style ) {
$css .= queryloop_generar_css( $style['selector'], $style['property'],
$key );
}
if ( ! empty( $css ) ) {
wp_add_inline_style( 'estilo-principal', $css );
}
}
add_action( 'wp_enqueue_scripts', 'queryloop_agregar_estilo' );
17. Usar el Customizer para guardar
Post Meta
con un setting distinto de
option y theme_mod
$wp_customize->add_setting( 'un_meta_key', array(
'type' => 'ql_meta',
'capability' => 'customize',
) );
19. Pasamos a JavaScript el ID de la
entrada a personalizar
/**
* Cargamos scripts con dependencias y pasamos variables.
*/
function queryloop_cargar_js_controles() {
wp_enqueue_script( 'queryloop-controles', UNA_URL . '/js/customizer-
controls.js', array( 'customize-views' ) );
wp_localize_script( 'queryloop-controles', 'queryloopCustomizerControls',
array(
'focus' => 'control_3',
'customize' => isset( $_GET['document'] ) ? $_GET['document'] :
‘general', // id de la entrada a personalizar
) );
}
add_action( 'customize_controls_enqueue_scripts', array( $this,
20. Si estamos personalizando el
post, alteramos la URL de AJAX
$(window).load(function(){
if ( ! _.isUndefined( queryloopCustomizerControls ) ) {
if ( 'general' !== queryloopCustomizerControls.customize ) {
wp.customize.control( queryloopCustomizerControls.focus ).focus();
// agregamos ?document=1234 a la URL
wp.ajax.settings.url += '?document=' +
queryloopCustomizerControls.customize;
}
}
});
21. Intervenimos el guardado de
settings para guardar el nuestro
/**
* Si se provee el id del post, guardar post meta.
* @param mixed $valor Valor a guardar en el setting.
* @param WP_Customize_Setting $setting Instancia de WP_Customize_Setting.
*/
function queryloop_guardar_meta( $valor, $setting ) {
if ( isset( $_GET['document'] ) && ctype_digit( $_GET['document'] ) ) {
update_post_meta( $_GET['document'], $setting->id, $valor );
}
}
// wp-includes/class-wp-customize-setting.php
add_action( 'customize_update_ql_meta', 'queryloop_guardar_meta', 10, 2 );
22. Mostramos el meta guardado
$wp_customize->add_setting( 'un_meta_key', array(
'type' => 'ql_meta',
'default' => isset( $_GET['document'] ) ?
get_post_meta( $_GET['document'], 'un_meta_key', true ) : '',
'capability' => 'customize',
) );
$valor = get_post_meta( get_the_ID(), 'un_meta_key', true );
Usamos la propiedad ‘default’ para los controles
En la previsualización o front end final