1. Code
  2. Game Development

Cómo modificar el comportamiento del tema padre dentro de un tema hijo

¿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.
Scroll to top

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)

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.

1
add_action( 'after_setup_theme', 'remove_parent_theme_features', 10 );
2
3
function remove_parent_theme_features() {
4
	// our code here

5
}

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.

1
function remove_parent_theme_features() {
2
	remove_theme_support( 'post-formats' );
3
	remove_theme_support( 'post-thumbnails' );
4
	remove_theme_support( 'custom-background' );
5
	remove_theme_support( 'custom-header' );
6
	remove_theme_support( 'automatic-feed-links' );
7
}

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():

1
// PARENT functions.php

2
3
add_action( 'after_setup_theme', 'parent_movie_add_post_type' );
4
5
function parent_movie_add_post_type() {
6
7
	$parent_args = array(
8
		// other arguments...

9
		'rewrite' => array( 'slug' => 'movie' ),
10
		'supports' => array( 'title', 'editor', 'author', 'excerpt' )
11
	);
12
	register_post_type( 'movie', $parent_args );
13
}

…podemos personalizarla gracias al archivo functions.php de nuestro tema hijo:

1
// CHILD functions.php

2
3
function remove_parent_theme_features() {
4
	// remove Movie Custom Post Type

5
	remove_action( 'init', 'parent_movie_add_post_type' );
6
	/*

7
	alternatively, we can add our custom post type to 

8
	overwrite only some aspects of the parent function

9
	*/
10
	add_action( 'init', 'child_movie_post_type' );
11
}
12
13
function child_movie_post_type() {
14
	$child_args = array(
15
		// other arguments...

16
		// change Custom Post slug

17
		'rewrite' => array( 'slug' => 'child-movie' ),
18
		// remove excerpts and add post thumbs

19
		'supports' => array( 'title', 'editor', 'author', 'thumbnail' )
20
	);
21
22
	register_post_type( 'movie', $child_args );
23
}

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:

1
function remove_parent_theme_features() {
2
	add_action( 'init', 'wp_tuts_remove_post_feature' );
3
}
4
5
function wp_tuts_remove_post_feature() {
6
	// remove excerpt

7
	remove_post_type_support( 'movie', 'excerpt' );
8
	// add post thumbs

9
	add_post_type_support( 'movie', 'thumbnail' );
10
}

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:

1
function wp_tuts_after_setup_theme() {
2
	remove_action( 'init', 'parent_taxonomy' );
3
}

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:

1
// PARENT functions.php

2
3
add_action( 'after_setup_theme', 'register_my_menu' );
4
5
function register_my_menu() {
6
	register_nav_menu( 'header-menu', __( 'Header Menu' ) );
7
}

Podemos eliminarlo de la siguiente manera:

1
// CHILD functions.php

2
3
function remove_parent_theme_features() {
4
	unregister_nav_menu( 'header-menu' );
5
}

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:

1
// PARENT theme

2
class ParentWidgetName extends WP_Widget {
3
	// widget code

4
}

Por tanto, para eliminar el registro de un widget, usaríamos el nombre de su clase, en este caso ParentWidgetName:

1
add_action( 'widgets_init', 'wp_tuts_parent_unregister_widgets', 10 );
2
3
function wp_tuts_parent_unregister_widgets() {
4
5
	// remove (some) WordPress default Widgets

6
	unregister_widget( 'WP_Widget_Pages' );
7
	unregister_widget( 'WP_Widget_Calendar' );
8
9
	// remove Parent registered Widget

10
	unregister_widget( 'ParentWidgetName' );
11
12
	// register a custom Widget (if needed)

13
	register_widget( 'MyCustomWidget' );
14
}
15
16
// don't forget to add the Widget Class

17
class MyCustomWidget extends WP_Widget {
18
	// Custom Widget code

19
}

Para los sidebars la acción es similar:

1
add_action( 'widgets_init', 'wp_tuts_parent_unregister_sidebars', 10 );
2
3
function wp_tuts_parent_unregister_sidebars() {
4
	// remove a sidebar registered by the Parent Theme

5
	unregister_sidebar( 'first-footer-widget-area' );
6
}

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:

1
// PARENT functions.php

2
3
$args = array(
4
	'id' => 'first-footer-widget-area',
5
	// other args...

6
);
7
8
register_sidebar( $args );

5. Eliminar shortcodes

Sobreescribir o eliminar shortcodes es fácil, sólo necesitamos modificar nuestra función de la siguiente manera:

1
function remove_parent_theme_features() {
2
	// remove the parent [gmap] shortcode

3
	remove_shortcode( 'gmap' );
4
	// add our [gmap] shortcode

5
	add_shortcode( 'gmap', 'child_shortcode_gmap' );
6
}
7
8
function child_shortcode_gmap( $atts ) {
9
	// create our shortcode that overwrites the parent one

10
}

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:

1
add_filter( 'intermediate_image_sizes_advanced', 'remove_parent_image_sizes' );
2
3
function remove_parent_image_sizes( $sizes ) {
4
	unset( $sizes['custom_size_parent_1'] );
5
	unset( $sizes['custom_size_parent_2'] );
6
	return $sizes;
7
}

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:

1
if ( function_exists( 'add_image_size' ) ) {
2
	// 400 pixels wide and unlimited height

3
	add_image_size( 'custom_size_child_1', 400, 9999 );
4
	// 320 pixels wide and 240 px tall, cropped

5
	add_image_size( 'custom_size_child_2', 320, 240, true );
6
}

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:

1
add_action( 'admin_menu' , 'wp_tuts_remove_metaboxes', 99 );
2
3
function wp_tuts_remove_metaboxes() {
4
	// remove default WP Trackback Metabox from Posts editing page

5
	remove_meta_box( 'trackbacksdiv', 'post', 'normal' );
6
	// remove a Parent Theme Metabox 'parent_post_foo_metabox'

7
	remove_meta_box( 'parent_post_foo_metabox', 'post', 'normal' );
8
}

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:

1
// PARENT functions.php

2
3
add_action( 'wp_print_scripts', 'parent_scripts' );
4
add_action( 'wp_print_styles', 'parent_styles' );
5
6
function parent_scripts() {
7
	wp_enqueue_script( 'fancybox-parent-js', get_stylesheet_directory_uri() . '/fancybox/jquery.fancybox.pack.js' );
8
}
9
10
function parent_styles() {
11
	wp_enqueue_style( 'fancybox-parent-css', get_stylesheet_directory_uri() . '/fancybox/jquery.fancybox.css' );
12
}

Las podemos eliminar de la siguiente manera:

1
// CHILD functions.php

2
3
add_action( 'wp_print_scripts', 'child_overwrite_scripts', 100 );
4
add_action( 'wp_print_styles', 'child_overwrite_styles', 100 );
5
6
function child_overwrite_scripts() {
7
	wp_deregister_script( 'fancybox-parent-js' );
8
}
9
10
function child_overwrite_styles() {
11
	wp_deregister_style( 'fancybox-parent-css' );
12
}

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:

1
// Unhook default Thematic functions

2
function unhook_thematic_functions() {
3
	// we put the position number of the original function (5)

4
	// for priority reasons

5
	remove_action( 'thematic_header', 'thematic_blogdescription', 5 );
6
}
7
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