În Tutoriale

Crearea unei teme WordPress (III). Dezvoltarea temei – loops și content

temă de wordpress

Până în momentul de față am învățat detaliile necesare pentru a începe construirea unei teme WordPress și am construit structura ei. Urmează să finalizăm prima versiune a temei.

În aceasă parte vom învăța cum să afișăm conținutul în tema noastră. Când spun conținut ma refer la pagina articolului, paginile de arhiva sau comentarii. Pe lânga acestea o să aruncăm o privire la cateva funcții deja existente în WordPress pe care mulți creatori de teme evită să le folosească și astfel ajung să recreeze respectivele funcții.

Ierarhia fișierelor și fișierele necesare

Vă invit să ne uităm din nou peste fișierele necesare afișării conținutului. Ca să afișăm toate tipurile de conținut corect, avem nevoie de single.php, page.php, archive.php, search.php, index.php și comments.php.

Scopul fiecăui fișier este:

  • single.php – Afișarea articolelor adăugate în Dashboard > Posts > Add New, sau a atașamentelor ( în lipsa fișierului attachment.php )
  • page.php – Afișarea paginilor adăugate în Dashboard > Pages > Add New
  • archive.php – Afișarea arhivei generată de dată ( an, lună, zi – în lipsa fișierului date.php ), paginare, autori ( în lipsa fișierului author.php ), categorii ( în lipsa fișierului category.php sau taxonomy.php ) sau taguri (  în lipsa fișierului tag.php )
  • search.php – Afișarea rezultatelor ale unei căutări.
  • index.php – Afișarea ultimelor postări în funție de interogarea facută. ( acest fișier este fișierul de back-up al WordPress-ului )
  • comments.php – Afișarea comentariilor pe pagini sau articole.

Observăm cum putem menține lucrurile simple dacă avem o structură uşoară dar în același timp avem posibilitatea de a extinde complexitatea temei foarte ușor.

Singular.php

Fișierul singular.php a fost introdus în WordPress din versiunea 4.3. El ne permite să îndeplinim scopul fișierelor single.php și page.php folosind un singur fișier. În concluzie, dacă folosim fișierul singular.php putem afișa aceeași structură pentru articole, pagini și atașamente, nefiind nevoiți să repetăm codul.

WP_Query Class și buclele principale

Afișarea conținutului în WordPress are o logică puțin mai complicată la început. Pentru a înțelege cum funcționează vă recomand să citiți puțin despre câteva lucruri din PHP: variabile globale, obiecte, clase și while loop

WP_Query Class

Clasa WP_Query este responsabilă pentru extragerea datelor din baza de date, pe baza argumentelor pe care le primește.

Informațiile fiecărei interogări  sunt stocate într-un obiect global $wp_query care preia postările din baza de date cu ajutorul clasei WP_Query ( motiv pentru care devine obiect ). Acest obiect este disponibil la orice request de pagina în WordPress și în orice instanță nouă de WP_Query. Practic, dacă doriți să primți ultimele postări în index.php se poate face acest lucru folosind acest obiect, dar acestă practică este folosită numai în cazul customizărilor avansate sau plugin-uri, nu este recomandat să se folosească acest obiect atunci când scopul task-ului poate fi obținut cu o altă funcție care face parte din core-ul WordPress, ex the_post().

Posts Loop

Pentru afișarea postărilor în orice situație/pagină este necesar să facem un loop simplu pe obiectul $wp_query. Desigur că loop-ul nu va fi facut direct pe acest obiect, ci ne vom folosi de anumite funcții deja disponibile în WordPress.

 

În exemplu ne folosim de doua funcții, have_posts() care verifică dacă există postări în $wp_query și the_post() care ne face disponibile informațiile pentru fiecare post în parte. Ca să facem legatura mai bine cu ceea ce am explicat mai sus, funcția the_post() cheamă defapt metoda the_post() din $wp_query, mai exact $wp_query->the_post(). Probabil vă întrebați de ce face acest lucru, care pare a fi numai un pas în plus, raspunsul este simplu. Face asta ca să se poată folosi $wp_query->the_post() fara a iniția din nou clasa WP_Query. Clasa este deja inițiata la încărcarea paginii, lucru care este considerat bad practice de anumiți programatori.  

Loop-ul, exact în forma prezentată îl vom folosi în fișierul index.php, iar în interiorul loop-ului while afișăm și formatăm conținutul. În cazul nostru folosim funția get_template_part() pentru a prelua respectiva bucată de cod și pentru a nu ne repeta codul.  

Single Loop

Pentru paginile de articol ( single.php și page.php ) o să ne folosim de acelasi tip de loop, dar excludem condiția care verifică dacă exisă postări, deoarece dacă se accesează orice pagină de postare care nu are id-ul înregistrat în baza de date, va returna eroare 404 și template-ul 404.php va fi chemat și afișat.  

Custom query și custom loop  

În WordPress avem posibilitatea de a creea noi query-uri folosind clasa WP_Query. Luând exemplul de mai sus, unde variabila globală $wp_query inițiază deja clasa WP_Query, la fel o să inițiem și noi noul query, doar ca în loop-ul nostru o să folosim metodele obiectului ci nu funcțiile simple ( have_posts() sau the_post() ). Mai jos avem ca și exemplu inițierea unui query personalizat și parcurgerea informațiilor cu ajutorul loop-ului.    
Posibil în momentul de față s-a creat o confuzie din cauza funcțiilor have_posts() și the_post(). Difereța este că atunci când facem un query custom, aceste funcții sunt metode ale obiectului care inițiaza clasa WP_Query iar în loop-ul simplu chemăm aceste funcțiile simplu, deoarece sunt doar două funcții cu același nume ca și metodele pe care le cheamă. Dacă aruncăm o privire în codul sursă al core-ului WordPress o să observam acest lucru în fișierul query.php la linia 818.

Archives

Când spunem archives ne referim la orice pagină care nu este o postare. În tema noastră ne folosim numai de archive.php și search.php dar, să nu uităm că archive.php acoperă și author.php, category.php, taxonomy.php, date.php și tag.php.

Archive.php

Diferența dintre archive.php și index.php este o singură linie de cod în cazul nostru, ci anume funcția care afișează titlul arhivei the_archive_title($before, $after), care acceptă doi parametrii. Funcția este relativ nouă, mai exact din versiunea WordPress 4.1 și a fost creata pentru a evita codul necesar pentru crearea titlurilor. Mai sus am observat o mulțime de fișiere pe care archive.php le acopera, dacă nu exista această functie eram nevoiți să facem câte o condiție pentru fiecare tip de arhiva ca să afișăm corect titlul.  Aici aveți codul sursă al funcției.

the_archive_title('<h2 class="archive_title">', '</h2>');

Search.php
Fișierul search.php este foarte similar cu archive.php și index.php, singura diferență este afișarea titlului paginii. Forma titlului pe pagina de search este aceasta: ”Ai cautat: $keyword„ . Ca să preluam cuvintele căutate ne folosim de funcția get_search_query(). Funcția nu face altceva decât să preia valoarea metodei GET din URL. În exemplul nostru am folosit funția sprintf() pentru a returna un string formatat.

echo '<h2 class="archive_title">' . sprintf( 'Search Results for: %s', get_search_query() ) . '</h2>';

Loop content

Mai sus observăm că am adăugat conținutul în loop folosind funcția get_template_part(), funcție care ne ajută să preluăm și să centralizăm o anumită bucată de template. În cazul nostru acestă bucată de cod se repetă pe fiecare poziție a loop-ului, astfel rezultă lista de postări de pe pagină.

Pentru fiecare postare noi trebuie să afișăm imaginea acesteia, titlul, url-ul ( ancora ), data postării, numărul de comentarii pe care îl are postarea și un extras de conținut.

Afișare imagine articol

Pentru afișarea imaginii în articol avem nevoie direct de URL-ul acesteia, pentru a obține URL-ul am folosit funția wp_get_attachment_image_src(), care acceptă ca și parametrii ID-ul atașamentului și dimensiunea imaginii. Id-ul îl vom obține cu ajutorul funcției get_post_thumbnail_id() care necesită ID-ul postari. După ce am obținut URL-ul imaginii, facem o condiție unde verificăm dacă imaginea există și o afișăm, dacă aceasta nu există o să asignăm un atribut HTML style la o variabilă, pentru a adauga width: 100% pe conţinut în situația când imaginea nu există.
  Titlu și URL A Afișăm titlul și URL-ul postări cu ajutorul funcțiilor he_title() și the_permalink().

<h3><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h3>

Notă: În WordPress URL-urile se găsesc sub denumirea de permalink(s). Post Meta Data Aceasta nu este o denumire oficiala, ci este o denumire dată de către comunitate. Se refera la datele specifice articolului, precum data publicarii, autorul, categoriile în care a fost adăugat, numarul de cuvinte, numarul de comentarii, etichetele sau post format-ul. Noi avem nevoie numai de data publicarii și numarul de comentarii. Data se afișeaza cu ajutorul funcției the_time() care acceptă ca și parametru formatarea datei/timpului folosind sintaxa oficială PHP. Numărul de comentarii îl putem prelua folosind funcția comments_number(), care acceptă ca și parametrii string-ul returnat în cele trei cazuri disponibile:

  1. Când nu există comentarii  2. Când există un singur comentariu 3. Când există mai mult de un comentariu
<div class="post_meta"><?php echo the_time('F j,Y'); ?> - <?php comments_number( 'no comments', 'one comment', '% comments' ); ?></div><!-- / .post_meta -->

 

Paginare

Paginarea este un element necesar pentru toate website-urile care au conținut semificativ. Următoarele funții le putem folosi în toate template-urile, index.php, search.php și archive.php în cazul nostru. Paginare simplă Pentru a împărții postările în pagini o să ne folosim de două funcții și clonele lor previous_posts_link() și next_posts_link(). Exact cum spune și numele funcțiilor, prima este pentru pagina anterioară iar cea de a doua pentru pagina următoare. Funcțiile acceptă ca și parametru text-ul ancorei și returnează următorul cod HTML:
În exemplu am verificat prima dată dacă există link-ul pagini, cu ajutorul previous_posts_link() apoi am returnat link-ul.

[nota]

Denumirea funcţiilor în WordPress sunt standardizate, mereu o funcţie care începe cu get_ va returna valoarea, astfel se poate folosi în expresii.

[/nota]

Paginare cu numere

În cazul în care doriți paginarea numerotată puteți folosi funcția paginate_links(). Recomand folosirea acestei funcții în schimbul anumitor plugins.

Funcțiile de paginare se pun mereu imediat după loop-ul while dar în interiorul conditiei, pentru a nu fi chemată când nu există postări.

Pagina articol

Pagina articolului nu este foarte diferită de postarea din cadrul loop-ului, cel puțin în cazul nostru formatarea conținutului în pagina de single este exact aceeași. Dar pe lângă conținut există câteva elemente în plus, link-uri către articolul precendent sau următor și secțiunea de comentarii.

Conținut

Conținutul pe pagina articolului este afișat folosind funcția the_content(). Funcție nu foarte diferită de the_excerpt(). Diferența este că această funcție va afișa tot conținutul formatat, inclusiv cu tag-uri HTML generate de către editorul WYSIWYG.

Link-uri către articolul precendent sau următor

Funcțiile get_previous_post($in_same_cat, $excluded_categories) și get_next_post($in_same_cat, $excluded_categories) ne sar în ajutor la afișarea acestor link-uri. Funcțiile returneză un obiect cu datele postării, inclusiv ID-ul acesteia, având ID-ul putem extrage ulterior orice informație despre postarea respectivă, deci formatarea acestor link-uri ramane la limita imaginatiei voastre. În cazul de față mă folosesc de ID-ul acesteia pentru a obține permalink-ul, iar numele acesteia îl preiau folosind parametrul obiectului.

Comentarii

Comentariile sunt unul dintre componentele WordPress la care se lucrează foarte mult, pentru a obține optimizarea și securitatea necesară, lucruri care îl fac destul de complex, motiv pentru care nu l-am aprofundat 100% în acest tutorial.

 

Afișarea comentariilor

Afișarea lor este condiționată de numărul de comentarii și setările efectuare în Dashboard. Comentariile pot fi dezactivate pentru tot website-ul sau pentru o singură postare, indiferent de custom post type. O altă regulă de care trebuie să ținem cont este aceea că din versiunea 4.3 comentariile pentru pagini sunt oprite din core. Le putem porni folosind un filter hook pe get_default_comment_status, aici există un exemplu oficial.

 

Pentru a afla dacă comentariile pentru un anumit post sunt pornite, ne folosim de funcția comments_open(). Aditional adaugăm în condiție și rezultatul funcției get_comments_number(), care ne returnează numărul de comentarii pentru a afișa formularul de comentarii dacă există măcar un comentariu. Apoi dacă una dintre condiții este adevărată afișăm formularul cu funția comments_template() care încarcă codul din fișierul comments.php.
În fișierul comments.php se verifică dacă postarea are parola, dacă aceasta are, formularul va fi afișat numai după ce parola va fi introdusă.

Listarea comentariilor

Comentariile se listează cu ajutorul funcției wp_list_comments() care acceptă multe argumente, lucru care îl face foarte flexibil, dar greu de înțeles în unele cazuri. În exemplul nostru sunt folosite trei atribute:

  1. style – folosit pentru definirea tipului de listă ( div, ul sau ol )
  2. max_depth – câte niveluri de raspunsuri la comentarii se afișează
  3. avatar_size – reprezintă dimensiunea avatarului, în tema noastră nu există avatare și valoarea va fi 0

Formularul de comentarii

Afișarea se face folosind funcția comment_form() care returnează HTML-ul formularului de comentarii. Funcția accepta o mulțime de argumente, noi nu folosim nici un argument. Pagina funcției din WordPress Codex este incompletă la momentul scrierii acestui tutorial și este posibil să citiți informații greșite.

Formatarea conținutului

După ce tema este gata, este necesar să formatăm conținutul, adică să adăugăm stil pentru toate elementele generate de WordPress în cadrul editorului WYSIWYG cât și al elementelor generate de funcțiile de embed sau galerie. Aici avem câteva exemple pentru toate tag-urile generate de editorul WYSIWYG, precum mark-up, pozitionare imagini sau diverse cazuri extreme precum folosirea a mai multor tipuri de liste.
Utilizatorul are posibilitatea să adauge ce conținut dorește și în special să îl formateze după propriul plac, de aceea este responsabilitatea noastră să îi asigurăm o compatibilitate cât mai mare. Subiectul o să îl aprofundăm în tutorialul dedicat testarii.

În momentul de față tema noastră arată așa:

Homepage:

http://hapiucrobert.ro/wp-content/uploads/2016/03/homepage.png

Pagină articol + mark-up:

http://hapiucrobert.ro/wp-content/uploads/2016/03/single-si-markup.png

Pargină arhivă:

http://hapiucrobert.ro/wp-content/uploads/2016/03/arhiva.png

Codul final se află pe Github disponibil la >>acest link.

–––––––––––––––––––––––––––––––––––––––––––

În următorul articol o să continuăm cu cateva lecții puţin mai avansate. O să vă explic cu exemple detaliate cum folosim toate tipurile de hooks, cum adăugăm diverse setări folosind Customizer API, cum facem tema compatibilă cu uneltele de traducere, cum testăm corect tema iar la final o să trimit tema catre directorul oficial de teme WordPress și desigur o să discutăm în detaliu aceasă procedură.