Simplificarea și reducerea codului WordPress

Simplificarea și reducerea codului WordPress

Azi am avut o zi foarte plină făcând refactor la o temă de WordPress. Iar una dintre cele mai bune modalități de a face asta este prin… spargerea codului în mai multe fișiere, separate pe responsabilități. Și hooks. Prin urmare, am două exemple:

functions.php§

În functions.php este, de obicei, haos. În proiectul curent aveam ~6000 linii de cod, patru clase definite, nenumărate filtre, acțiuni, shortcode-uri, widget-uri, set-up etc. O adevărată plăcere să cauți ceva acolo!

Eu încerc să păstrez fișierul ăsta doar ca un fel de bootstrap: includ fișiere, includ composer (dacă e cazul, de data asta nu a fost), adaug filtre și maximum instanțiez clase.

Un exemplu de cod:

function taxonomy_description(){
    //....
}
add_shortcode('taxdescription', 'taxonomy_description');

function exclude_single_posts_home() {
    //....
}
add_action('pre_get_posts', 'exclude_single_posts_home');
//etc

Primul lucru făcut în cazul ăsta este să extrag fiecare funcție în fișierul ei, într-un folder sugestiv. De obicei este includes/numele-proiectului. În cazul de față, numele proiectului a fost vippy. Prin urmare, funcțiile (doar funcțiile) de mai sus au fost mutate în fișiere:

- includes/vippy/shortcodes/taxonomy_description.php
- includes/vippy/filters/query/exclude_single_posts_home.php

Al doilea lucru a fost să pun fiecare funcție sub un namespace. Prin urmare, avem așa:

// includes/vippy/shortcodes/taxonomy_description.php:
namespace vippy\shortcodes;
function taxonomy_description() {}

// functions.php:
require_once 'includes/vippy/shortcodes/taxonomy_description.php';
add_shortcode('taxdescription', 'vippy\shortcodes\taxonomy_description');

În acest fel am reușit să cobor functions.php de la ~6000 linii la 150. Nu-i rău, nu? Nu mă înțelege greșit, tot codul ăla este în continuare în proiect, dar responsabilitățile sunt atât de bine separate încât treaba asta devine o problemă secundară.

header.php§

Am observat că un alt loc unde se adună porcării este header.php. Ai bucăți din structura site-ului, ai tracking codes, css custom și alte minuni. În proiectul curent aveam 400 linii de cod. Prin urmare, am împărțit și pe aici lucrurile:

wp_head§

Din temele văzute de mine de-a lungul timpului, se pare că lumea nu prea a aflat de wp_head: un hook care se pune în tag-ul <head> și care permite adăugarea de … orice ar trebui să fie acolo: css custom, tracking code și alte minuni! (evident, nu se aplică doar la acest fișier ci la toate fișierele: single.php, archive.php etc)

// functions.php
require_once 'includes/vippy/filters/wp_head.php';
add_action('wp_head', 'vippy\filters\wp_head');

În funcția vippy\filters\wp_head nu facem decât să includem bucățile ce ne interesează:

// includes/vippy/filters/wp_head.php
namespace vippy\filters;
function wp_head() {
  require_once STYLESHEETPATH . '/views/custom_css.php';
}

Nu face greșeala de a amesteca HTML aici! Fă un folder views (sau templates sau ceva sugestiv) în care pui HTML-ul. Evident, în acele fișiere păstrezi logica la minimum!

Custom hooks§

Al doilea lucru de care „programatorii” n-au aflat este acela că poți avea… drum rolls… custom hooks.

În cazul ăsta aveam ceva de genul:

<div id="content">
        <div id="container" class="boxed">
        // 80 linii de html + php
// EOF

Pentru că vreau să simplific codul și că cele ~80 linii de html + php nu arătau prea frumos, am mutat toată povestea în views/layout/after_container_open.php iar codul de mai sus s-a transformat în:

<div id="content">
        <div id="container" class="boxed">
        <?php do_action('vippy/layout/after_container_open'); ?>
EOF

Apoi am adăugat în functions.php hook-ul ăla și zbang, am rămas cu un header.php de 30 linii.

Concluzie§

Înțeleg de ce WordPress este atât de hulit de mulți programatori experimentați: codul poate ajunge rapid o harababură imensă, greu de citit, greu de întreținut.

Dar asta nu înseamnă că trebuie să produci și tu, la rândul tău, o asemenea harababură, nu? :)

10 Comentarii

Ionut Popa a scris

Am o intrebare legata de WordPress. Pe StackOverflow nu a vrut sa imi raspunda nimeni, asa ca te intreb pe tine: cum sanitizezi si escapezi codul JS care trebuie salvat in baza de date si apoi printat in frontend. De exemplu un cod de baner, care trebuie bagat de un admin in customizer sau intr-un camp de plugin settings.

Am vazut ca WordPress are un esc_js(), dar ala e doar pentru inline javascript si doar pentru afisare. Pentru sanitizare nu are nicio functie similara. Mersi.

Ionuț Staicu a scris

@Ionut Popa: Eu evit pe cât posibil să țin cod în DB. Mai degrabă aș pune codul ăla într-un plugin și aș face doar variațiile configurabile (e.g. userID).

Dacă vrei să faci asta la modul generic (e.g. să pui într-o temă publică sau să accepte orice fel de cod) și pleci de la premisa că doar userii cu anumite permisiuni pot face asta, atunci nu este nevoie să faci nici un escape dacă salvezi în wp_postmeta sau wp_options. CRED că ai nevoie să faci esc_html când afișezi editorul (în admin), dar când vrei să afișezi în frontend dai doar echo get_option().

Ionut Popa a scris

@Ionuț Staicu: Eu incerc sa respect coding standards pe cat posibil. Deocamdata am salvat in clar JS-ul, fara nicio sanitizare si il afisez fara escapare. Merge fara probleme. Da, ideea e ca doar adminul poate pune codul si vreau sa las la liber, sa fie orice cod de ads. Ideea cu variatiile configurabile a mers pentru codul de Analytics (property ID-ul).

Am incercat cu base64 encode si apoi decode, dar theme checker-ul de la WordPress si cel de la Envato ma avertizeaza ca nu se poate folosi base64. M-am uitat cum fac si altii in Flatsome (o tema f populara de pe ThemeForest) si la cateva pluginuri si teme de pe wordpress.org, care si ele salveaza in clar. De asta sunt cumva nedumerit, ca este obligat sa sanitizezi orice input si sa escapezi orice output, dar de fapt acest „orice” nu se aplica intotdeauna.

Vroiam sa stiu daca fac eu ceva gresit si daca exista un mod corect de a salva astfel de bucati de cod in baza de date.

Ionuț Staicu a scris

@alescx: Depinde foarte mult care este scopul acelor date. Dacă vrei să afișezi conținut – de exemplu – te apuci să cureți tot input-ul (e.g. scoți tag-uri invalide, închizi tag-uri lăsate neînchise etc).

Dar dacă vrei să afișezi FIX acele date care mai este rostul sanitizării? WP – știu că ești fan 😂 – se ocupă de sanitizare la insert în DB deci nu există risc de injecții în direcția asta.

Adaugă un comentariurăspuns pentru

Poți adăuga bucăți de cod folosind [code]codul tău aici[/code], [js][/js], [php][/php] etc.

Link-urile în context sunt binevenite. Comentariile fără nume/email valid sunt șterse.
PS: Comentariul NU este editabil.

Acest site folosește Akismet pentru a reduce spamul. Află cum sunt procesate datele comentariilor tale.

Site-ul blog.iamntz.com utilizează cookie-uri. Continuarea navigării presupune acceptarea lor. Mai multe informații.

windows apple dropbox facebook twitter