Sobrescribir la traducción del tema padre en el tema hijo
Tengo un tema padre que usa correctamente load_theme_textdomain()
para cargar todas las cadenas traducidas en varios idiomas.
Luego creé un tema hijo que usa load_child_theme_textdomain()
para lograr lo mismo con sus cadenas.
Hay ciertas cadenas traducidas para un idioma particular en el tema padre que me gustaría reemplazar/sobrescribir en el tema hijo.
Sé que si estuvieran en un archivo de plantilla podría reemplazar el archivo y simplemente cambiar el textdomain para esas cadenas, pero desafortunadamente las que menciono se usan en muchos lugares y también en el panel de administración (así que están dentro de algunas funciones de filtros/acciones).
Entonces mi pregunta es: ¿hay alguna manera de reemplazar esas cadenas traducidas dentro del tema hijo sin tener que reemplazar los archivos de plantilla o funciones del padre?
No sé, tal vez agregando un archivo parent-theme.mo dentro de la carpeta languages del tema hijo con solo esas cadenas traducidas, o algo así.

Creo que encontré una solución, pero antes un poco de
Premisa
load_theme_textdomain()
y load_child_theme_textdomain()
son básicamente iguales, la única diferencia es la ruta predeterminada que usan:
- obtienen el idioma actual (usando
get_locale()
) y añaden el archivo .mo relativo a la ruta pasada como argumento; - luego llaman a
load_textdomain()
pasando como argumento tanto el dominio de texto como la ruta resultante al archivo .mo.
Entonces load_textdomain
carga el archivo .mo en la variable global del dominio de texto, pero como podemos leer en el código fuente:
Si el dominio ya existe, las traducciones se fusionarán.
Si ambos conjuntos tienen la misma cadena, se tomará la traducción del valor original.
Por lo tanto, para sobrescribir/reemplazar solo las cadenas del tema padre que queremos, necesitamos cargar un archivo .mo personalizado para el dominio de texto del padre, que contenga solo esas cadenas traducidas, antes de que el tema padre cargue su archivo .mo.
Solución
Al final, simplemente creé una carpeta con el nombre del tema padre (solo por conveniencia) dentro de la carpeta de idiomas del tema hijo, y coloqué dentro mis archivos .mo personalizados para el dominio de texto del padre (uno por idioma, en la forma xx_XX.mo
, donde xx_XX
es el código de idioma).
Y luego añadí una línea en mi archivo functions.php
del tema hijo durante la acción after_setup_theme
, cerca de la que carga el archivo .mo para el dominio de texto de mi tema hijo:
add_action( 'after_setup_theme', function () {
// cargar archivo de traducción personalizado para el tema padre
load_theme_textdomain( 'parent-textdomain', get_stylesheet_directory() . '/languages/parent-theme' );
// cargar archivo de traducción para el tema hijo
load_child_theme_textdomain( 'my-child-theme', get_stylesheet_directory() . '/languages' );
} );
Debido a que el archivo functions.php
del tema hijo se carga antes que el del padre, este conjunto de cadenas tendrá precedencia sobre la traducción del tema padre (o también podría haber establecido la prioridad usando el tercer parámetro de la función add_action
).
Nota: Podría haber usado load_child_theme_textdomain
en lugar de load_theme_textdomain
, como se mencionó en la premisa hubiera sido lo mismo.

Puedes utilizar archivos de idioma que estén en la carpeta de tu tema hijo. Primero debes saber qué dominio de texto está utilizando el tema padre. Luego crea los archivos .po y .mo con solo tu idioma como nombre del archivo (por ejemplo, es_ES.po/es_ES.mo o es_MX.po/es_MX.mo) y colócalos en una carpeta dentro del directorio de tu tema hijo, por ejemplo "languages".
Luego puedes inicializar el dominio de texto con load_child_theme_textdomain()
:
load_child_theme_textdomain( 'el_dominio_de_texto', get_stylesheet_directory() . '/languages/' );
Ten en cuenta que puedes encontrar el dominio de texto buscando llamadas a funciones como __()
o _e()
dentro de los archivos PHP del tema padre. El segundo parámetro es el dominio de texto: __( 'Texto traducido', 'dominio_de_texto' );

gracias @redelschaap, al final tu solución funcionaría siempre y cuando uses una carpeta diferente para el textdomain padre de la que usas para el textdomain hijo: ¡ese era el truco! :)

Una actualización de 2019 para WordPress 5.0.1.
- Los archivos NO deben tener el slug del tema padre o hijo en ellos. Por ejemplo, al proporcionar una traducción al español mexicano, los archivos deben ser child-theme-name/languages/es_MX.po y /child-theme-name/languages/es_MX.mo
- El archivo functions.php del tema hijo debe tener el siguiente código. Observa que el primer parámetro de la función load_child_theme_textdomain() es el slug del tema PADRE, no el del hijo:
function child_theme_slug_setup() {
load_child_theme_textdomain( 'parent-theme-slug', get_stylesheet_directory() . '/languages' );
}
add_action( 'after_setup_theme', 'child_theme_slug_setup' );
