Comment charger parent_theme functions.php avant child_theme?

12

J'ai le problème que je dois charger le functions.phpfichier de mon thème parent avant le chargement du fichier de mon thème enfant functions.php. Cela est nécessaire pour la procédure de configuration et d'initialisation. J'ai regardé les crochets à l'intérieur de /wp_core_root/wp-settings.php (nommé:) do_action('setup_theme');.

Le problème est que je ne sais pas comment s'y connecter, car le premier fichier que je reçois est celui du thème enfant functions.php, donc ça ne add_action( 'setup_theme', 'my_init_function' );marchera pas.

Edit:
a) Je sais que les plugins se chargent plus tôt que le thème et peuvent donc accéder même à la requête initiale, mais je ne veux pas compter sur un plugin.
b) Voici le code (raccourci) du fichier 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' );

Je veux éviter deux choses: d'abord beaucoup d'explications aux utilisateurs. Deuxièmement, la chance que quelqu'un casse quoi que ce soit si la corde coupe en supprimant accidentellement la procédure d'initiation des parents. Les gens doivent simplement jouer à l'intérieur du functions.php sans risquer de casser quoi que ce soit sans le savoir.

En d'autres termes: comment garder mon fichier de thèmes enfants functions.php propre, mais le bootstrap des thèmes parents est-il fait?

Des idées? Merci beaucoup!

kaiser
la source
Ne pouvez-vous pas simplement l'inclure?
wyrfel
Ma question est: d'où? Le premier fichier qui est chargé dans le contexte du thème est celui du thème enfant functions.php. Jetez un oeil au wp-settings.phpfichier "molto loko" dans le noyau (ligne: 275-279 @wp 3.1 rc) ... ressemble à ceci:, if ( TEMPLATEPATH !== STYLESHEETPATH && file_exists( STYLESHEETPATH . '/functions.php' ) ) include( STYLESHEETPATH . '/functions.php' ); if ( file_exists( TEMPLATEPATH . '/functions.php' ) ) include( TEMPLATEPATH . '/functions.php' );donc je ne vois aucune chance ... Et je ne veux pas utiliser un plugin pour bootstrap mon thème.
kaiser
Il se peut que je manque totalement quelque chose ici, mais si vous insérez include(/path/to/parent/themes/functions.php)en haut de votre thème enfant functions.php, alors tout y est chargé avant. Ne pas?
wyrfel
@wyrfel: j'ai mis à jour le Q pour le rendre plus clair
kaiser
Je vois, merci, c'est beaucoup plus clair maintenant. De plus, je supposais que vous faisiez cela pour une seule installation.
wyrfel

Réponses:

11

Justin Tadlock a récemment écrit un excellent article sur la création d'un meilleur fichier functions.php
où (si je me souviens bien), il traite de ce problème exact.

Malheureusement, son site est en panne pour le moment, je dois donc compter sur ma mémoire pour l'instant.

Vous êtes sur la bonne voie avec le after_setup_themecrochet.

  1. Pour autant que je me souvienne, l'astuce consiste à envelopper vos filtres et vos actions dans sa fonction.
    Voir l'exemple ci-dessous.
  2. Vous faites cela dans lesfunctions.php fichiers parents et enfants .
  3. Ensuite, vous pouvez jouer avec la priorité de ces deux crochets.

Un peu de code valant mille mots - le thème de votre parent function.phpdevrait ressembler à ceci:

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
la source
Ehm, merci pour l'écriture (+1). Vous avez un cerveau impressionnant;). Le problème est qu'il after_setup_themeest trop tard, car les fichiers functions.php étaient déjà chargés.
kaiser
EDIT: Après avoir repensé votre code et lu "faites cela dans les fonctions parent et enfant. Php" et "jouer avec la priorité", cela commence à avoir un sens. Toujours à la recherche d'une meilleure solution que l'utilisateur ne peut pas casser aussi facilement, mais cela a du sens! Merci!
kaiser
Pas de vraie solution ici, donc je coche ceci, car vous avez été le premier à proposer cela.
kaiser
9

Premièrement, vous ne pouvez pas. Le thème enfant functions.php se charge toujours en premier, point.

Deuxièmement, les thèmes ne peuvent pas s'accrocher à setup_theme. Les plugins le peuvent, mais la première chose à laquelle un thème peut s'accrocher est after_setup_theme.

Si votre parent est conçu correctement, l'enfant est capable de remplacer les fonctions et les éléments du parent, mais uniquement lors du premier chargement.

D'une manière générale, si vous pensez que vous devez d'abord charger le fichier de fonctions du parent, vous vous trompez probablement, d'une manière ou d'une autre. Vous devez expliquer le problème plus large.

Otto
la source
Merci pour votre réponse. Je comprends la nécessité de charger des plugins avant les thèmes et je l'ai déjà réalisé (lire ci-dessus: "Et je ne veux pas utiliser de plugin pour démarrer mon thème."). Pour élaborer mon cas: j'ai obtenu un fichier ini qui se soucie de charger toutes mes parties de framework, qui commence dans les fonctions des thèmes parents php avec la nécessité du fichier et le chargement de la classe init. InitClass se soucie de charger a) et un tableau de données à partir de fichiers .ini de thèmes enfants, puis les pousse dans différentes classes pour un traitement ultérieur, par exemple. méta-boîtes, types de messages personnalisés, etc.
kaiser
Mon problème est que je dois initier tout cela à partir du fichier functions.php de mes parents, donc un utilisateur normal ne peut pas le casser, lorsqu'il joue à l'intérieur du thème enfant. Mon deuxième problème est que toutes ces classes ne sont pas disponibles dans le fichier functions.php du thème enfant, donc elles ne sont d'aucune utilité ... mais j'ai peut-être une grosse erreur de réflexion ici. Des idées ou des suggestions sur la façon de l'améliorer?
kaiser
3
... Je pense que vous allez devoir accepter le fait que si un utilisateur casse des choses, alors c'est vraiment son problème. Bottom line: Il n'y a aucun moyen de charger en premier les fonctions du thème parent.php et de laisser le thème enfant "propre". Si vous avez besoin que quelque chose dans le thème enfant s'exécute après le chargement du fichier functions.php du thème parent, vous le placez dans une fonction liée à after_setup_theme. Cela s'exécute après le chargement des deux fichiers functions.php.
Otto
D'accord. Ce n'est pas un gros problème. Je suis simplement intéressé s'il y a une possibilité. Question: Pourquoi un "framework qui vaut son sel" a-t-il un hook après la procédure init et n'utilise pas simplement le after_setup_themehook? Juste pour ne pas "spammer" le crochet, ou parce que c'est plus "entreprenant" ou "kool" euh? Je veux dire: est-ce que l'idée de "meilleure pratique" derrière les crochets parallèles spécifiques au thème "laisse les crochets de base pour les plugins"? (C'est comme ça que je le gère actuellement.)
kaiser
"Si vous allez à cela, ne vous embêtez pas avec une action supplémentaire. Accrochez-vous simplement à after_setup_theme." D'accord. Merci. +1
kaiser
4

Vous essayez donc d'exécuter du code à partir du fichier functions.php de l'enfant, mais après le chargement du thème parent. Simple, utilisez simplement une action personnalisée:

À la fin de parent/functions.php:

do_action('parent_loaded');

Dans child/functions.php:

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

Tous les thèmes parent qui valent leur sel le font de cette façon. De plus, ils ont plusieurs autres actions et filtres pour le thème enfant à utiliser.

scribu
la source
J'essaie d'éviter autant d'instructions que possible. C'est l'une des raisons pour lesquelles je suis passé d'un fichier config.php dans le dossier de thème enfant et utilise désormais des fichiers ini à la place. En une phrase: j'essaie de m'éloigner de mon ancienne / de votre solution et de me rapprocher le plus possible du core et du codex. Mon problème est que je ne peux pas fournir une seule fonction à partir du thème enfant, car aucune classe ou bien à partir de mon bootstrap n'est disponible dans le fichier children themes functions.php (sans parler des balises de modèle personnalisées / de framework).
kaiser
Voir la réponse mise à jour.
scribu
J'ai aussi mis à jour le Q. Après avoir lu que 2/3 des réponses m'indiquent la même source (thématique, avant votre montage), j'ai l'impression qu'il n'y a que la méthode "justin tadlock" d'inclure, mais je veux être sûr.
kaiser
2
Si vous allez à cela, ne vous embêtez pas avec une action supplémentaire. Accrochez-vous simplement à after_setup_theme.
Otto
0

Pourquoi ne pas inclure le functions.phpfichier du thème parent dans le fichier du thème enfant functions.php, comme ceci:

Dans le functions.phpfichier du thème enfant :

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

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

De cette façon, le functions.phpfichier du thème parent n'est pas modifié (parfois c'est important).

Anh Tran
la source
comme mentionné dans le Q: "En d'autres termes: comment garder mon fichier de thèmes enfants functions.php propre, mais faire amorcer les thèmes parents?" Encore mieux: comment éviter un appel depuis n'importe quel fichier functions.php? Pourquoi: Les gens ont l'habitude de casser toutes les conneries qu'ils ne veulent pas avoir dans les fichiers de modèle. Il y a donc de fortes chances que quelqu'un supprime accidentellement certaines lignes. Mon expérience: personne ne lit vraiment les commentaires, le fichier lisez-moi ou la documentation.
kaiser
0

J'ai eu un problème similaire auparavant et je le corrige en créant un "child-functions.php" supplémentaire vide dans le parent et en l'incluant dans "functions.php" (le parent aussi) juste après les fichiers / fonctions que je veux utiliser chez l'enfant, puis dans le thème enfant, je crée un fichier "child-functions.php" et c'est là que je peux commencer à simuler l'enfant functions.php exécuté après que le parent n'est pas une solution élégante mais a fait le travail.

Softmixt
la source