Probleme cu încărcarea fișierelor CSS în temele părinte și copil folosind metoda revizuită din Codex
Acest articol abordează câteva probleme întâlnite în legătură cu modificările recente privind metodele de încărcare a fișierelor CSS discutate în acest subiect și acest subiect.
Problemele au apărut într-un scenariu tipic, folosind o temă părinte bine întreținută și pregătită pentru teme copil, pe o instalare WordPress 4.0. Fișierul functions.php al temei mele copil conține doar funcția wp_enqueue_style
conform documentației din Codex.
Rețineți că deși codul referit mai jos este specific acestei teme, mare parte utilizează convenții actuale de codare folosite de temele părinte. În plus, preocupările mele sunt probabil replicabile pe multe teme părinte existente. De asemenea, întrebările ridicate sunt aplicabile la nivel universal, indiferent de tema părinte folosită.
PROBLEMA 1: Dublarea încărcării
Configurația recomandată:
Tema părinte încarcă stilurile și scripturile folosind hook-ul wp_enqueue_scripts
, partea relevantă fiind:
add_action('wp_enqueue_scripts', 'parent_theme_function_name');
function parent_theme_function_name() {
wp_register_style( 'avia-style' , $child_theme_url."/style.css", array(), '2', 'all' );
wp_enqueue_style( 'avia-base');
if($child_theme_url != $template_url) { wp_enqueue_style( 'avia-style'); }
}
Tema mea copil încarcă stilurile conform modificărilor recente din Codex:
add_action( 'wp_enqueue_scripts', 'enqueue_parent_theme_style' );
function enqueue_parent_theme_style() {
wp_enqueue_style( 'dm-parent-style', get_template_directory_uri().'/style.css' );
}
ID-urile folosite de codul referit:
id='dm-parent-style-css'
- fișierul CSS al temei părinte, încărcat de funcția temei copilid='avia-style-css'
- fișierul CSS al temei copil, încărcat de funcția temei părinteid='dm-child-style-css'
- fișierul CSS al temei copil, încărcat de funcția temei copil
Rezultate:
La prima vedere, totul arăta bine, cu următoarea ordine în <head>
:
<link rel='stylesheet' id='dm-parent-style-css' href='testinstall.dev/wp-content/themes/enfold/style.css?ver=4.0' type='text/css' media='all' />
<!-- Mai multe fișiere CSS individuale ale temei părinte aici -->
<link rel='stylesheet' id='avia-style-css' href='testinstall.dev/wp-content/themes/child-theme/style.css?ver=2' type='text/css' media='all' />
După instalarea unui plugin, ordinea de încărcare s-a schimbat astfel:
<link rel='stylesheet' id='dm-parent-style-css' href='testinstall.dev/wp-content/themes/enfold/style.css?ver=4.0' type='text/css' media='all' />
<!-- Mai multe fișiere CSS individuale ale temei părinte aici -->
<link rel='stylesheet' id='avia-style-css' href='testinstall.dev/wp-content/themes/child-theme/style.css?ver=2' type='text/css' media='all' />
<!-- Fișiere CSS ale plugin-urilor -->
Am nevoie ca fișierul CSS al temei copil să se încarce după plugin-uri, așa că am fost nevoit să adaug un număr de prioritate funcției din tema copil (vezi discuția anterioară despre numerele de prioritate).
Deoarece funcția mea încarcă doar CSS-ul temei părinte, rezultatul este că acum CSS-ul temei părinte este mutat la sfârșit, lăsând CSS-ul temei copil într-o poziție și mai nefavorabilă.
<!-- Mai multe fișiere CSS individuale ale temei părinte aici -->
<link rel='stylesheet' id='avia-style-css' href='testinstall.dev/wp-content/themes/child-theme/style.css?ver=2' type='text/css' media='all' />
<!-- Fișiere CSS ale plugin-urilor -->
<link rel='stylesheet' id='dm-parent-style-css' href='testinstall.dev/wp-content/themes/enfold/style.css?ver=4.0' type='text/css' media='all' />
Acum sunt nevoit să încarc și fișierul CSS al temei copil, pentru a mă asigura că revine la început, ceea ce duce la problema menționată anterior de dublare a încărcării CSS-ului temei copil.
Configurația depreciată:
Funcția revizuită în tema copil:
add_action( 'wp_enqueue_scripts', 'enqueue_parent_theme_style', 99 );
function enqueue_parent_theme_style() {
wp_enqueue_style( 'dm-parent-style', get_template_directory_uri().'/style.css' );
wp_enqueue_style( 'dm-child-style', get_stylesheet_directory_uri().'/style.css' );
}
Rezultate:
Producând următoarea ordine în <head>
:
<!-- Mai multe fișiere CSS individuale ale temei părinte aici -->
<link rel='stylesheet' id='avia-style-css' href='testinstall.dev/wp-content/themes/child-theme/style.css?ver=2' type='text/css' media='all' />
<!-- Fișiere CSS ale plugin-urilor -->
<link rel='stylesheet' id='dm-parent-style-css' href='testinstall.dev/wp-content/themes/enfold/style.css?ver=4.0' type='text/css' media='all' />
<link rel='stylesheet' id='dm-child-style-css' href='testinstall.dev/wp-content/themes/child-theme/style.css?ver=2' type='text/css' media='all' />
Deși includerea fișierului CSS al temei copil în funcția mea a dus la încărcarea lui de două ori, personal consider că acest lucru este preferabil față de a presupune că tema părinte va încărca corect fișierul nostru CSS.
Soluția mea:
Deși nu aș sugera ca aceasta să fie metoda recomandată (și sunt sigur că dezvoltatorii cu mai multă experiență vor gemi la această soluție), am dezactivat ID-ul temei părinte (folosit pentru a încărca CSS-ul temei copil) chiar înaintea încărcării proprii în fișierul functions.php al temei copil:
add_action( 'wp_enqueue_scripts', 'enqueue_parent_theme_style', 99 );
function enqueue_parent_theme_style() {
wp_enqueue_style( 'dm-parent-style', get_template_directory_uri().'/style.css' );
wp_dequeue_style( 'avia-style' );
wp_enqueue_style( 'dm-child-style', get_stylesheet_directory_uri().'/style.css' );
}
Rezultate:
Aceasta a rezolvat problemele, rezultând în:
<!-- Mai multe fișiere CSS individuale ale temei părinte aici -->
<!-- Fișiere CSS ale plugin-urilor -->
<link rel='stylesheet' id='dm-parent-style-css' href='testinstall.dev/wp-content/themes/enfold/style.css?ver=4.0' type='text/css' media='all' />
<link rel='stylesheet' id='dm-child-style-css' href='testinstall.dev/wp-content/themes/child-theme/style.css?ver=2' type='text/css' media='all' />
Desigur, acest lucru a necesitat cunoașterea ID-ului folosit de tema părinte - ar fi necesar ceva mai generic pentru a fi folosit ca metodologie standard de dezvoltare a temelor copil.
PROBLEMA 2: Fișiere CSS ale temei copil relocate
(Pare greu de crezut că această problemă nu a apărut în alt subiect, dar nu am găsit nimic specific când am căutat...dacă am omis ceva, nu ezitați să-mi atrageți atenția.)
Niciodată nu folosesc fișierul implicit style.css
din directorul rădăcină al temei copil pentru stilurile temei - evident că trebuie să fie acolo, dar toate stilurile mele reale sunt compilate din SCSS ca un fișier .css minificat într-un director /css/. Deși înțeleg că acest lucru nu este "norma așteptată" la nivel universal pentru dezvoltarea temelor copil, majoritatea dezvoltatorilor WordPress serioși pe care îi cunosc fac ceva similar. Acest lucru, desigur, necesită încărcarea manuală a acelui fișier CSS în funcția mea, indiferent dacă tema părinte l-a încărcat sau nu.
Pe scurt...
- Este sigur să presupunem că temele părinte încarcă corect stilurile temei copil, din punctul de vedere al standardelor pentru teme copil?
- Eliminarea priorității ar putea crea confuzie pentru o parte a comunității WordPress, când stilurile temei copil încep să fie suprascrise de un plugin. Ne așteptăm ca temele să suprascrie stilurile, dar nu la fel de mult la plugin-uri.
- Când folosim un fișier CSS personalizat pentru stilurile reale ale temei copil (spre deosebire de a le pune în fișierul prestabilit
style.css
), devine necesară încărcarea manuală a acelui fișier. În termeni de menținere a continuității pe o gamă largă de dezvoltatori, nu ar avea sens să încurajăm încărcarea manuală a fișierului CSS al temei copil, indiferent de posibila dublare?

ÎNTREBAREA 1
Este sigur să presupunem că temele părinte încarcă corect stilurile temei copil, din perspectiva standardelor temelor copil?
Regula generală, da. Dar, nu ar trebui să presupui niciodată. Majoritatea dezastrelor și eșecurilor în viață se datorează presupunerilor sau faptelor bazate pe o presupunere.
FAPTELOR FĂRĂ PRESUPUNERI
Fișierul functions.php al unei teme copil este încărcat mai întâi, apoi cel al temei părinte. Acest lucru asigură că fișierul de stil principal al temei părinte este încărcat înaintea celui al temei copil, conform codului actualizat din codex.
Să ne uităm la tema inclusă, twentytwelve. Magia se întâmplă aici
wp_enqueue_style( 'twentytwelve-style', get_stylesheet_uri() );
. Acesta este modul în care fișierul de stil principal este încărcat. Când tema este activă ca temă părinte, style.css va fi încărcat din tema părinte, deoareceget_stylesheet_uri()
va indica spre style.css din directorul părinte.Când treci la o temă copil,
get_stylesheet_uri()
"schimbă" calea pentru a indica spre style.css al temei copil, ceea ce înseamnă că acumwp_enqueue_style( 'twentytwelve-style', get_stylesheet_uri() );
în loc să încarce style.css al părintelui, va încărca style.css al copilului.Toate celelalte stiluri din tema părinte sunt încărcate normal, în ordinea în care sunt scrise.
CAPCANE
Stiluri inline și fișiere de stil adăugate direct în șablonul header. Am făcut câteva teste pe această problemă. Dacă fișierul de stil al părintelui nu este încărcat folosind
wp_enqueue_scripts
și este încărcat direct în header, atunci fișierul de stil principal al temei copil este încărcat primul. Ca soluție, am recomandat anterior să copiezi header.php din părinte în tema copil și să elimini acele apeluri. Apoi va trebui să încarci atât stilurile părintelui și copilului, cât și orice alte fișiere de stil încărcate direct în header.php, conform OP funcție depreciată.Am întâlnit de câteva ori situații în care stilurile (și scripturile) sunt încărcate direct în header, iar din această cauză apelul către
wp_head
este omis. Acest lucru va face ca acțiunea ta de încărcare să eșueze în tăcere, astfel încât stilurile tale pur și simplu nu vor apărea.Priorități setate greșit. Nu este necesar să setezi priorități în acțiunile părintelui sau copilului atunci când îți agăți funcțiile de încărcare. Când ambele au aceeași prioritate implicită, se aplică regula "primul venit, primul servit". Acest lucru va asigura că ordinea de încărcare este corectă.
NOTĂ PENTRU AUTORII DE TEME PĂRINTE
Metoda corectă și acceptată de a adăuga stiluri și scripturi la o temă este prin acțiunea wp_enqueue_scripts
. Niciodată nu adăuga stiluri și scripturi direct în șablonul header și nu seta nicio prioritate în acțiune atunci când îți agăți funcția.
Întotdeauna încarcă fișierul de stil principal după cum urmează:
wp_enqueue_style( 'twentytwelve-style', get_stylesheet_uri() );
Acest lucru va asigura că fișierul de stil principal al copilului este încărcat atunci când este utilizată o temă copil.
RESPONSABILITATEA TA CA AUTOR DE TEMĂ COPIL
Ia-ți timp și studiază tema părinte. Cunoaște tema părinte, asigură-te că ești confortabil cu structurile temei și cu modul în care sunt utilizate funcțiile și hook-urile în temă. Nu poți crea o temă copil de succes dacă nu ai cunoștințe despre cum funcționează tema părinte. Este responsabilitatea ta să te asiguri că stilurile și scripturile sunt încărcate corect pentru ca codul tău să funcționeze conform așteptărilor.
Întotdeauna avertizează autorul temei părinte despre orice cod cu care nu ești mulțumit. De exemplu, dacă autorul a adăugat stilurile sale direct în header, avertizează-l despre acest lucru și fă-l conștient că acesta este modul greșit de a face acest lucru, și cere-i să corecteze acest lucru într-o versiune viitoare.
ÎNTREBAREA 2
Eliminarea priorității ar putea crea mai multă confuzie pentru o parte a comunității WordPress, atunci când stilurile temei copil încep să fie suprascrise de un plugin. Ne așteptăm ca temele să suprascrie stilurile, dar nu la fel de mult cu plugin-urile.
Din păcate, nu există o metodă directă de a te proteja împotriva acestui lucru. Adevărul este că stilurile plugin-urilor nu ar trebui să suprascrie niciodată stilurile implicite ale temei fără consimțământul utilizatorului final. În opinia mea, aceasta este doar o practică proastă sau neglijență din partea autorului plugin-ului. Aș sugera ca într-un astfel de caz, să contactezi autorul plugin-ului și să-l avertizezi despre această problemă.
De asemenea, ai întotdeauna opțiunea de a dezactiva și deregistra un stil (și script) de care nu ai nevoie, sau pentru care trebuie să schimbi prioritatea, și apoi să le reîncarci și reregistrezi, așa cum ai făcut în codul tău de mai sus (ceea ce este perfect în regulă). Doar o notă despre shivm, cea mai bună practică este să dezactivezi și să deregistrezi un stil și un script.
ÎNTREBAREA 3
Când folosești un fișier de stil personalizat pentru stilurile reale ale temei copil (în loc să le pui în style.css predefinit), devine necesară încărcarea manuală a acelui fișier. În ceea ce privește menținerea continuității pe o gamă largă de dezvoltatori, nu ar avea sens să încurajăm încărcarea manuală a fișierului de stil al copilului, indiferent de posibila duplicare?
Nu cred că există un răspuns direct alb-negru la această problemă. Aș răspunde spunând, fă ce te simți confortabil, atâta timp cât rămâi în cadrul unor anumite linii directoare care reglementează acțiunea.
Fișierele de stil nu sunt acolo pentru a adăuga funcționalitate, ci pentru a îmbunătăți experiența vizuală a utilizatorului. Stilurile sunt, de asemenea, trimise direct așa cum sunt către browser, unde sunt procesate. WordPress nu joacă niciun rol aici.
Pe baza acestui fapt, nu văd nicio amenințare majoră în încărcarea unui fișier de stil de două ori. Acest lucru ar putea costa câteva milisecunde în ceea ce privește performanța. Sincer, în afară de asta, nu sunt sigur cum sunt gestionate duplicatele în diferite browsere. Acesta este ceva pe care tu, cititorule, poți să-l testezi.
IMHO, duplicatele nu sunt niciodată bune și ar trebui evitate întotdeauna. Aș sugera ca, dacă chiar vrei să încarci manual fișierul de stil principal al copilului, indiferent de motiv, să folosești codul din shivm. Dezactivează și deregistrează duplicatul adăugat implicit și apoi reîncarci fișierul de stil în mod normal.
Un lucru de reținut, de asemenea, funcțiile de încărcare și înregistrare au un parametru $dependancy
pe care îl poți folosi. Așadar, este ușor să încarci un fișier de stil secundar și să-l faci dependent de fișierul de stil principal al temei tale copil.
ÎN CONCLUSIE
De la ultima actualizare a codex-ului, feedback-ul a fost uimitor și aș dori să le mulțumesc tuturor pentru feedback-ul oferit la această întrebare. Aș dori să încurajez pe toată lumea să participe la orice fel de feedback legat de această întrebare în special. Dacă ai ceva de adăugat sau de comentat, te rog să o faci.

Pieter, mulțumesc pentru răspunsul tău detaliat. Am fost copleșit astăzi, dar am câteva gânduri bazate pe ceea ce ai spus și sper să le adaug mai târziu în seara aceasta.
