Cómo modificar el comportamiento del tema padre dentro de un tema hijo
Spanish (Español) translation by Eva Collados Pascual (you can also view the original English article)
¿Qué son los temas hijo o child themes? Los temas hijo son una útil funcionalidad de WordPress que permite que los desarrolladores creen una nueva plantilla sin necesidad de empezar de cero, sino aprovechando las características disponibles en un tema ya existente.
Sin embargo, en ocasiones, es posible que el tema padre que hayamos elegido para nuestro sitio tenga algunas funcionalidades o características que no necesitamos (o queremos personalizarlo para que se adapte mejor a nuestras necesidades), por ejemplo, añadir tipos de entradas personalizadas que usen un slug distinto, shortcodes, librerías JavaScript, tamaños de imagen que no usamos, etc.
Personaliza el tema de dos formas
Aunque podría ser fácil conseguir lo que queremos editando el tema directamente, también es cierto que cada vez que lo actualicemos se sobreescribirán todas nuestras modificaciones, y por tanto tendremos que volver a realizarlas. Esto puede ser muy frustrante, pero por suerte tenemos otra opción: podemos crear un tema hijo y usar el archivo functions.php para modificar la funcionalidad del tema padre. De esta forma podremos actualizar el tema padre siempre que se publique una nueva versión sin perder todo aquello que hayamos personalizado.
Antes de entrar en detalles más concretos, una breve nota sobre la apariencia del tema: podemos modificar los colores, los fondos, la tipografía y la maquetación de página a través del archivo style.css del tema hijo, importando en él la hoja de estilos del tema padre y sobreescribiendo los estilos que queramos cambiar.
Para controlar mejor la maquetación de página, también podemos seguir las sugerencias de este artículo que propone Abbas Suterwala y clonar los archivos de plantilla personalizadas del tema padre en nuestro tema hijo:
Después el tema hijo podría opcionalmente sobreescribir otros archivos de plantilla como author.php, category.php, etc. El framework de WordPress buscará primero el archivo de plantilla en el directorio del tema hijo y si no lo encuentra allí, usará el ubicado en el directorio del tema padre.
Lo que podemos modificar
A través del archivo functions.php del tema hijo podremos gestionar lo siguiente:
- Características del tema
- Tipos de entradas personalizadas y taxonomías
- Menús y sidebars
- Widgets
- Shortcodes
- Tamaños de imágenes adicionales
- Metaboxes
- JavaScript y CSS
- Acciones y filtros del tema padre
Por tanto, imaginemos que tenemos la siguiente estructura en nuestro sitio web:
- htdocs O www
- wp-content
- themes
- foo-theme (directorio del tema padre - no será modificado)
- functions.php
- header.php
- style.css
- otros archivos de plantilla…
- foo-theme-child (directorio de nuestro tema hijo)
- functions.php (el archivo que usaremos para personalizar el tema padre)
- header.php (sobreescribe header.php por el tema padre)
- style.css (este es un archivo necesario en cualquier tema hijo y debe denominarse style.css)
- foo-theme (directorio del tema padre - no será modificado)
- themes
- wp-content
Empecemos: crea un archivo functions.php vacío en el directorio /wp-content/themes/foo-theme-child/.
Para la mayor parte usaremos una función genérica wp_tuts_remove_features()
, enganchada en la acción after_setup_theme
de WordPress. También establecemos 10
como nuestro tercer parámetro (para indicar la prioridad), de esta manera sabremos que la función se ejecutará antes que la del tema padre.
add_action( 'after_setup_theme', 'remove_parent_theme_features', 10 ); function remove_parent_theme_features() { // our code here }
1. Eliminar las características del tema
Algunos temas padre añaden características a WordPress a través de la función add_theme_support
.
Las características disponibles son:
Formatos de entrada (post-formats)
Miniaturas de entrada (post-thumbnails)
Fondos personalizados (custom-background)
Cabeceras personalizadas (custom-header)
Enlaces automáticos para los feeds (automatic-feed-links)
Por tanto, para eliminarlas, podemos modificar la función remove_parent_theme_features()
en nuestro archivo functions.php.
function remove_parent_theme_features() { remove_theme_support( 'post-formats' ); remove_theme_support( 'post-thumbnails' ); remove_theme_support( 'custom-background' ); remove_theme_support( 'custom-header' ); remove_theme_support( 'automatic-feed-links' ); }
2. Eliminar los tipos de entradas personalizadas
Eliminar tipos de entradas y taxonomías personalizadas es fácil: si el archivo functions.php del tema padre añade un tipo de entrada personalizada denominado Movie, a través de una función parent_movie_add_post_type()
:
// PARENT functions.php add_action( 'after_setup_theme', 'parent_movie_add_post_type' ); function parent_movie_add_post_type() { $parent_args = array( // other arguments... 'rewrite' => array( 'slug' => 'movie' ), 'supports' => array( 'title', 'editor', 'author', 'excerpt' ) ); register_post_type( 'movie', $parent_args ); }
…podemos personalizarla gracias al archivo functions.php de nuestro tema hijo:
// CHILD functions.php function remove_parent_theme_features() { // remove Movie Custom Post Type remove_action( 'init', 'parent_movie_add_post_type' ); /* alternatively, we can add our custom post type to overwrite only some aspects of the parent function */ add_action( 'init', 'child_movie_post_type' ); } function child_movie_post_type() { $child_args = array( // other arguments... // change Custom Post slug 'rewrite' => array( 'slug' => 'child-movie' ), // remove excerpts and add post thumbs 'supports' => array( 'title', 'editor', 'author', 'thumbnail' ) ); register_post_type( 'movie', $child_args ); }
También podemos eliminar sólo ciertas características sin eliminar el registro del tipo de entrada, por ejemplo, si queremos sustituir el campo del extracto por una imagen de entrada personalizada, podríamos modificar la función de la siguiente manera:
function remove_parent_theme_features() { add_action( 'init', 'wp_tuts_remove_post_feature' ); } function wp_tuts_remove_post_feature() { // remove excerpt remove_post_type_support( 'movie', 'excerpt' ); // add post thumbs add_post_type_support( 'movie', 'thumbnail' ); }
Puedes encontrar un listado completo de las funciones que puedes eliminar en el Codex de WordPress, dentro de con remove_post_type_support
.
Al igual que sucede con los tipos de entradas personalizadas, también puedes eliminar una taxonomía personalizada del tema padre mediante la función parent_taxonomy()
, de la siguiente forma:
function wp_tuts_after_setup_theme() { remove_action( 'init', 'parent_taxonomy' ); }
3. Eliminar menús
Podemos eliminar un menú del tema padre a través de la función unregister_nav_menu()
. Esta función acepta un parámetro, el slug identificador de la ubicación del menú usado en la función register_nav_menu()
.
Si el tema padre registra un Header Menu:
// PARENT functions.php add_action( 'after_setup_theme', 'register_my_menu' ); function register_my_menu() { register_nav_menu( 'header-menu', __( 'Header Menu' ) ); }
Podemos eliminarlo de la siguiente manera:
// CHILD functions.php function remove_parent_theme_features() { unregister_nav_menu( 'header-menu' ); }
Para identificar los menús registrados, podemos buscar las llamadas a register_nav_menu()
en el código del tema padre. El primer argumento de la función representa el ID del menú que podremos usar para eliminar su registro (en este caso el ID es header-menu
).
4. Eliminar widgets y sidebars
WordPress viene con algunos widgets predeterminados que podrías desactivar. Además, es posible que nuestro tema padre haya añadido también sus propios widgets, por tanto podríamos buscar entre los archivos del tema para descubrir dónde están declarados y anotar sus nombres. Normalmente están declarados mediante una clase PHP que extiende la clase WP_Widget
:
// PARENT theme class ParentWidgetName extends WP_Widget { // widget code }
Por tanto, para eliminar el registro de un widget, usaríamos el nombre de su clase, en este caso ParentWidgetName
:
add_action( 'widgets_init', 'wp_tuts_parent_unregister_widgets', 10 ); function wp_tuts_parent_unregister_widgets() { // remove (some) WordPress default Widgets unregister_widget( 'WP_Widget_Pages' ); unregister_widget( 'WP_Widget_Calendar' ); // remove Parent registered Widget unregister_widget( 'ParentWidgetName' ); // register a custom Widget (if needed) register_widget( 'MyCustomWidget' ); } // don't forget to add the Widget Class class MyCustomWidget extends WP_Widget { // Custom Widget code }
Para los sidebars la acción es similar:
add_action( 'widgets_init', 'wp_tuts_parent_unregister_sidebars', 10 ); function wp_tuts_parent_unregister_sidebars() { // remove a sidebar registered by the Parent Theme unregister_sidebar( 'first-footer-widget-area' ); }
Para identificar los sidebars registrados, podemos buscar en el código de nuestro tema padre y localizar las invocaciones register_sidebar()
.
Todo lo que necesitamos es anotar el ID del sidebar:
// PARENT functions.php $args = array( 'id' => 'first-footer-widget-area', // other args... ); register_sidebar( $args );
5. Eliminar shortcodes
Sobreescribir o eliminar shortcodes es fácil, sólo necesitamos modificar nuestra función de la siguiente manera:
function remove_parent_theme_features() { // remove the parent [gmap] shortcode remove_shortcode( 'gmap' ); // add our [gmap] shortcode add_shortcode( 'gmap', 'child_shortcode_gmap' ); } function child_shortcode_gmap( $atts ) { // create our shortcode that overwrites the parent one }
Para identificar los shortcodes registrados, podemos buscar en el código del tema padre las llamadas add_shortcode()
. El primer parámetro es el que estamos buscando ;-).
6. Eliminar tamaños de imagen adicionales
Si el tema padre añade nuevos tamaños de imagen que no vamos a usar en nuestro tema hijo, podemos buscar en su código las invocaciones a add_image_size()
. En este caso son: custom_size_parent_1
y custom_size_parent_2
. Las reseteamos de esta manera:
add_filter( 'intermediate_image_sizes_advanced', 'remove_parent_image_sizes' ); function remove_parent_image_sizes( $sizes ) { unset( $sizes['custom_size_parent_1'] ); unset( $sizes['custom_size_parent_2'] ); return $sizes; }
Esto es útil porque así cada vez que un usuario suba una imagen, WordPress no creará tamaños de imagen adicionales que después no vayamos a usar.
Para crear tamaños de imagen personalizados podemos añadir lo siguiente en el archivo functions.php de nuestro tema hijo:
if ( function_exists( 'add_image_size' ) ) { // 400 pixels wide and unlimited height add_image_size( 'custom_size_child_1', 400, 9999 ); // 320 pixels wide and 240 px tall, cropped add_image_size( 'custom_size_child_2', 320, 240, true ); }
7. Eliminar Metaboxes
Mediante la función remove_meta_box()
podemos eliminar las cajas de meta datos o metaboxes tanto del tema padre como las predeterminadas de WordPress.
Puedes consultar el listado completo de metaboxes predeterminados en WordPress dentro de la sección remove_meta_box
del Codexde WordPress. La función tiene tres argumentos: el ID del metabox, la página en la que será eliminado, el contexto de edición (normal
, advanced
, side
).
Si el tema padre añade metaboxes en la pantalla de edición, podemos dehabilitarlos de la siguiente manera:
add_action( 'admin_menu' , 'wp_tuts_remove_metaboxes', 99 ); function wp_tuts_remove_metaboxes() { // remove default WP Trackback Metabox from Posts editing page remove_meta_box( 'trackbacksdiv', 'post', 'normal' ); // remove a Parent Theme Metabox 'parent_post_foo_metabox' remove_meta_box( 'parent_post_foo_metabox', 'post', 'normal' ); }
Podemos identificar los metaboxes del tema padre buscando en su código las llamadas add_meta_box
o add_meta-boxes()
.
El ID del metabox a eliminar es el primer argumento de la función add_meta_box()
.
8. Eliminar JavaScript y las hojas de estilo CSS
Si el tema padre añade JavaScript y estilos CSS que no necesitamos:
// PARENT functions.php add_action( 'wp_print_scripts', 'parent_scripts' ); add_action( 'wp_print_styles', 'parent_styles' ); function parent_scripts() { wp_enqueue_script( 'fancybox-parent-js', get_stylesheet_directory_uri() . '/fancybox/jquery.fancybox.pack.js' ); } function parent_styles() { wp_enqueue_style( 'fancybox-parent-css', get_stylesheet_directory_uri() . '/fancybox/jquery.fancybox.css' ); }
Las podemos eliminar de la siguiente manera:
// CHILD functions.php add_action( 'wp_print_scripts', 'child_overwrite_scripts', 100 ); add_action( 'wp_print_styles', 'child_overwrite_styles', 100 ); function child_overwrite_scripts() { wp_deregister_script( 'fancybox-parent-js' ); } function child_overwrite_styles() { wp_deregister_style( 'fancybox-parent-css' ); }
Para identificar los estilos JavaScript y CSS registrados, podemos buscar en el código del tema padre las llamadas wp_enqueue_script()
y wp_enqueue_style()
.
El primer argumento de la función es lo que podemos usar en las funciones wp_deregister_script()
o wp_deregister_style()
.
9. Eliminar las acciones y los filtros del tema padre
Algunos temas, como Thematic, proporcionan varios hooks para modificar su comportamiento sin alterar sus archivos. En este caso, Thematic proporciona una acción thematic_header
que se encarga de cargar otras acciones:
thematic_brandingopen()
thematic_blogtitle()
thematic_blogdescription()
thematic_brandingclose()
thematic_access()
Nosotros no examinaremos en detalle qué hacen estas funciones, probablemente algunas de ellas proporcionen salida a algunos datos en la cabecera del blog: el nombre, la descripción, etc… En este caso podemos desactivar la función thematic_blogdescription()
de esta forma:
// Unhook default Thematic functions function unhook_thematic_functions() { // we put the position number of the original function (5) // for priority reasons remove_action( 'thematic_header', 'thematic_blogdescription', 5 ); } add_action( 'init', 'unhook_thematic_functions' );
En estos casos puede ser complicado entender la estructura del tema padre y cómo funciona esta. Mi consejo es que elijas un tema padre que cuente con una documentación detallada, un buen foro de soporte, y disponga de hooks en su código.
Esto seguramente nos hará perder menos tiempo durante el desarrollo y conseguirá que la personalización del tema hijo sea más sencilla.
Referencias
- Fundamentos de temas hijo y cómo crear temas hijo en WordPress
- Documentación disponible en el Codex de WordPress
after_setup_theme
remove_action
add_theme_support
register_post_type
add_post_type_support
remove_post_type_support
register_nav_menu
unregister_nav_menu
register_widget
unregister_widget
register_sidebar
unregister_sidebar
add_shortcode
remove_shortcode
add_image_size
add_meta_box
remove_meta_box
wp_deregister_script
wp_deregister_style
- Una colección de temas padre para WordPress
- Thematic Theme Framework