Caldeira do personalizador de temas do WordPress
- 1. Introdução ao personalizador de temas do WordPress
- 2. Interagindo com o WordPress Theme Customizer
- 3. Atualmente lendo: WordPress Theme Customizer Boilerplate
- 4. Estendendo o padrão do personalizador de temas do WordPress
- 5. Personalizador de Temas: Condicionais, Temas Filhos e Plugins
Atualização: Este artigo foi editado em 19 de fevereiro de 2013, para refletir as alterações feitas no Theme Customizer Boilerplate.
Espero que você tenha lido e gostado dos dois primeiros posts da série Theme Customizer – Introdução ao WordPress Theme Customizer e Interagindo com o Theme Customizer . Agora é hora de passar para o prato principal e começar a montar o clichê do Personalizador de Temas que você poderá usar em seus temas. Este post contém alguns longos blocos de código, então preste atenção aos comentários embutidos.
Nota: Se você preferir apenas usar o clichê imediatamente, você pode baixá-lo do Github e alterar os campos no array $options conectando-se ao gancho de filtro ‘thsp_cbp_options_array’.
O que estamos criando
Estrutura de diretórios do personalizador de temas Boilerplate
- customizer.php – Este é o principal arquivo clichê do Customizador de Tema, aquele que adiciona seções, configurações e controles usando dados do array de opções
- custom-controls.php – classes de controles personalizados e um gancho de ação que permite adicionar seus próprios controles personalizados
- helpers.php – Funções auxiliares, usadas para recuperar opções de temas, padrões de opções etc.
- options.php – Opções de amostra e um gancho de filtro que permite editar o array de opções e usar seus próprios campos
- customizer-controls.css – CSS básico para controle personalizado de rádio substituído por imagem
A idéia toda é poder copiar esses arquivos para um subdiretório no diretório do seu tema, incluir o arquivo customizer.php do seu functions.php e alterar o que quiser, incluindo e especialmente o array de opções, usando os ganchos do Theme Customizer Boilerplate (explicado na Parte 4). Atualização: Anteriormente, você apenas editava options.php, mas usar ganchos torna as coisas muito mais limpas.
Agora vamos usar um exemplo real — adicionaremos um controle de texto a uma nova seção do Personalizador de Tema. A matriz é colocada em uma função auxiliar e tem um filtro aplicado a ela quando retornada. Dessa forma, você pode adicionar mais opções de um tema filho ou plugin. Aqui está:
/**
* Helper function that holds array of theme options.
*
* @return array $options Array of theme options
* @uses thsp_get_theme_customizer_fields() defined in customizer/helpers.php
*/
function thsp_get_theme_customizer_fields() {
/*
* Using helper function to get default required capability
*/
$required_capability = thsp_settings_page_capability();
$options = array(
// Section ID
‘new_customizer_section’ => array(
/*
* We’re checking if this is an existing section
* or a new one that needs to be registered
*/
‘existing_section’ => false,
/*
* Section related arguments
* Codex – http://codex.wordpress.org/Class_Reference/WP_Customize_Manager/add_section
*/
‘args’ => array(
‘title’ => __( ‘New Section Title’, ‘my_theme_textdomain’ ),
‘description’ => __( ‘New section description’, ‘my_theme_textdomain’ ),
‘priority’ => 10
),
/*
* ‘fields’ array contains all the fields that need to be
* added to this section
*/
‘fields’ => array(
/*
* ==========
* ==========
* Text field
* ==========
* ==========
*/
// Field ID
‘new_text_field’ => array(
/*
* Setting related arguments
* Codex – http://codex.wordpress.org/Class_Reference/WP_Customize_Manager/add_setting
*/
‘setting_args’ => array(
‘default’ => __( ‘Default text value’, ‘my_theme_textdomain’ ),
‘type’ => ‘option’,
‘capability’ => $required_capability,
‘transport’ => ‘refresh’,
‘sanitize_callback’ => ‘thsp_sanitize_cb’,
),
/*
* Control related arguments
* Codex – http://codex.wordpress.org/Class_Reference/WP_Customize_Manager/add_control
*/
‘control_args’ => array(
‘label’ => __( ‘New text control label’, ‘my_theme_textdomain’ ),
‘type’ => ‘text’, // Text field control
‘priority’ => 1
)
)
)
),
);
/*
* ‘thsp_customizer_options’ filter hook will allow you to
* add/remove some of these options from a child theme
*/
return apply_filters( ‘thsp_customizer_options’, $options );
}
Atualização: A matriz permanece a mesma, mas agora você também pode passar a matriz de opções para um gancho de filtro, consulte a Parte 4 para obter mais detalhes.
Parece complicado à primeira vista, eu sei, mas deixe-me explicar.
O array $options consiste em seções (apenas uma neste caso – new_customizer_section), cada seção tem seus argumentos, campos e um valor booleano (existing_section) para indicar se é uma nova seção, ou estamos apenas adicionando alguns campos a um já existente. O array de argumentos é idêntico ao que você passaria para o método $wp_customize->add_section . A matriz de campos é um pouco mais complexa.
Atualização: a matriz de opções nos argumentos de controle agora é uma matriz multidimensional.
Cada campo consiste em uma configuração do Personalizador e um controle do Personalizador. É por isso que temos os arrays setting_args e control_args. Eles são quase exatamente os mesmos que os arrays de argumentos que você passaria para os métodos $wp_customize->add_setting e $wp_customize-> add_control . A única diferença é o array ‘choices’ nos argumentos de controle, $wp_customize->add_control requer que seja um array de par de chave => valor e estamos usando um array multidimensional.
Desta forma é possível passar mais dados para cada uma das opções, então se você estiver, por exemplo, carregando Google Fonts em seu tema, poderá ter strings que permitem carregar a fonte correta dentro do array de opções . Você pode ver um exemplo deste tema que usa Customizer Boilerplate .
Então, se você já conhece esses três métodos, tudo é muito familiar.
Adicionar um controle de caixa de seleção é quase o mesmo, você só precisa alterar ‘tipo’ para ‘caixa de seleção’ no array ‘control_args’:
/*
* ==============
* Checkbox field
* ==============
*/
‘new_checkbox_field’ => array(
‘setting_args’ => array(
‘default’ => true,
‘type’ => ‘option’,
‘capability’ => $required_capability,
‘transport’ => ‘refresh’,
‘sanitize_callback’ => ‘thsp_sanitize_cb’,
),
‘control_args’ => array(
‘label’ => __( ‘New radio control label’, ‘my_theme_textdomain’ ),
‘type’ => ‘checkbox’, // Checkbox field control
‘priority’ => 2
)
),
Os controles de rádio e seleção são quase os mesmos, você só precisa especificar as opções fornecidas:
/*
* ===========
* ===========
* Radio field
* ===========
* ===========
*/
‘new_radio_field’ => array(
‘setting_args’ => array(
‘default’ => ‘option-2’,
‘type’ => ‘option’,
‘capability’ => $thsp_cbp_capability,
‘transport’ => ‘refresh’,
),
‘control_args’ => array(
‘label’ => __( ‘New radio control label’, ‘my_theme_textdomain’ ),
‘type’ => ‘radio’, // Radio control
‘choices’ => array(
‘option-1’ => array(
‘label’ => __( ‘Option 1’, ‘my_theme_textdomain’ )
),
‘option-2’ => array(
‘label’ => __( ‘Option 2’, ‘my_theme_textdomain’ )
),
‘option-3’ => array(
‘label’ => __( ‘Option 3’, ‘my_theme_textdomain’ )
)
),
‘priority’ => 3
)
),
/*
* ============
* ============
* Select field
* ============
* ============
*/
‘new_select_field’ => array(
‘setting_args’ => array(
‘default’ => ‘option-3’,
‘type’ => ‘option’,
‘capability’ => $thsp_cbp_capability,
‘transport’ => ‘refresh’,
),
‘control_args’ => array(
‘label’ => __( ‘New select field label’, ‘my_theme_textdomain’ ),
‘type’ => ‘select’, // Select control
‘choices’ => array(
‘option-1’ => array(
‘label’ => __( ‘Option 1’, ‘my_theme_textdomain’ )
),
‘option-2’ => array(
‘label’ => __( ‘Option 2’, ‘my_theme_textdomain’ )
),
‘option-3’ => array(
‘label’ => __( ‘Option 3’, ‘my_theme_textdomain’ )
)
),
‘priority’ => 4
)
)
E, finalmente, dois tipos de controle complexos que são incorporados ao WordPress — upload de arquivo e upload de imagem:
/*
* ===========
* ===========
* File Upload
* ===========
* ===========
*/
‘new_file_upload_field’ => array(
‘setting_args’ => array(
‘default’ => ”,
‘type’ => ‘option’,
‘capability’ => $thsp_cbp_capability,
‘transport’ => ‘refresh’,
),
‘control_args’ => array(
‘label’ => __( ‘File upload’, ‘my_theme_textdomain’ ),
‘type’ => ‘upload’, // File upload field control
‘priority’ => 5
)
),
/*
* ============
* ============
* Image Upload
* ============
* ============
*/
‘new_image_upload_field’ => array(
‘setting_args’ => array(
‘default’ => ”,
‘type’ => ‘option’,
‘capability’ => $thsp_cbp_capability,
‘transport’ => ‘refresh’,
),
‘control_args’ => array(
‘label’ => __( ‘Image upload’, ‘my_theme_textdomain’ ),
‘type’ => ‘image’, // Image upload field control
‘priority’ => 6
)
)
Observe que usei ‘type’ => ‘option’ na configuração de argumentos para todos esses campos. Isso permitirá que todos os valores sejam armazenados como um valor em seu banco de dados. A alternativa é ‘type’ => ‘theme_mod’ mas por enquanto vamos ficar com ‘option’.
Usando a matriz de opções para adicionar seções, configurações e controles do personalizador
Se você não tem certeza de como interagir com o WordPress Theme Customizer , vá e verifique, porque é isso que faremos agora. A única diferença é que, em vez de adicionar seções, configurações e controles, um de cada vez, automatizaremos o processo usando o array serializado que criamos. Vamos pular nele:
function thsp_cbp_customize_register( $wp_customize ) {
/**
* Custom controls
*/
require( dirname(__FILE__) . ‘/custom-controls.php’ );
/*
* Get all the fields using a helper function
*/
$thsp_sections = thsp_cbp_get_fields();
/*
* Get name of DB entry under which options will be stored
*/
$thsp_cbp_option = thsp_cbp_option();
/**
* Loop through the array and add Customizer sections
*/
foreach( $thsp_sections as $thsp_section_key => $thsp_section_value ) {
/**
* Adds Customizer section, if needed
*/
if( ! $thsp_section_value[‘existing_section’] ) {
$thsp_section_args = $thsp_section_value[‘args’];
// Add section
$wp_customize->add_section(
$thsp_section_key,
$thsp_section_args
);
} // end if
/*
* Loop through ‘fields’ array in each section
* and add settings and controls
*/
$thsp_section_fields = $thsp_section_value[‘fields’];
foreach( $thsp_section_fields as $thsp_field_key => $thsp_field_value ) {
/*
* Check if ‘option’ or ‘theme_mod’ is used to store option
*
* If nothing is set, $wp_customize->add_setting method will default to ‘theme_mod’
* If ‘option’ is used as setting type its value will be stored in an entry in
* {prefix}_options table. Option name is defined by thsp_cbp_option() function
*/
if ( isset( $thsp_field_value[‘setting_args’][‘type’] ) && ‘option’ == $thsp_field_value[‘setting_args’][‘type’] ) {
$setting_control_id = $thsp_cbp_option . ‘[‘ . $thsp_field_key . ‘]’;
} else {
$setting_control_id = $thsp_field_key;
}
/*
* Add default callback function, if none is defined
*/
if ( ! isset( $thsp_field_value[‘setting_args’][‘sanitize_cb’] ) ) {
$thsp_field_value[‘setting_args’][‘sanitize_cb’] = ‘thsp_cbp_sanitize_cb’;
}
/**
* Adds Customizer settings
*/
$wp_customize->add_setting(
$setting_control_id,
$thsp_field_value[‘setting_args’]
);
/**
* Adds Customizer control
*
* ‘section’ value must be added to ‘control_args’ array
* so control can get added to current section
*/
$thsp_field_value[‘control_args’][‘section’] = $thsp_section_key;
/*
* $wp_customize->add_control method requires ‘choices’ to be a simple key => value pair
*/
if ( isset( $thsp_field_value[‘control_args’][‘choices’] ) ) {
$thsp_cbp_choices = array();
foreach( $thsp_field_value[‘control_args’][‘choices’] as $thsp_cbp_choice_key => $thsp_cbp_choice_value ) {
$thsp_cbp_choices[$thsp_cbp_choice_key] = $thsp_cbp_choice_value[‘label’];
}
$thsp_field_value[‘control_args’][‘choices’] = $thsp_cbp_choices;
}
// Check control type
if ( ‘color’ == $thsp_field_value[‘control_args’][‘type’] ) {
$wp_customize->add_control(
new WP_Customize_Color_Control(
$wp_customize,
$setting_control_id,
$thsp_field_value[‘control_args’]
)
);
} elseif ( ‘image’ == $thsp_field_value[‘control_args’][‘type’] ) {
$wp_customize->add_control(
new WP_Customize_Image_Control(
$wp_customize,
$setting_control_id,
$thsp_field_value[‘control_args’]
)
);
} elseif ( ‘upload’ == $thsp_field_value[‘control_args’][‘type’] ) {
$wp_customize->add_control(
new WP_Customize_Upload_Control(
$wp_customize,
$setting_control_id,
$thsp_field_value[‘control_args’]
)
);
} else {
$wp_customize->add_control(
$setting_control_id,
$thsp_field_value[‘control_args’]
);
}
} // end foreach
} // end foreach
}
add_action( ‘customize_register’, ‘thsp_cbp_customize_register’ );
Percorrendo todas as seções, adicionando as que ainda não existem, depois percorrendo todos os campos de cada seção, adicionando uma configuração e um controle para cada uma. Isso é tudo o que está acontecendo aqui.
Lembra que usamos ‘type’ => ‘option’ para todas as configurações? É por isso que agora temos “my_theme_options[$thsp_field_key]” para configurações e seções. Isso armazenará todos os valores como um array serializado que você pode recuperar usando get_option( ‘my_theme_options’ ) . Ou você pode simplesmente usar funções auxiliares definidas em helpers.php para recuperar os valores atuais e os valores padrão para todos os campos:
/**
* Get Option Values
*
* Array that holds all of the options values
* Option’s default value is used if user hasn’t specified a value
*
* @uses thsp_get_theme_customizer_defaults() defined in /customizer/options.php
* @return array Current values for all options
* @since Theme_Customizer_Boilerplate 1.0
*/
function thsp_cbp_get_options_values() {
// Get the option defaults
$option_defaults = thsp_cbp_get_options_defaults();
// Parse the stored options with the defaults
$thsp_cbp_options = wp_parse_args( get_option( thsp_cbp_option(), array() ), $option_defaults );
// Return the parsed array
return $thsp_cbp_options;
}
/**
* Get Option Defaults
*
* Returns an array that holds default values for all options
*
* @uses thsp_get_theme_customizer_fields() defined in /customizer/options.php
* @return array $thsp_option_defaults Default values for all options
* @since Theme_Customizer_Boilerplate 1.0
*/
function thsp_cbp_get_options_defaults() {
// Get the array that holds all theme option fields
$thsp_sections = thsp_cbp_get_fields();
// Initialize the array to hold the default values for all theme options
$thsp_option_defaults = array();
// Loop through the option parameters array
foreach ( $thsp_sections as $thsp_section ) {
$thsp_section_fields = $thsp_section[‘fields’];
foreach ( $thsp_section_fields as $thsp_field_key => $thsp_field_value ) {
// Add an associative array key to the defaults array for each option in the parameters array
if( isset( $thsp_field_value[‘setting_args’][‘default’] ) ) {
$thsp_option_defaults[$thsp_field_key] = $thsp_field_value[‘setting_args’][‘default’];
} else {
$thsp_option_defaults[$thsp_field_key] = false;
}
}
}
// Return the defaults array
return $thsp_option_defaults;
}
Há apenas mais uma coisa que devo mencionar – função de retorno de chamada de sanitização que especificamos no array ‘setting_args’. A função é definida em extend.php e simplesmente executa os dados através da função wp_kses_post :
/**
* Theme Customizer sanitization callback function
*/
function thsp_sanitize_cb( $input ) {
return wp_kses_post( $input );
}
Para onde a partir daqui?
Por enquanto, você pode usar este Theme Customizer Boilerplate em seus temas, tudo que você precisa fazer é baixá-lo do Github, copiar para o diretório do seu tema e incluir o arquivo principal de functions.php, que é 100% funcional e bom o suficiente para a maioria temas.
Como seu tema não é “como a maioria dos temas”, na próxima semana veremos como estender o clichê usando seu filtro e ganchos de ação.
Eu adoraria saber como você acha que esse clichê poderia ser melhorado ou expandido, então, por favor, dispare nos comentários.