Wie lade ich parent_theme functions.php vor child_theme?

12

Ich habe das Problem, dass ich die functions.phpDatei meines übergeordneten Themas laden muss, bevor die Datei meines untergeordneten Themas geladen wird functions.php. Dies wird für das Setup & Init-Verfahren benötigt. Ich habe mir die Hooks in /wp_core_root/wp-settings.php (mit dem Namen :) angesehen do_action('setup_theme');.

Das Problem ist, dass ich nicht weiß, wie ich mich dort einhängen soll, weil die erste Datei, die ich bekomme, die des untergeordneten Themas ist functions.php, also wird keine add_action( 'setup_theme', 'my_init_function' );funktionieren.

Bearbeiten:
a) Ich weiß, dass Plugins früher als das Thema geladen werden und daher auch auf die anfängliche Abfrage zugreifen können, aber ich möchte mich nicht auf ein Plugin verlassen.
b) Hier ist der Code (gekürzt) aus der Datei 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' );

Ich möchte zwei Dinge vermeiden: Erstens viele Erklärungen für Benutzer. Zweitens die Möglichkeit, dass jemand etwas bricht, wenn das Seil durch versehentliches Löschen des Init-Verfahrens der Eltern durchtrennt. Die Leute sollen einfach in der functions.php spielen, ohne das Risiko einzugehen, etwas zu zerbrechen, ohne es zu wissen.

Mit anderen Worten: Wie halte ich die Datei "functions.php" meiner untergeordneten Themen sauber, aber habe ich den Bootstrap der übergeordneten Themen durchgeführt?

Irgendwelche Ideen? Danke vielmals!

Kaiser
quelle
Kannst du es nicht einfach einschließen?
Wyrfel
Meine Frage ist: von wo? Die erste Datei, die im Themenkontext geladen wird, ist die des untergeordneten Themas functions.php. Schauen Sie sich die "molto loko" wp-settings.php-Datei im Kern an (Zeile: 275-279 @wp 3.1 rc) ... sieht so aus : if ( TEMPLATEPATH !== STYLESHEETPATH && file_exists( STYLESHEETPATH . '/functions.php' ) ) include( STYLESHEETPATH . '/functions.php' ); if ( file_exists( TEMPLATEPATH . '/functions.php' ) ) include( TEMPLATEPATH . '/functions.php' );, also sehe ich keine Chance ... Und ich möchte sie nicht nutzen ein Plugin zum Bootstrap meines Themas.
Kaiser
Ich könnte hier etwas völlig vermissen, aber wenn Sie include(/path/to/parent/themes/functions.php)oben in Ihre untergeordneten Themen functions.php einfügen , wird alles dort vorher geladen. Nicht?
Wyrfel
@wyrfel: Ich habe das Q aktualisiert, um es klarer zu machen
Kaiser
Ich sehe, danke, es ist jetzt viel klarer. Außerdem habe ich angenommen, dass Sie dies nur für eine einzelne Installation tun.
Wyrfel

Antworten:

11

Justin Tadlock hat kürzlich einen großartigen Beitrag über das Erstellen einer besseren Datei functions.php geschrieben,
in dem er sich (wenn ich mich richtig erinnere) genau mit diesem Problem befasst.

Leider ist seine Seite momentan nicht verfügbar, so dass ich mich vorerst auf mein Gedächtnis verlassen muss.

Mit dem after_setup_themeHaken sind Sie auf dem richtigen Weg .

  1. Soweit ich mich erinnere, besteht der Trick darin, Ihre Filter und Aktionen in seine Funktion einzubinden.
    Siehe Beispiel unten.
  2. Sie tun dies sowohl in übergeordneten als auch in untergeordneten functions.phpDateien.
  3. Dann können Sie mit der Priorität dieser beiden Haken spielen.

Ein bisschen Code mit mehr als tausend Wörtern - das übergeordnete Thema function.phpsollte folgendermaßen aussehen:

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
quelle
Ähm, danke für das Schreiben (+1). Du hast ein beeindruckendes Gehirn;). Das Problem ist, dass after_setup_themees zu spät ist, weil die functions.php-Dateien bereits geladen wurden.
Kaiser
BEARBEITEN: Nachdem Sie Ihren Code überarbeitet und "Mach das sowohl in übergeordneten als auch in untergeordneten Funktionen.php" und "mit der Priorität spielen" gelesen haben, macht es Sinn. Immer noch auf der Suche nach einer besseren Lösung, die der Benutzer nicht so einfach brechen kann, aber es macht Sinn! Vielen Dank!
Kaiser
Hier gibt es keine wirkliche Lösung, also markiere ich dies, da du der erste warst, der dies vorschlug.
Kaiser
9

Erstens kannst du nicht. Die functions.php des untergeordneten Themas wird immer zuerst geladen, Punkt.

Zweitens können Themen nicht mit setup_theme verknüpft werden. Plugins können, aber das erste, woran sich ein Thema anschließen kann, ist after_setup_theme.

Wenn Ihr Elternteil richtig entworfen ist, kann das Kind Funktionen und Inhalte im Elternteil überschreiben, jedoch nur, wenn es zuerst geladen wird.

Wenn Sie der Meinung sind, dass Sie zuerst die Funktionsdatei der Eltern laden müssen, machen Sie das wahrscheinlich irgendwie falsch. Sie müssen das größere Problem erklären.

Otto
quelle
Danke für deine Antwort. Ich verstehe die Notwendigkeit, Plugins vor Themes zu laden, und habe dies bereits erkannt (siehe oben: "Und ich möchte kein Plugin verwenden, um mein Theme zu booten."). Um meinen Fall zu erläutern: Ich habe eine INI-Datei erhalten, die sich um das Laden aller meiner Framework-Teile kümmert. Diese beginnt in den übergeordneten Themenfunktionen PHP, wobei die Datei benötigt und die Init-Klasse geladen wird. InitClass kümmert sich darum, a) und ein Array von Daten aus INI-Dateien für untergeordnete Themen zu laden und diese dann zur weiteren Verarbeitung in verschiedene Klassen zu verschieben, z. Meta-Boxen, benutzerdefinierte Beitragstypen usw.
Kaiser
Mein Problem ist, dass ich all dies aus der Datei functions.php meiner Eltern heraus initiieren muss, damit ein normaler Benutzer es nicht brechen kann, wenn er innerhalb des untergeordneten Themas herumspielt. Mein zweites Problem ist, dass nicht alle diese Klassen in der Datei functions.php des untergeordneten Themas verfügbar sind, sodass sie keinen Nutzen haben ... aber vielleicht habe ich hier einen großen Denkfehler . Irgendwelche Ideen oder Vorschläge, wie man es besser machen kann?
Kaiser
3
.... Ich denke, Sie müssen einfach die Tatsache akzeptieren, dass wenn ein Benutzer Dinge kaputt macht, das wirklich ihr Problem ist. Fazit: Es gibt keine Möglichkeit, die Datei functions.php des übergeordneten Themas zuerst zu laden und das untergeordnete Thema "sauber" zu lassen. Wenn Sie etwas im untergeordneten Thema benötigen, um ausgeführt zu werden, nachdem die Datei functions.php des übergeordneten Themas geladen wurde, fügen Sie es in eine Funktion ein, die mit after_setup_theme verknüpft ist. Dies wird ausgeführt, nachdem beide Funktionen.php-Dateien geladen wurden.
Otto
In Ordnung. Es ist kein so großes Problem. Ich bin nur interessiert, wenn es eine Möglichkeit gibt. Frage: Wofür hat ein "Framework, das es wert ist, gesalzen zu werden" nach der Init-Prozedur einen Hook und verwendet den after_setup_themeHook nicht einfach ? Nur um den Hook nicht zu "spammen" oder weil er eher "enterprisy" oder "kool" ist? Ich meine: Ist die "Best Practice" -Idee hinter themenspezifischen Parallel-Hooks "Leave Core Hooks für Plugins"? (So ​​gehe ich derzeit damit um.)
Kaiser
"Wenn du dazu gehst, kümmere dich nicht um eine zusätzliche Aktion. Haken Sie einfach bei after_setup_theme ein." In Ordnung. Vielen Dank. +1
Kaiser
4

Sie versuchen also, Code aus der Datei functions.php des Kindes auszuführen, aber nachdem das übergeordnete Thema geladen wurde. Einfach, verwenden Sie einfach eine benutzerdefinierte Aktion:

Am Ende von parent/functions.php:

do_action('parent_loaded');

In child/functions.php:

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

Alle übergeordneten Themen, die ihr Geld wert sind, tun dies auf diese Weise. Darüber hinaus gibt es mehrere andere Aktionen und Filter, die für das untergeordnete Thema verwendet werden können.

Scribu
quelle
Ich versuche so viele Anweisungen wie möglich zu vermeiden. Das ist einer der Gründe, warum ich von einer config.php-Datei im untergeordneten Themenordner gewechselt bin und jetzt stattdessen INI-Dateien verwende. In einem Satz: Ich versuche, mich von meiner alten / Ihrer Lösung zu lösen und so nah wie möglich an Kern und Kodex zurückzukehren. Mein Problem ist, dass ich keine einzelne Funktion aus dem untergeordneten Thema liefern kann, da in der Datei functions.php des untergeordneten Themas keine Klasse oder aus meinem Bootstrap verfügbar ist (es handelt sich nicht um benutzerdefinierte / Framework-Vorlagen-Tags).
Kaiser
Siehe aktualisierte Antwort.
Scribu
Ich habe auch das Q aktualisiert. Nachdem ich gelesen habe, dass 2/3 Antworten auf dieselbe Quelle verweisen (thematisch, vor Ihrer Bearbeitung), habe ich das Gefühl, dass es nur die "Justin Tadlock" -Methode zum Einbeziehen gibt, aber ich möchte sicher gehen.
Kaiser
2
Wenn Sie dazu gehen, kümmern Sie sich nicht um eine zusätzliche Aktion. Einfach an after_setup_theme anschließen.
Otto
0

Warum fügen Sie die functions.phpDatei des übergeordneten Themas nicht wie folgt in die Datei des untergeordneten Themas ein functions.php:

In der functions.phpDatei des untergeordneten Themas :

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

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

Auf diese Weise wird die functions.phpDatei des übergeordneten Themas nicht geändert (manchmal ist dies wichtig).

Anh Tran
quelle
wie im F erwähnt: "Mit anderen Worten: Wie halte ich meine untergeordnete Themes functions.php-Datei sauber, aber habe ich den Bootstrap der übergeordneten Themes durchgeführt?" Noch besser: Wie vermeide ich einen Aufruf aus einer Datei functions.php? Warum: Leute sind es gewohnt, einfach jeden Mist zu zerschlagen, den sie nicht in Vorlagendateien haben wollen. Es besteht also eine hohe Wahrscheinlichkeit, dass jemand versehentlich einige Zeilen löscht. Meine Erfahrung: Niemand liest wirklich Kommentare, Readme oder Dokumentation.
Kaiser
0

Ich hatte zuvor ein ähnliches Problem und behebe es, indem ich eine zusätzliche leere "child-functions.php" im übergeordneten Element erstelle und direkt nach den Dateien / Funktionen, die ich im untergeordneten Element verwenden möchte, in "functions.php" (auch übergeordnetes Element) einfüge. dann erstelle ich im untergeordneten Thema eine "child-functions.php" -Datei und dort kann ich beginnen, die untergeordnete Funktion zu simulieren. Die Ausführung nach dem übergeordneten Element ist keine elegante Lösung, hat aber die Arbeit erledigt.

Softmixt
quelle