Crearea unui Preprocesor Mini-CSS pentru opțiunile culorii tematice

WordPress oferă dezvoltatorilor de teme un sistem puternic de creare a sistemelor de opțiuni tematice ușor de utilizat, prin intermediul Theme Customizer. În timp ce personalizatorul oferă un sistem de previzualizare excelentă în timp real și o experiență de ansamblu a utilizatorului, definirea rezultatelor setate în personalizatorul poate fi dezordonată. 

În acest tutorial, vă voi arăta cum să simplificați obținerea opțiunilor de culoare care sunt setate în personalizatorul în CSS în front-end. Acest sistem simplu poate fi adaptat pentru utilizarea cu alte proprietăți CSS, precum și. Acest lucru înseamnă că puteți utiliza aceste tehnici pentru a lucra cu opțiuni stabilite prin alte metode decât Tema Customizer.

Ce încercăm să evităm

Prea adesea, obtinerea de culori si alte optiuni setate in Theme Customizer implica mixarea codului PHP si CSS. 

De exemplu: 

add_action ('wp_head', 'slug_theme_customizer_css'); funcția slug_theme_customizer_css () ?>   

Problema cu acest cod nu este pur estetică sau că este greu de citit. Este prea ușor să faci o greșeală. De exemplu, închiderea etichetelor PHP, urmată de închiderea declarației CSS, conduce la următoarele:?>;, care pare rău, dar este punct de vedere tehnic corect.

În timp ce puteți începe această funcție prin obținerea tuturor valorilor de culoare de care aveți nevoie în variabile, va trebui în continuare să deschideți etichete PHP pentru a echivala valorile lor în CSS. Totuși, este un început bun. Abilitatea de a pune valorile culorilor CSS în variabile, desigur, este unul dintre multe lucruri minunate despre utilizarea unui preprocesor CSS.

În timp ce adăugați un procesor Sass sau LESS complet la tema dvs. este posibil și există pluginuri pentru a face acest lucru, aceasta trece peste bord pentru o sarcină simplă de a converti câteva variabile la valori hexazecimale. În schimb, vă voi arăta cum să creați un simplu preprocesor în tema dvs. cu doar câteva rânduri de cod.

O mai bună marcare CSS

Primul lucru pe care trebuie să-l faceți este să creați un fișier în tema numită customizer.css. Acest fișier ar putea avea cu adevărat o extensie, dar să-i dai un a css extensia înseamnă că editorul de cod sau IDE-ul îl va trata ca un fișier CSS care ușurează lucrul cu acesta.

În customizer.css puteți reformula acel cod urât din exemplul anterior în acesta:

h1.site-title a culoare: [site_title_color];  h3.site-description culoare: [site_description_color]; 

După cum puteți vedea, acum puteți scrie CSS ca și cum ar fi CSS. Pur și simplu înlocuiți valorile care vor fi setate de la personalizatorul cu numele theme_mod în paranteze. Aceste șiruri vor fi înlocuite de preprocesorul nostru cu valoarea din baza de date. Cel mai important lucru aici este că folosiți numele temelor mod ca valoare de substituție în CSS neprocesat.

Construirea Preprocesorului dvs.

Preprocesorul în sine este de fapt incredibil de simplu, deoarece ia conținutul dvs. customizer.css  și utilizează PHP str_replace () pentru a înlocui valorile din paranteze cu valorile din instrumentul de personalizare.

Întregul sistem implică o clasă simplă, cu trei metode și o funcție în afara clasei, la care este cuprins wp_head pentru a genera CSS procesate și optimizate. Rețineți că acest cod presupune că toate datele de care avem nevoie sunt stocate în moduri tematice, care este implicit pentru personalizatorul temelor. Este posibil să trebuiască să le înlocuiți get_theme_mod () cu get_option () în codul dvs., în funcție de nevoile dvs. exacte.

Această clasă folosește a pentru fiecare bucla în fiecare metodă. Dacă nu sunteți familiarizat cu modul în care pentru fiecare bucle, vă recomandăm să aruncați o privire la articolul meu despre lucrul cu bucle și matrice. De asemenea, dacă nu sunteți familiarizați cu clasele PHP sau PHP (OOP) orientate pe obiecte în general, ar trebui să verificați seria introductivă a lui Tom McFarlin despre OOP.

Pentru a începe, într-o a ta functions.php sau într-un fișier inclus în el, creează o clasă goală numită slug_theme_customizer_output înlocuind "slug" cu melcul unic al temei. Ar trebui să arate astfel:

clasa Slug_Theme_Customizer_Output 

Prima metodă din clasă va fi locul în care setați modurile de temă pe care le veți folosi, precum și valorile implicite pentru fiecare temă mod. Ați setat fiecare într-o matrice sub formă de theme_mod => implicit. Lipind cu aceleași două setări ca înainte, ar fi de dorit acest lucru:

funcția theme_mods () retur array ('site_title_color' => '# ff0000', 'site_description_color' => '# 000'); 

Următorul pas va fi obținerea valorii actuale a fiecăruia theme_mod și pune-l într-o matrice pe care o putem folosi în preprocesorul nostru real. Această metodă primește pur și simplu fiecare valoare din theme_mods () metoda și trece cheia ca primul argument, care este numele temei_mods la get_theme_mods () în timp ce trece valoarea implicită ca al doilea argument, care va fi returnat dacă nu există nimic setat în tema mod. Acesta va arata astfel:

funcția prepare_values ​​() $ colors = array (); // Obțineți modurile de temă și valorile implicite. $ theme_mods = $ this-> theme_mods (); // Pentru fiecare temă mod, ieșiți valoarea temei mod sau valoarea implicită. foreach ($ theme_mods ca $ theme_mod => $ implicit) $ culori [$ theme_mod] = get_theme_mod ($ theme_mod, $ default);  întoarce $ culori; 

Acum avem o matrice sub forma de 'theme_mod_name' => 'valoare de înlocuit' și gata de a procesa CSS în a treia metodă finală a acestei clase.

În pentru fiecare în această metodă, profităm de capacitatea pe care PHP o oferă pentru a trata cheia și valoarea matricei ca variabile separate. Aceasta este o caracteristică foarte puternică a PHP pentru fiecare buclele care necesită o planificare mică în modul în care fiecare structură este structurată și face viața mult mai ușoară.

Primul pas va fi de a utiliza file_get_contents () pentru a converti customizer.css fișier într-un șir și stocați-l într-o variabilă. Deoarece această funcție va cauza o eroare fatală dacă nu poate găsi fișierul, trebuie să înfășurăm tot codul în această metodă într-un test dacă fișierul există la toate. 

Rețineți că acest cod presupune acest lucru customizer.css este în același director ca și clasa, este posibil să trebuiască să ajustați structura fișierului temei. Iată cum începem această metodă:

($) $ css = "; / / Modificați acest nume de fișier și / sau locație pentru a satisface nevoile dvs. $ theme_customizer_file = trailingslashit (dirname (__FILE__)). (file_exists ($ topic_customizer_file)) // Obțineți conținutul fișierului $ css = file_get_contents ($ theme_customizer_file);

Așa cum am spus înainte, această întreagă metodă este înfășurată într-o verificare dacă fișierul există. Asta înseamnă că se va întoarce fals dacă fișierul nu se încarcă. Țineți minte acest lucru, deoarece va trebui să luăm în calcul această posibilitate mai târziu.

Acum, că avem CSS ca șir, va trebui să luăm matricea de valori de substituție de la prepare_values ​​() metodă. Din nou, vom folosi cheia de matrice și variabila ca variabile separate în pentru fiecare buclă. Pentru fiecare theme_mod trebuie să adăugăm paranteze în jurul acestuia, apoi îl putem folosi pentru a înlocui șirul de substituție în CSS cu str_replace (), asa:

// Obțineți culorile noastre. $ culori = $ this-> prepare_values ​​(); // Înlocuiți fiecare culoare. foreach ($ culori ca $ theme_mod => $ color) $ search = '['. $ theme_mod. ']'; $ css = str_replace ($ căutare, $ culoare, $ css); 

Această buclă ne va oferi un CSS complet validat, cu toate denumirile de moduri tematice încorporate, înlocuite cu codurile hexate corecte pentru culori. Tot ce a mai rămas este să înfășurați CSS procesat în etichetele de stil corespunzătoare înainte de ao returna:

// Adăugați etichete de stil. $ css = '„; retur $ css;

E tot preprocesorul. Singurul pas rămas este de a ieși din CSS în sine. Pentru a face acest lucru, putem folosi o funcție, în afara clasei, care inițializează clasa și o transmite în antetul temei. 

Această funcție arată astfel:

add_action ('wp_head', 'slug_theme_customizer_output'); funcția slug_theme_customizer_output () // Asigurați-vă că există clasa noastră. dacă (class_exists ('Slug_Theme_Customizer_Output')) // Iniționați clasa și obțineți css procesat. $ class = noua funcția Slug_Theme_Customizer_Output (); $ css = $ clasă-> proces (); // Pentru a fi sigur, asigurați-vă că metoda "proces" nu a revenit false sau altceva decât un șir. dacă ($ css && este_string ($ css)) echo $ css; 

Dacă vă amintiți din timp, metoda proces() poate reveni la fals dacă fișierul CSS nu a putut fi încărcat. Pentru a ține cont de această posibilitate, înainte de a reda valoarea proces() , este important să vă asigurați că nu se întoarce nici falsă, nici nu întoarce nimic care nu este un șir.

Extra optimizare bonus

În timp ce ne-am putut opri aici, aș vrea să fac lucrurile mai puțin eficiente. Acest sistem funcționează perfect, dar are și o mulțime de procesări repetitive, complete cu ceea ce ar putea fi mai multe interogări baze de date pe fiecare încărcare de pagină. Personal, aș prefera să sărind să rulez întreaga clasă și să obțin un șir dintr-o bază de date.

Pentru a realiza acest lucru putem redeschide funcția de ieșire pentru a memora cache-ul CSS într-un tranzitoriu. În acest fel, atunci când putem trece peste întreaga clasă de preprocesoare în cazul în care tranzitoria are o valoare, dacă nu, atunci putem rula întregul proces și re-cache-l. Iată funcția de ieșire modificată:

add_action ('wp_head', 'slug_theme_customizer_output'); funcția slug_theme_customizer_output () // Fie setați css la tranzitorie sau reconstrui. if (false === ($ css = get_transient ('slug_theme_customizer_css'))) // Asigurați-vă că există clasa noastră. dacă (class_exists ('Slug_Theme_Customizer_Output')) // Iniționați clasa și obțineți css procesat. $ class = noua funcția Slug_Theme_Customizer_Output (); $ css = $ clasă-> proces (); // Cache cache pentru data viitoare. set_transient ('slug_theme_customizer_css', $ css);  // Pentru a fi sigur, asigurați-vă că metoda "proces" nu a revenit false sau altceva decât un șir. dacă ($ css && este_string ($ css)) echo $ css; 

Acum, dacă există o valoare stabilită în tranziție slug_theme_customizer_css acesta poate fi reluat direct, după trecerea acelorași teste pentru a se asigura că nu este nici unul fals sau nu un șir. Clasa preprocesor nu este încărcată și se face o singură interogare în baza de date. Dacă revine tranziția fals, procesul este rulat și valoarea este stocată în memoria cache pentru data viitoare.

Desigur, vrem să ne asigurăm că atunci când modurile de temă sunt actualizate, vom șterge tranzitoria, astfel încât să nu se obțină setări de date depășite. WordPress va procesa acest lucru ori de câte ori o opțiune specifică este actualizată.

Putem folosi această acțiune deoarece temele mods sunt stocate opțiune numită pentru tema asociată cu. De exemplu, modurile temei TwentyFourteen sunt stocate în opțiune theme_mods_twentyfourteen. Iată cum folosim această acțiune, pentru a limita tranzitorii:

/ ** * Resetați slug_theme_customizer_css tranzitorii atunci când modurile tematice sunt actualizate. * / // Obțineți numele temei curente. $ temă = get_stylesheet (); add_action ("update_option_theme_mods _ $ theme", "slug_reset_theme_customizer_css_transient"); funcția slug_reset_theme_customizer_css_transient () delete_transient ('slug_theme_customizer_css'); 

Puneți-l în uz și luați-l mai departe

Acum, că puteți să vă scrieți CSS care se actualizează de la personalizatorul temei cu variabile, un lucru pe care poate doriți să îl luați în considerare este utilizarea unui mod tematic în multe locuri. 

De exemplu, în loc să setați un theme_mod pentru fiecare culoare din temă și să provocați supraîncărcarea opțiunilor, despre opțiunile pentru culoarea primară, culoarea secundară și culoarea accentului?

Sistemul pe care ți-am arătat-o ​​cum să creezi aici funcționează numai cu opțiuni de culoare, făcându-l foarte util doar pentru proprietățile CSS culoare, culoare de fundal, border-color, etc. Ați putea să le extindeți pentru a fi utile pentru alte tipuri de proprietăți. 

Doar amintiți-vă să nu reinventezi Sass sau mai puțin, scopul acestui lucru este să eviți balonarea temei cu o implementare completă PHP Sass sau LESS, care sunt deja disponibile ca pluginuri.

Cod