Versionierung @import von style.css des übergeordneten Themas

28

Kontext

Ich habe ein Kinderthema basierend auf Twenty Thirteen erstellt, was sehr gut funktioniert. Nachdem ich das übergeordnete Thema auf Version 1.3 aktualisiert hatte, bemerkte ich ein merkwürdiges Verhalten mit dem Stil, das durch das zwischengespeicherte übergeordnete Thema verursacht wurde style.css.

Hier ist der Inhalt des Themas meines Kindes style.css(ohne Überschriften)

/* =Imports styles from the parent theme
-------------------------------------------------------------- */
@import url('../twentythirteen/style.css');

Das Kinderthema style.cssimportiert also nur das Elternthema style.css.

Ich habe auch eine andere CSS-Datei mit den Anpassungen meines Kinderthemas, die ich wie folgt einreihe functions.php:

// Enqueue parent theme's style.css (faster than using @import in our style.css)
$themeVersion = wp_get_theme()->get('Version');

// Enqueue child theme customizations
wp_enqueue_style('child_main', get_stylesheet_directory_uri() . '/css/main.css',
    null, $themeVersion);

Dies gibt mir eine sehr schöne CSS-URL domain.com/wp-content/themes/toutprettoutbon/css/main.css?ver=1.0.1, die sicherstellt, dass das Stylesheet neu geladen wird, wenn das untergeordnete Thema aktualisiert wird.

Nun das Problem

Die Anweisung @import url('../twentythirteen/style.css');ist völlig unabhängig von der Version des zugrunde liegenden übergeordneten Themas. Tatsächlich kann das übergeordnete Design aktualisiert werden, ohne dass das untergeordnete Design aktualisiert wird. Browser verwenden jedoch weiterhin zwischengespeicherte Versionen des alten Designs ../twentythirteen/style.css.

Relevanter Code in Dreizehnundzwanzig, der Folgendes in die Warteschlange stellt style.css:

function twentythirteen_scripts_styles() {
    // ...

    // Add Genericons font, used in the main stylesheet.
    wp_enqueue_style( 'genericons', get_template_directory_uri() . '/genericons/genericons.css', array(), '3.03' );

    // Loads our main stylesheet.
    wp_enqueue_style( 'twentythirteen-style', get_stylesheet_uri(), array(), '2013-07-18' );
    // Note usage of get_stylesheet_uri() which actually enqueues child-theme/style.css

    // Loads the Internet Explorer specific stylesheet.
    wp_enqueue_style( 'twentythirteen-ie', get_template_directory_uri() . '/css/ie.css', array( 'twentythirteen-style' ), '2013-07-18' );
}
add_action( 'wp_enqueue_scripts', 'twentythirteen_scripts_styles' );

Ich kann mir ein paar Möglichkeiten vorstellen, um dieses Problem zu lösen, aber keine ist wirklich zufriedenstellend:

  1. Aktualisieren Sie mein untergeordnetes Thema jedes Mal, wenn das übergeordnete Thema aktualisiert wird, um eine Versionszeichenfolge in style.css(z @import url('../twentythirteen/style.css?ver=NEW_VERSION');. B. ) zu ändern . Dies schafft eine unnötige und ärgerliche Verbindung zwischen der übergeordneten Designversion und dem untergeordneten Design.

  2. In meinem Kind functions.php1) wp_dequeue_styledas enthaltene Kind-Thema style.cssund 2) wp_enqueue_styledas Eltern- Thema style.cssdirekt mit Versionszeichenfolge. Dadurch wird die Reihenfolge der in die Warteschlange gestellten CSS-Dateien im übergeordneten Thema durcheinander gebracht.

  3. Verwenden Sie den style_loader_tagFilter, um das generierte CSS- <link>Tag für zu style.cssändern, und ändern Sie den Pfad so, dass er direkt auf die WITH-Versionszeichenfolge des übergeordneten Themas style.cssverweist. Scheint für solch ein allgemeines Bedürfnis eher undurchsichtig (Cache-Busting).

  4. Gib das Thema style.cssmeiner Eltern in das meines Kindes style.css. Wie (1), aber etwas schneller.

  5. style.cssLassen Sie das Thema meines Kindes ein Symlink zum Thema des Elternteils sein style.css. Das scheint ziemlich hackisch ...

Habe ich etwas verpasst Irgendwelche Vorschläge?

bearbeiten

Hinzugefügt genericicons.cssund ie.cssStylesheets im übergeordneten Thema, um zu verdeutlichen, warum ich die @importCSS-Anweisung wp_enqueue_stylein meinem untergeordneten Thema nicht ändern kann . Derzeit habe ich mit einer @importAussage in meinem Kinderthema style.cssdiese Reihenfolge in generierten Seiten:

  1. Dreizehnundzwanzig / genericons / genericons.css -> Eingereiht nach übergeordnetem Thema
  2. child-theme / style.css -> nach übergeordnetem Thema in die Warteschlange gestellt, @imports twentythirteen / style.css
  3. einundzwanzig / css / ie.css -> nach übergeordnetem Thema in die Warteschlange gestellt
  4. child-theme / css / main.css -> nach untergeordnetem Thema in die Warteschlange gestellt

Wenn ich die Eltern style.cssals Abhängigkeit von in die Warteschlange einreihe main.css, wird dies zu:

  1. Dreizehnundzwanzig / genericons / genericons.css -> Eingereiht nach übergeordnetem Thema
  2. child-theme / style.css -> leer, eingereiht nach übergeordnetem Thema
  3. einundzwanzig / css / ie.css -> nach übergeordnetem Thema in die Warteschlange gestellt
  4. twentythirteen / style.css -> nach untergeordnetem Thema als Abhängigkeit von main.css in die Warteschlange gestellt
  5. child-theme / css / main.css -> nach untergeordnetem Thema in die Warteschlange gestellt

Beachten Sie, dass ie.css jetzt vor dem übergeordneten Thema enthalten ist style.css. Ich möchte die Reihenfolge der Warteschlangen in den CSS-Dateien des übergeordneten Themas nicht ändern, da ich nicht davon ausgehen kann, dass dies keine Probleme mit der Priorität der CSS-Regeln verursacht.

Bernie
quelle
5
Niemals verwenden @import, stattdessen das Stylesheet des übergeordneten Themas als Abhängigkeit von Ihrem eigenen Stylesheet festlegen .
Fuxia
Ich weiß, es ist nicht der beste Ansatz, aber er wird hier empfohlen: codex.wordpress.org/Child_Themes
bernie
Auch das, was Sie vorgeschlagen haben, behebt mein Problem nicht. Das übergeordnete Thema wird style.cssnicht an der Stelle eingefügt, an der es sich gerade befindet. Das übergeordnete Element enthält andere CSS-Dateien, die zwischen style.cssdem zugehörigen CSS und dem CSS meines untergeordneten Themas liegen müssen.
Bernie
3
Bitte ignorieren Sie den Codex vollständig. Es ist voller Fehlinformationen. Die Verwendung des Abhängigkeitsparameters schließt die Stylesheets in der richtigen Reihenfolge ein.
fuxia
Bitte sehen Sie meine Bearbeitung.
Bernie

Antworten:

19

Sie müssen @import nicht verwenden. Eigentlich ist es das Beste, das nicht zu tun. Die Verwendung eines Ansatzes in Warteschlangen ist wahrscheinlich überall besser.

Hier ist der relevante Teil des dreizehnundzwanzigsten Codes:

function twentythirteen_scripts_styles() {
...
    // Loads our main stylesheet.
    wp_enqueue_style( 'twentythirteen-style', get_stylesheet_uri(), array(), '2013-07-18' );
...
}
add_action( 'wp_enqueue_scripts', 'twentythirteen_scripts_styles' );

Folgendes tun Sie in Ihrem Code:

function child_scripts_styles() {
    wp_enqueue_style( 'child-style', get_stylesheet_directory_uri().'/css/main.css', array('twentythirteen-style'), 'YOUR_THEME_VERSION' );
}
add_action( 'wp_enqueue_scripts', 'child_scripts_styles' );

Wenn Ihre main.css nach der style.css der Eltern kommen muss, dann machen Sie es einfach davon abhängig.

Wenn Sie nun auch ein B.css im untergeordneten Element haben, richten Sie die Abhängigkeiten entsprechend ein:

function child_scripts_styles() {
    wp_enqueue_style( 'child-B-style', get_stylesheet_directory_uri().'/B.css', array('twentythirteen-style'), 'YOUR_THEME_VERSION' );
    wp_enqueue_style( 'child-style', get_stylesheet_directory_uri().'/css/main.css', array('child-B-style'), 'YOUR_THEME_VERSION' );
}
add_action( 'wp_enqueue_scripts', 'child_scripts_styles' );

Stellen Sie sicher, dass die Abhängigkeiten, die Sie für jedes Element definieren, die tatsächlichen Abhängigkeiten widerspiegeln. Wenn main.css nach B.css kommen muss, dann kommt es darauf an. Wenn B.css nach dem style.css der Eltern kommen muss, dann hängt B davon ab. Das Enqueue-System erledigt das für Sie.

Und wenn Sie die Datei style.css des Kindes nicht für irgendetwas verwenden, müssen Sie sie überhaupt nicht einreihen . Es kann nur ein Platzhalter für die Header-Informationen Ihres Themas sein. Verwenden Sie es nicht? Laden Sie es nicht.

Und was genau machst du, wenn du hier bestellst? In den meisten Situationen kümmert sich CSS nicht um die Ladereihenfolge. CSS hängt mehr von der Spezifität der Selektoren ab. Wenn Sie etwas außer Kraft setzen möchten, müssen Sie Ihre Auswahl spezifischer machen. Es kann zuerst oder zuletzt oder irgendetwas dazwischen kommen, der spezifischere Selektor gewinnt immer.

Bearbeiten

Wenn ich Ihre Kommentare lese und den Code genauer betrachte, sehe ich, wo der Fehler liegt. Der dreizehnundzwanzigste Code reiht das "get_stylesheet_uri ()" in eine Warteschlange, das in einem untergeordneten Themenfall die style.css-Datei Ihres untergeordneten Themas ist und nicht die Datei des übergeordneten Themas. Aus diesem Grund funktioniert der @import und behält die gleiche Reihenfolge bei (was wiederum nicht annähernd so wichtig ist, wie Sie denken).

In diesem Fall würde ich empfehlen, die Datei style.css des übergeordneten Elements direkt in die Warteschlange zu stellen, wenn Sie den Import nicht verwenden möchten. Wie so:

function child_scripts_styles() {
    wp_enqueue_style( 'parent-style', get_template_directory_uri().'/style.css', array() );
}
add_action( 'wp_enqueue_scripts', 'child_scripts_styles' );

Code in der Datei functions.php des untergeordneten Themas wird zuerst ausgeführt, sodass Ihre eigenen wp_enqueue_scripts zuerst ausgeführt werden. Dadurch wird die Datei style.css des übergeordneten Themas in eine Warteschlange gestellt, die das übergeordnete Thema nicht selbst ausführt (da die Datei style.css Ihres untergeordneten Themas tatsächlich in eine Warteschlange gestellt wird). Indem es nicht von etwas abhängig gemacht wird, das dem übergeordneten Element entspricht, wird es einfach korrekt in die Ausgabe eingefügt. Beachten Sie, dass die Reihenfolge dieser Datei und der genericons.css keine Rolle spielt, da die genericons.css im ursprünglichen Stil "13" nicht als aufgelistete Abhängigkeit vorhanden ist.

Style.css Ihres eigenen Kindes wird geladen, und ehrlich gesagt, hier sollten Sie Ihre Änderungen für das untergeordnete Thema ablegen, nicht in einer separaten main.css. Nichts hindert Sie daran, Ihre Änderungen dort abzulegen, aber es gibt keinen wirklichen Grund, eine zusätzliche CSS-Datei zu haben.

Otto
quelle
Ich stimme vollkommen zu, dass @imports nicht der beste Weg ist. Weitere Informationen finden Sie in meinem Abschnitt "Bearbeiten". Ich habe keine besonderen Bedürfnisse in Bezug auf die Bestellung von CSS. Ich möchte einfach nicht die interne Reihenfolge der CSS-Dateien des übergeordneten Themas ändern, was Probleme mit der Priorität der CSS-Regeln verursachen kann.
Bernie
Zur Verdeutlichung ist B.css (jetzt in "ie.css" geändert) nicht Teil meines untergeordneten Themas, sondern Teil des übergeordneten Themas.
Bernie
2
Wenn Sie möchten, dass Ihr Stil dem ie.css-Stil folgt, können Sie Ihren eigenen Stil davon abhängig machen. Sein Name ist "13-ie". Die Reihenfolge wird vollständig durch die von Ihnen deklarierten Abhängigkeiten gesteuert, aber auch bei CSS spielt die tatsächliche Reihenfolge der Abhängigkeiten im Dokument normalerweise keine Rolle. Ich bin mir also nicht sicher, warum Sie sich übermäßig darum kümmern sollten.
Otto
2
Bearbeitet meine Antwort, um einen anderen Ansatz einzuschließen.
Otto
Ja, ich glaube, ich habe das "Bedürfnis" mitgerissen, die CSS-Bestellung aufrechtzuerhalten. Wenn die Reihenfolge für das übergeordnete Thema wirklich wichtig war, sollte dies in den Abhängigkeiten angegeben werden.
Bernie
9

Meine vorherige Antwort ist zu kompliziert und berücksichtigt möglicherweise nicht die Abhängigkeitskette des übergeordneten Themas (siehe Hinweis in einer anderen Antwort).

Hier ist eine andere, viel einfachere Einstellung, die viel besser funktionieren sollte:

function use_parent_theme_stylesheet() {
    // Use the parent theme's stylesheet
    return get_template_directory_uri() . '/style.css';
}

function my_theme_styles() {
    $themeVersion = wp_get_theme()->get('Version');

    // Enqueue our style.css with our own version
    wp_enqueue_style('child-theme-style', get_stylesheet_directory_uri() . '/style.css',
        array(), $themeVersion);
}

// Filter get_stylesheet_uri() to return the parent theme's stylesheet 
add_filter('stylesheet_uri', 'use_parent_theme_stylesheet');

// Enqueue this theme's scripts and styles (after parent theme)
add_action('wp_enqueue_scripts', 'my_theme_styles', 20);

Die Idee ist, einfach den Aufruf get_stylesheet_uri()im übergeordneten Design zu filtern , um das eigene Stylesheet anstelle des untergeordneten Designs zurückzugeben. Das Stylesheet des untergeordneten Themas wird später im Aktions-Hook in die Warteschlange gestellt my_theme_styles.

Bernie
quelle
Nur zur Veranschaulichung: 1) Ihr Code generiert genau das gleiche HTML wie in der alten @importVersion, hat keinerlei Auswirkungen auf die Leistung. Es gibt zwei separate style.css-Anfragen an den Server. 2) Diese Antwort löscht die gesamte Abhängigkeitssache together ... 3) Hier können Sie überprüfen, was get_template_directory_uriund was Sie get_template_stylesheet_uritun: core.trac.wordpress.org/browser/tags/4.8/src/wp-includes/… Auch hier ist der größte Teil dieses Codes nicht erforderlich.
BG17AW
1
@ bg17aw using wp_enqueue_stylefügt der generierten URL automatisch eine Cache-Busting- Abfragezeichenfolge hinzu (z. B. ?ver=2013-07-18), die auf der Version des Themas basiert. Dies erfolgt nicht durch eine @importAussage.
Bernie
2

Warnung

Diese Lösung berücksichtigt nicht die Abhängigkeiten des übergeordneten Themas ! Das Ändern des Handle-Namens des übergeordneten Themas wirkt sich auf die im übergeordneten Thema festgelegte Abhängigkeitskette aus. Siehe meine viel einfachere andere Antwort .

orignal Antwort

Obwohl Ottos Antwort ziemlich gut ist, landete ich damit in den Funktionen meines Kinderthemas

function my_theme_styles() {
    global $wp_styles;
    $parentOriginalHandle = 'twentythirteen-style';
    $parentNewHandle = 'parent-style';

    // Deregister our style.css which was enqueued by the parent theme; we want
    // to control the versioning ourself.
    $parentStyleVersion = $wp_styles->registered[$parentOriginalHandle]->ver;
    $parentDeps = $wp_styles->registered[$parentOriginalHandle]->deps;
    wp_deregister_style($parentOriginalHandle);

    // Enqueue the parent theme's style.css with whatever version it used instead
    // of @import-ing it in the child theme's style.css
    wp_register_style($parentNewHandle, get_template_directory_uri() . '/style.css',
        $parentDeps, $parentStyleVersion);

    // Enqueue our style.css with our own version
    $themeVersion = wp_get_theme()->get('Version');
    wp_enqueue_style($parentOriginalHandle, get_stylesheet_directory_uri() . '/style.css',
        [$parentNewHandle], $themeVersion);
}

// Run this action action the parent theme has enqueued its styles.
add_action('wp_enqueue_scripts', 'my_theme_styles', 20);

Die style.cssReihenfolge und Versionsnummern des übergeordneten Themas werden beibehalten, während die Version des untergeordneten Themas gesteuert wird style.css.

Bernie
quelle
5
Es verwirrt mich, dass die beliebteste Blog-Software mehr als 20 Codezeilen benötigt, um das CSS eines vorhandenen Themas zu optimieren. Ich denke, das ist Arbeitsplatzsicherheit.
Carl G
Ich musste umsteigen [$parentNewHandle]zuarray($parentNewHandle)
Carl G
@CarlG: Die verwendete Array-Syntax (Klammern) wurde in PHP 5.4 eingeführt.
Bernie
An die Wähler: Bitte sehen Sie sich meine andere Antwort an, die Probleme mit dieser löst.
Bernie
Es ist alles ein großes Missverständnis, es besteht keine Notwendigkeit für irgendetwas davon. Tatsächlich @importfunktioniert die alte Methode genauso gut. Bitte vergleichen Sie beide Methoden. Auch dies ist für die Abhängigkeit des untergeordneten Themas vom übergeordneten Thema nicht erforderlich. Das Kind style.csswird immer nach dem Elternteil geladen, zumindest aus meinen Tests. Liebe es, sich als falsch zu erweisen.
BG17AW