Eelmistes postitustes ehitasime vundamendi: theme.json disainisüsteem, üldine plaan, pluginad ja CPT-d. Kõik tundus selge – kuni hakkasime Hero sektsiooni esilehele paigutama.
Selles postituses lahkame ühte FSE peamist küsimust: kus iga element elab?
Aha-hetk Hero’ga
Esimene mõte oli loogiline: Hero on suurus, mida tasub salvestada patterniks, et hiljem korduvalt kasutada. Tegime patterni, ehitasime Site Editor’is, eksportisime Create Block Theme’iga, lisasime templaadile.
Aga kui klient küsis “kuidas ma seda H1 teksti muudan?” – selgus, et pattern-viited ei ole inline-toimetatavad. Ta peaks “Edit pattern” nuppu kasutama, mis avab patterni-vaate. Segane.
Siis vaatasime Figmat uuesti üle. Ja sealt tuli pauk:
Hero on AINULT esilehel. Üks kasutus. Mitte korduv. Miks see pattern üldse on?
Pattern on disaini-mall. Kui sa kasutad seda ühel lehel, oled mallinud mitte-millegi jaoks. Sa oled lukustanud sisu PHP-faili (või veel hullem, andmebaasi pattern-vaatesse), kui see oleks võinud lihtsalt elada Avaleht Page’i sisus – kuhu klient on harjunud Block Editor’is sisu kirjutama.
FSE-l on viis kihti, mitte kolm
Õpikutes räägitakse tavaliselt kolmest: Template, Template Part, Pattern. Aga see jätab kõrvale kaks olulisemat:
- Template (
templates/*.html) – lehe luustik - Template part (
parts/*.html) – korduvad osad nagu header, footer - Pattern (
patterns/*.php) – disaini-mallid 2+ kasutuse jaoks - Page / Post sisu (
wp_posts.post_content) – konkreetse lehe sisu, klient muudab - CPT entry + ACF meta – dünaamiline andmestik (Teenused, Meeskond)
Iga kiht on disainilahendus oma probleemile. Kõige tähtsam erinevus: kus sa seda toimetad ja kas see jõuab Git’i.
| Kiht | Git’is | Toimetatav kus |
|---|---|---|
| Template | Jah | Site Editor → Templates |
| Template part | Jah | Site Editor → Patterns → Template Parts |
| Pattern | Jah | PHP fail / Pattern Editor |
| Page / Post sisu | EI | Pages/Posts → Edit (Block Editor) |
| CPT entry | EI | CPT menüü → Edit |
Kaks viimast kihti on andmebaasis. Migreerimisel tuleb käsitsi. See on kompromiss, mida tasub teadlikult teha – mitte kogemata.
Otsustusmaatriks
Iga kord, kui vaatad Figmast ühte elementi, küsi järjekorras:
- Kas see on kõikidel lehtedel sama? Header, footer? → Template part
- Kas see on lehe luustik (mitte sisu)? → Template
- Kas see on dünaamiline andmestik, mis kasvab ajaga? → CPT + ACF + Query Loop
- Kas see on kasutusel 2+ kohas?
- Sama sisuga → Pattern reference
- Erineva sisuga → Pattern + Detach iga kasutuskoha sees
- Ainult 1 koht? → Page/Post sisu (mitte pattern!)
Hero (esilehel, 1 koht) langeb kategooriasse 4 → Page sisuks. Päevaselge – pärast.
Figma – kus mis elab?
Kasutasime maatriksit kõigil 8 lehel. Mõni huvitavam tulemus:
Hero vs PageHero
Figmas on tegelikult kaks heroʼd: suur Hero (esilehel, pildiga, 2 nuppu) ja väike PageHero (Teenused/Meist/Kontakt/Blogi/Privaatsus – ainult H1 ja alapealkiri). Esimene on ühekordne → Page sisu. Teine on 5+ kasutusega, erineva tekstiga → Pattern + Detach.
Featured Services, Team Grid, Blog Preview
Need on Query Loop’i patternid. Featured Services näitab CPT entry’sid, kus featured = true. Team Grid näitab kõiki meeskonnaliikmeid. Blog Preview näitab viimast 3 postitust. Andmed tulevad CPT-st / Posts-ist, mitte staatilisest markup’ist.
Mis ei ole pattern
- Story tekst Meist lehel – ainulaadne, klient kirjutab → Page sisu
- Contact info (e-mail, telefon) – ainulaadne, klient muudab → Page sisu
- Privacy content (7 sektsiooni) – ainulaadne, juriidiline tekst → Page sisu
Reegel: kui see on see konkreetne tekst sellel lehel, mitte mall – ei ole pattern.
Lõksud, kuhu astusime
Localize Text Create Block Theme’is
Create Block Theme plugin pakub valikut “Localize Text” eksportimisel. See kõlab hästi – automaatne i18n lisamine. Aga reaalsuses: plugin liigutab terve templaadi sisu patterni faili (et PHP-funktsioonid nagu esc_html_e() töötaks), ja jätab template’i õhukeseks pattern-viiteks (<!-- wp:pattern -->). Tagajärg: template ei ole enam inline-toimetatav.
Reegel: kui tahad template’i Site Editor’is inline-toimetatav, ÄRA linnuta “Localize Text”. Aktsepteeri, et template ei ole i18n-itud. Page-põhise saidi puhul (üks keel) ei ole see kaotus.
Localize Images katkine URL
Sama plugin’i “Localize Images” valik genereerib pildi URL’iks assets/images/<pildinimi>.jpg, aga ei loo kausta ega kopeeri pilti tegelikult (vähemalt selle versiooniga). Tulemus: katkine URL.
Lahendus: kasuta otse /wp-content/uploads/... URL’i (klient saab media library kaudu asendada), VÕI kopeeri pilt käsitsi assets/images/-i.
Pattern cache
WordPress kasutab pattern’idele cache’i (WP_Theme::get_block_patterns()). Kui lisad uue PHP faili kausta patterns/, WP võib seda mitte näha, kuni cache flushid:
ddev exec wp eval-file wp-content/themes/fse-theme/flush-pattern-cache.php
flush-pattern-cache.php sisu (asub teema juurkaustas):
<?php
$theme = wp_get_theme();
$theme->delete_pattern_cache();
_register_theme_block_patterns();
echo "Pattern cache flushed.\n";
Boonusõppetund: semantiline HTML FSE-s
Veebistandardite ja screen reader’ite jaoks tahaks puhast struktuuri:
<header>...</header>
<main>
<section>...</section>
</main>
<footer>...</footer>
Group block rendib vaikimisi <div>. Et saada semantilised tag’id, kasuta tagName atribuuti:
<!-- wp:template-part {"slug":"header","tagName":"header"} /-->
<!-- wp:group {"tagName":"main"} -->
<main class="wp-block-group">
<!-- wp:post-content {"align":"full"} /-->
</main>
<!-- /wp:group -->
<!-- wp:template-part {"slug":"footer","tagName":"footer"} /-->
WordPress lisab paratamatult kaks div-wrapper’it (.wp-site-blocks ja .entry-content), mida ei tasu eemaldada – eemaldamine vajab fragile output-buffering hack’i, mis WP-update’iga katki läheb. Aktsepteerime need ja keskendume sellele, et semantiline puu (header/main/section/footer) on õigetes kohtades. See on, mida loevad nii screen reader’id kui Google.
Kokkuvõte
FSE filosoofia ühe lauses: anna kliendile võimalikult palju Page-vaate kaudu hallatavat sisu; jäta teema-koodi ainult see, mis on tõeliselt korduv (template part) või dünaamiline mall (pattern).
Praktilised reeglid, mis jäid külge:
- 1 koht = ei vaja pattern’it. Hero esilehel → Page sisu.
- Klient muudab Page’is, mitte template’is. Anna Page’i nii palju, kui võimalik.
- Localize Text VÄLJAS, kui tahad template’i inline-toimetatavaks.
- Pattern cache flush uue pattern faili lisamisel.
- Semantiline HTML Group block’i
tagNameatribuudiga, aktsepteeri WP-core div-id.
Täielik dokument koos lehe-haaval analüüsi ja failistruktuuriga elab repositories: project/fse-filosoofia.md. See on minu (ja Claude’i) otsuste vundament järgmistele sammudele.
Järgmises postituses asume Avaleht Page’i ehitama ja PageHero patternit koostama. Vundament on käes – nüüd lehed.
Praktiline lisa (#5 ja #6 järelmõte): millal kasutada pattern’it, millal mitte
Pärast Projektipäevik #5 ja #6 ehitamist on selge: filosoofia on alus, aga otsus “kas see ON pattern” tuleb teha **iga elemendi kohta eraldi**. Lisan siia kolm asja, mida tahaksin olla algusest peale teadnud.
1. Kontrast-tabel: mis elemendid Figmas kuuluvad kuhu
| Element | Kasutuskohad | Sisu | Otsus |
|---|---|---|---|
| Hero (esileht) | 1 (avaleht) | unikaalne | Avaleht Page’i sisu – MITTE pattern |
| PageHero | 5 (Meist, Kontakt, Privaatsus, Teenused-arhiiv, Blogi) | varieerub iga lehe järgi | Pattern + post-title/post-excerpt (dünaamiline) |
| Header | KÕIKIDEL lehtedel | sama | Template part (parts/header.html) |
| Footer | KÕIKIDEL lehtedel | sama | Template part (parts/footer.html) |
| Service card | Teenused-arhiiv + Avalehe Featured | sama struktuur, andmed CPT-st | Pattern Query Loop’i sees + Service CPT + ACF |
| Team card | Meist-lehe Meeskond | sama struktuur, andmed CPT-st | Pattern Query Loop’i sees + Team CPT + ACF |
| Blog card | Blogi-listing + Single-postituse “Related” | sama struktuur, andmed wp_posts’ist | Pattern Query Loop’i sees (built-in posts) |
| FAQ section | Teenuse single-leht | unikaalne sisu | Service single-template’is – MITTE pattern |
| Final CTA | Esileht + Teenuse single + (potentsiaalselt rohkemgi) | sama tekst kõikjal | Pattern reference |
| Filters (Blogi listing) | 1 (Blogi listing) | unikaalne | Template sees – MITTE pattern |
Märkad mustrit: 3+ kasutuskohta + struktuuriline taaskasutus = pattern. 1 koht = ALATI Page sisu või template-sisu. 2 kohta on piiripealne – sõltub, kas sisu varieerub.
2. Viis antimustrit (mida MITTE teha)
❌ “Iga komponent on pattern”: Avaleht Hero kahjustab klienti, kes tahab muuta teksti. Pattern on PHP-failis lukus – vaja arendajat ja git-commit’i.
❌ “Pattern lihtsuse pärast”: Kui klient küsib “kuhu muuta teksti”, ja vastad “ava VS Code, leia patterns/hero-home.php” – vale arhitektuur. Klient peab toimetama UI-st.
❌ “Pattern selleks, et oleks Git’is”: Page/Post sisu IS andmebaasis ja seda saab eksportida (näiteks wp post update või WXR-eksport). Ei pea sundima patternisse, et “kood Git’is”.
❌ “Loon mitu väikest pattern’it suurte asemel”: Card-Icon + Card-Title + Card-Excerpt eraldi pattern’idena → halduskulu kasvab, taaskasutuse väärtus ei lisandu. Eelista ühte korralikku Card-pattern’it.
❌ “Pattern, aga inline’itud template’is”: Site Editor’s pattern’i lisamine template’i inline’b markup’i (kui pattern pole synced). Template’i fail sisaldab kogu pattern’i markup’i, mitte reference’it. Tulemus: pattern’i muutused EI propageeru template’i (vt #6 Lõks 6). Lahendus: kirjuta käsitsi <!-- wp:pattern slug --> markup’is.
3. Neli küsimust enne uue pattern’i loomist
- Mitu kasutuskohta? 1 → MITTE pattern (Page/Post sisu). 2+ → võibolla.
- Kas sisu varieerub kasutuskohas?
- Jah, struktuuriliselt sama, andmed varieeruvad → pattern + post-data blokid (post-title, post-excerpt)
- Jah, ka struktuur võib varieeruda → mitu pattern variantsiooni VÕI inline igas kohas
- Ei, kõikjal sama → pattern reference
- Kas klient muudab teksti?
- Jah → Page sisu VÕI post-data sees (Page Title, Page Excerpt jne)
- Ei (staatiline brand-tekst) → pattern PHP-failis OK
- Kas template-sisene kasutus on võimalik?
- Jah, ainult 1 template’s → otse template sees, mitte pattern
- Jah, mitu template’s + Page’is võimalik → pattern reference
Kõik need õppetunnid on detailselt talletatud project/casestudy.md Case 13-s.
Järgmine etapp: CPT + ACF setup (Service, Team), pluss Avaleht Page sisu ehitamine. Pattern’imuusika hakkab tõsiselt mängima, kui meil on Query Loop’iga dünaamilist sisu päringult.