¿Cómo cargar parent_theme functions.php antes de child_theme?

12

Tengo el problema de que tengo que cargar el functions.phparchivo de mi tema principal antes de que se cargue el archivo de mi tema secundario functions.php. Esto es necesario para el procedimiento de configuración e inicio. Miré los ganchos dentro de /wp_core_root/wp-settings.php (named:) do_action('setup_theme');.

El problema es que no sé cómo conectarme allí, porque el primer archivo que obtengo es el tema secundario functions.php, por lo que no add_action( 'setup_theme', 'my_init_function' );funcionará.

Editar:
a) Sé que los complementos se cargan antes que el tema y, por lo tanto, pueden acceder incluso a la consulta inicial, pero no quiero confiar en un complemento.
b) Aquí está el código (acortado) del archivo wp-settings.php

// happens a lot earlier:  
do_action( 'plugins_loaded' );

// localize stuff happening here
    do_action( 'setup_theme' );

        // Load the functions for the active theme, for both parent and child theme if applicable.
        if ( TEMPLATEPATH !== STYLESHEETPATH && file_exists( STYLESHEETPATH . '/functions.php' ) )
            include( STYLESHEETPATH . '/functions.php' );
        if ( file_exists( TEMPLATEPATH . '/functions.php' ) )
            include( TEMPLATEPATH . '/functions.php' );
    // first available hook, *after* functions.php was loaded
    do_action( 'after_setup_theme' );

Quiero evitar dos cosas: primero mucha explicación para los usuarios. En segundo lugar, la posibilidad de que alguien rompa algo si corta la cuerda al eliminar accidentalmente el procedimiento de inicio de los padres. La gente simplemente jugará dentro de functions.php sin arriesgarse a romper nada sin saberlo.

En otras palabras: ¿cómo mantengo limpio mi archivo de funciones de temas infantiles.php, pero tengo el arranque de los temas principales?

¿Algunas ideas? ¡Muchas gracias!

emperador
fuente
¿No puedes incluirlo?
wyrfel
Mi pregunta es: ¿de dónde? El primer archivo que se interponen en el contexto cargado tema es el tema de niño functions.php. Eche un vistazo al wp-settings.phparchivo "molto loko" en el núcleo (línea: 275-279 @wp 3.1 rc) ... se ve así: if ( TEMPLATEPATH !== STYLESHEETPATH && file_exists( STYLESHEETPATH . '/functions.php' ) ) include( STYLESHEETPATH . '/functions.php' ); if ( file_exists( TEMPLATEPATH . '/functions.php' ) ) include( TEMPLATEPATH . '/functions.php' );así que no puedo ver una oportunidad ... Y no quiero usar un complemento para arrancar mi tema.
Kaiser
Es posible que me falte algo aquí, pero si inserta include(/path/to/parent/themes/functions.php)en la parte superior de los temas de su hijo functions.php, entonces todo lo que está allí se carga antes. ¿No?
wyrfel
@wyrfel: actualicé la Q para hacerlo más claro
kaiser
Ya veo, gracias, ahora está mucho más claro. Además, supuse que estabas haciendo esto para una sola instalación.
wyrfel

Respuestas:

11

Justin Tadlock recientemente escribió una gran publicación sobre cómo hacer un mejor archivo functions.php
donde (si no recuerdo mal) se ocupa de este problema exacto.

Lamentablemente, su sitio no funciona en este momento, así que tengo que confiar en mi memoria por ahora.

Estás en el camino correcto con el after_setup_themegancho.

  1. Hasta donde recuerdo, el truco es envolver sus filtros y acciones en su función.
    Ver ejemplo a continuación.
  2. Lo haces en losfunctions.php archivos primarios y secundarios .
  3. Entonces puedes jugar con la prioridad de estos dos ganchos.

Un poco de código que vale más que mil palabras: el tema principal function.phpdebería verse así:

add_action( 'after_setup_theme', 'your_parent_theme_setup', 9 );
function your_parent_theme_setup() {    
    add_action(admin_init, your_admin_init);
    add_filter(the_content, your_content_filter);
}

function your_admin_init () {
...
}

function your_content_filter() {
...
}
Michal Mau
fuente
Ehm, gracias por la redacción (+1). Tienes un cerebro impresionante;). El problema es que after_setup_themees demasiado tarde, porque los archivos functions.php ya estaban cargados.
kaiser
EDITAR: Después de repensar su código y leer "hacer eso en las funciones padre e hijo.php" y "jugar con la prioridad", comienza a tener sentido. Todavía estoy buscando una solución mejor que el usuario no pueda romper tan fácilmente, ¡pero tiene sentido! ¡Gracias!
kaiser
No hay una solución real aquí, así que marque esto, ya que usted fue el primero en proponer esto.
kaiser
9

En primer lugar, no puedes. El archivo child functions.php siempre se carga primero, punto.

En segundo lugar, los temas no se pueden conectar a setup_theme. Los complementos pueden, pero lo primero a lo que se puede conectar un tema es after_setup_theme.

Si su padre está diseñado correctamente, entonces el niño es capaz de anular funciones y cosas en el padre, pero solo cuando se carga primero.

En términos generales, si cree que necesita cargar primero el archivo de funciones de los padres, entonces probablemente lo esté haciendo mal, de alguna manera. Necesitas explicar el problema más grande.

Otón
fuente
Gracias por tu respuesta. Entiendo la necesidad de cargar complementos antes de los temas y ya me di cuenta del hecho (lea más arriba: "Y no quiero usar un complemento para arrancar mi tema"). Para elaborar mi caso: obtuve un archivo ini que se preocupa por cargar todas mis partes del marco, que comienza en las funciones de temas principales php con la solicitud del archivo y la carga de la clase init. InitClass se preocupa por cargar a) y la matriz de datos de los archivos secundarios .ini-files y luego lo empuja a diferentes clases para su posterior procesamiento, por ejemplo. meta cuadros, tipos de publicaciones personalizadas, etc.
kaiser
Mi problema es que tengo que iniciar todo esto desde el archivo functions.php de mis padres, para que un usuario normal no pueda romperlo, al jugar dentro del tema secundario. Mi segundo problema es que todas esas clases no están disponibles dentro del archivo functions.php del tema secundario, por lo que no sirven de nada ... pero tal vez obtuve un gran error de pensamiento aquí. ¿Alguna idea o sugerencia sobre cómo mejorarlo?
kaiser
3
.... Creo que vas a tener que aceptar el hecho de que si un usuario rompe cosas, entonces ese es realmente su problema. En pocas palabras : no hay forma de cargar primero las funciones del tema principal .php y dejar el tema secundario "limpio". Si necesita que algo en el tema secundario se ejecute después de que se haya cargado el archivo functions.php del tema principal, póngalo dentro de una función enganchada a after_setup_theme. Eso se ejecuta después de que se carguen ambos archivos functions.php.
Otto
Okay. No es ese gran problema. Solo estoy interesado si hay una posibilidad. Pregunta: ¿Para qué sirve un "marco que vale la pena" luego tiene un gancho después del procedimiento de inicio y no simplemente usa el after_setup_themegancho? ¿Simplemente para no "enviar spam" al gancho, o porque es más "emprendedor" o "kool" er? Quiero decir: ¿la idea de "mejor práctica" detrás de los ganchos paralelos específicos del tema "deja los ganchos centrales para los complementos"? (Así es como lo manejo actualmente.)
Kaiser
"Si vas a hacer eso, no te molestes con una acción extra. Simplemente engancha a after_setup_theme". Okay. Gracias. +1
kaiser
4

Entonces está tratando de ejecutar código desde las funciones del niño.php, pero después de que se haya cargado el tema principal. Simple, solo use una acción personalizada:

Al final de parent/functions.php:

do_action('parent_loaded');

En child/functions.php:

function parent_loaded() {
    // do init stuff
}
add_action('parent_loaded', 'parent_loaded');

Todos los temas para padres que valen la pena lo hacen de esta manera. Además, tienen varias otras acciones y filtros esparcidos para que el tema secundario los use.

scribu
fuente
Intento evitar tantas instrucciones como sea posible. Esa es una de las razones por las que cambié de un archivo config.php en la carpeta de temas secundarios y ahora uso archivos ini. En una oración: trato de alejarme de mi solución anterior / suya y acercarme lo más posible al núcleo y al códice. Mi problema es que no puedo entregar una sola función desde el tema secundario, porque no hay disponible ninguna clase ni desde mi bootstrap dentro del archivo de funciones secundarias de los temas secundarios (sin hablar de etiquetas de plantilla personalizadas / marco).
Kaiser
Ver respuesta actualizada.
scribu
También actualicé la Q. Después de leer que las respuestas de 2/3 me señalan a la misma fuente (temática, antes de su edición) tengo la sensación de que solo hay que incluir el método "justin tadlock", pero quiero asegurarme.
Kaiser
2
Si vas a hacer eso, no te molestes con una acción extra. Solo conéctese a after_setup_theme.
Otto
0

¿Por qué no incluye el functions.phparchivo del tema principal en el archivo del tema secundario functions.php, así:

En el functions.phparchivo del tema hijo :

if ( TEMPLATEPATH !== STYLESHEETPATH && file_exists( TEMPLATEPATH . '/functions.php' ) )
            include( TEMPLATEPATH . '/functions.php' );

// code of child theme's functions.php file continues here

De esta manera, el functions.phparchivo del tema principal no cambia (a veces esto es importante).

Anh Tran
fuente
como se menciona en la P: "En otras palabras: ¿Cómo mantengo limpio mi archivo de funciones infantiles. Aún mejor: ¿cómo evito una llamada desde cualquier archivo functions.php? Por qué: las personas están acostumbradas a romper cada basura que no quieren tener en los archivos de plantilla allí. Por lo tanto, existe una alta probabilidad de que alguien elimine accidentalmente algunas líneas. Mi experiencia: nadie realmente lee comentarios, léame o documentación.
Kaiser
0

Tuve un problema similar antes y lo solucioné creando un "child-functions.php" vacío adicional en parent e incluyéndolo en "functions.php" (parent también) justo después de los archivos / funciones que quiero usar en child, luego, en el tema hijo, creo un archivo "child-functions.php" y allí es donde puedo comenzar a simular las funciones child.php ejecutadas después de parent no es una solución elegante, pero hizo el trabajo.

Softmixt
fuente