Si trabajas con temas hijos, ya sabrás que los archivos de la plantilla que tengas en tu tema hijo tienen prioridad sobre los que estan en el tema padre, de forma que puedes hacer modificaciones de forma sencilla sin tocar el código del tema padre. Tambíen debes saber que a traves del archivo functions.php puedes añadir nuevos CSS personalizados a tu gusto de forma que puedas sobreescribir los estilos que más te interesan, pero ¿que sucede con las funciones?
Se podría pensar que con las funciones sucede lo mismo: creamos una función en el tema hijo con el mismo nombre que en el tema padre, y esta va a tener prioridad. Pero por desgracia no es tan sencillo como esto.
En este tutorial voy a mostrar tres métodos que puedes utilizar para anular las funciones del tema padres dando prioridad a las funciones que crees en el tema hijo, asi pues vamos a tener que utilizar uno de los métodos explicados a continuación según el caso:
- Funciones enchufables
- Cambiar la prioridad de ejecución de una función
- Eliminación de las funciones que esten unidas a un hook.
Cómo se cargan las Funciones en el tema padre e hijo.
Antes de examinar los métodos sobreescribir las funciones en tu tema hijo, permíteme una breve explicación de como trabajan las funciones en los temas padre e hijo.
En primer lugar, es necesario saber que todas las funciones en los tema padre se ejecutarán cuando se estés utilizando un tema hijo. No tiene que añadir nada al archivo functions.php de tu tema hijo para que esto suceda. Esto funciona de forma diferente al CSS como explicabamos anteriormente.
Las funciones en los temas hijos se cargan antes que las funciones del tema padre. Esto significa que si el tema padre e hijo comparten una misma funcion, por ejemplo my_function()
y hacen un trabajo similar, La función que esta en el tema padré se cargará despues, lo que significa que anulará la que tengamos en el tema hijo.
Sin embargo, podemos cambiar el orden en el que se disparan las funciones, y se puede evitar que queden anuladas por completo, como veremos en breve.
Funciones enchufables
Las funciones enchufables contienen un par de lineas más de código, que lo que hacen es comprobar y definir la función en caso de que esta no exista. En este caso no hay que hacer nada, ya que la función en el tema padre no se ejecutará si ya existe en el tema hijo.
Si estas escribiendo tu propio tema padre, es una buena práctica para definir las funciones, ya que de esta manera se pueden reemplazar facilmente en los temas hijos.
Para escribir una función enchufable, sólo tienes que encerrar la función en un código condicional para comprobar si una función con ese nombre ya se ha ejecutado:
if ( ! function_exists ( ‘my_function’ ) ) {
function my_function() {
// Aquí el contenido.
}
}
Así que solo tendremos que comprobar si este es el caso de la funcion que queremos sobreescribir, y si es así, escribir en el tema hijo la función con el mismo nombre y el código que necesitemos ejecutar:
function my_function() {
// Aqui el código que quieres sobreescribir.
}
WordPress ejecutará la función en el tema hijo primero, y cuando vaya a cargar las funciones del tema padre comprobará que ya existe y se saltara la función en el tema padre.
Modificar la prioridad de la función
En caso de que el metodo anterior no sea aplicable, ya porque no estás utilizando tu propio tema padre o bien estás utilizando un tercero sin funciones enchufables, necesitarás otro método.
Cuando se escribe funciones en WordPress se le puede asignar una prioridad, que le dice cuando WordPress debe ejecutarlas. Esto se hace al agregar la función a un filtro o acción (hook). WordPress ejecutará las funciones unidas a un hook en orden ascendente de prioridad, por lo que aquellos con números más altos se ejecutarán después.
Imaginemos la función en el tema principal no es enchufable, y se ve así:
function parent_function() {
// Aquí el contenido de la función.
}
add_action( 'init', 'parent_function' );
Esta función está unido al hook init
y no tiene definida una prioridad. Por defecto WordPress asigna una prioridad 10
a las funciones a las que no se ha añadido una prioridad, por lo que para que se ejecute después necesitamos poner una prioridad mayor que 10
.
Esto significa que la función del tema hijo podría quedar así:
function child_function() {
// Aquí el contenido.
}
add_action( 'init', 'child_function', 15 );
Por otra parte, la función en el tema de los padres puede haber tenido una prioridad asignada a la misma:
function parent_function() {
// Aquí el contenido.
}
add_action( 'init', 'parent_function', 20 );
Por lo que sólo tienes que asegurarte de que la prioridad que des des a tu función en el tema hijo sea más alta:
function child_function() {
// Aquí el contenido.
}
add_action( 'init', 'child_function', 25 );
La eliminación de las funciones de los ganchos
Hay situaciones que debemos asegurarnos de que la función en el tema padre no se ejecute porque los métodos anteriores no acabaron de funcionar. En este caso, se puede quitar la función del tema padre del hook al que está conectado, mediante las funcionesremove_action()
o remove_filter()
. La que se utilice dependerá de si la función está unido a un filter hook o aun action hook en el tema padre.
Así que volvamos a nuestra función anterior en el tema de los padres:
function parent_function() {
// Aquí el contenido.
}
add_action( 'init', 'parent_function' );
Para eliminar esta función de su action hook y, por tanto, evitar que se dispare, se crea una función en el tema hijo para quitarlo usando remove_action()
:
remove_action( 'init', 'parent_function' );
Sin embargo, esto no funcionará por sí solo; debe adjuntar esta función a un gancho que se activará después del enlace al que está asociada la función de tema principal. Esto se debe a que no puedes eliminar la acción antes de que se haya disparado.
Sin embargo, esto no va a trabajar por si sólo, debes añadir esta función a un hook que se active despues del hook que se ejecuta en el tema padre, ya que no es posible eliminar una acción que todavía no se ha disparado. Puede encontrar detalles de la orden en el que las acciones se disparan en el Codex.
function child_remove_parent_function() {
remove_action( 'init', 'parent_function' );
}
add_action( 'wp_loaded', 'child_remove_parent_function' );
Una vez hecho esto, simplemente hay que escribir una función alternativa para reemplazar la función del tema padre en el archivo functions.php del tema hijo, o puedeno necesitar hacer nada si todo lo que quería hacer era eliminar la funcionalidad del tema de los padres.
Una nota sobre las prioridades
Ten en cuenta que si estas tratando de eliminar una función utilizando remove_action()
o remove_filter()
y la función ha tenido una prioridad asignada a la misma, en tu función debes añadir el mismo valor para la prioridad o no va a funcionar.
Así que si la función del tema padres se ve así:
function parent_function() {
// Aquí el contenido.
}
add_action( 'init', 'parent_function', 15 )
… tendrás que incluir el mismo valor de prioridad al retirarlo:
function child_remove_parent_function() {
remove_action( 'widgets_init', 'parent_function', 15 );
}
add_action( 'wp_loaded', 'child_remove_parent_function' );
Resumen
La anulación o sobreescritura de funciones de un tema padre es más complicado que anular archivos de plantilla o estilo, pero se puede hacer. Aquí hemos visto tres métodos para conseguirlo:
- Si estás escribiendo tu propio tema padre, utiliza funciones conectables de manera que una función en el tema hijo con el mismo nombre lo reemplace.
- Asigna mayor prioridad a las funciones tu tema hijo para asegurarte de que se ejecuten despues de las del tema padre y pueda funcionar tal como esperas.
- Usa
remove_action()
oremove_filter()
para quitar funciones en el tema padre por completo.
El método que utilices dependerá de la forma en que el tema padre esté codificado y si es necesario eliminar la función por completo de los temas padres, o simplemente ejecutar otra función después que anule la primera.
5 comentarios
Excelente artículo. Muchas gracias por la aportación.
Tan sólo si pudiera aclararme: en mi caso, quiero quitar el search bar del que lo contiene, y reubircarlo o crearle otro en otra parte de la web.
Para quitarlo, he pensado hacerlo con css, indicando en el child theme, para el correspondiente, «display: none» ¿es la forma más adecuada de hacerlo?
Para crearle otro en otra parte de la web, ¿como podría hacerlo en el child theme?
Gracias por adelantado
Disculpe, quería decir : […] quiero quitar el search bar del «div» que lo contiene,
Buenos dias, si lo que quieres es reubicar la barra de busqueda seguramente con algún hook lo podrás hacer. ¿Que tema estas utilizando?
Si copias un post de otra persona deberias mencionar la fuente. NO es muy etico no hacerlo.
https://code.tutsplus.com/tutorials/a-guide-to-overriding-parent-theme-functions-in-your-child-theme–cms-22623
Un saludo,
Yolanda
Buenas tardes, gracias por tu comentario y ahora en adelante cuando sea una traducción indicaré la fuente.