Projektipäevik #6: Blog Home template – 6 lõksu Query Loop’iga

Sissejuhatus

Eelmises postituses ehitasime PageHero pattern’i – H1 + alapealkiri tsentrissa, dünaamiline post-title + post-excerpt. Aeg anda sellele esimene päris kasutuskoht: blogilisting.

Eesmärk: templates/home.html – WP template hierarchy järgi blogilistingu jaoks (kui pole, kasutab index.html fallback’ina). Sisaldama PageHero pattern reference + 3-veeruline grid kaartidega + pagination.

Ehitamine läks pisut põnevamalt kui ootasime – tabasime 6 lõksu. Igaüks neist on tüüpiline WP FSE arendamise kogemus.

Esimene samm: Add new template → Blog Home

Site Editor → Templates → vajutame “+” → ilmub dialoog. WP pakub valida, millise template-tüübi jaoks loome:

  • Blog Home ← see ongi home.html
  • Single Posts
  • All Archives
  • Author Archives

“Blog Home” valime – WP teab, et see vastab page_for_posts seades olevale lehele. Praktikas: kui Settings → Reading → Posts page = “Blogi”, siis selle lehe frontend rendib home.html.

Query Loop variant: “Image, Date, & Title”

Tühjas template’is lisame Query Loop’i. WP küsib esimese asjana “Choose a pattern for the query loop or start blank”, siis variandi:

  • Title & Date
  • Title & Excerpt
  • Title, Date, & Excerpt
  • Image, Date, & Title ← see Figma-kaardi struktuuri lähedasem

Valime Image-i, lisame ise Excerpt’i. Mitte ühtegi variandi ei ole täpne, aga see annab kõige rohkem blokke (3/5 vajalikust).

Lõks #1: “Inherit query from template” on nüüd “Query Type: Default”

Otsisin sidebar’s “Inherit query from template” toggle’it. Polnud kuskil. WP 6.x-s see seade nimetati ümber:

OLI:  Inherit query from template  [toggle ON/OFF]
ON:   Query Type  [Default | Custom]
  • Default = päri template’ist (= inherit ON) ✅ vaikimisi õige
  • Custom = oma päring (post-type, perPage, taxQuery)

Niisiis vaikimisi on juba korras – pole vaja midagi muuta. Aga **otsing võtab aega**, kui sa otsid vana sõnastust.

Lõks #2: Grid layout on Post Template’is, mitte Query Loop’s

Tahame 3-veerulist grid’i. Query Loop sidebar’s näeme “Layout” sektsiooni: Inner blocks use content width, Content width, Wide width, Justification. Aga **kus Grid valik?**

Vastus: Grid layout pole Query Loop bloki seade, vaid Post Template bloki seade (Query Loop SEES). Niisiis:

  • List View → ava Query Loop → vali Post Template
  • Post Template’i toolbar’s (üleval) on kaks layout ikooni: Stack (vertikaalne) ja Grid
  • Vali Grid → sidebar’s ilmub “Columns” → vali 3

Pärast: kaardid hakkavad 3 veergu paigutuma. Mobile’l läheb automaatselt 1 veerg, sest WP Grid layout on responsive.

Lõks #3: 720px-laius on liiga kitsas – vajame wide width

Kaardid paigutusid 3 veergu, aga grid oli kogu sisu-laiuses ~720px (theme.json contentSize). 3 kaardi jagu 720px = ~230px iga, **liiga kitsas**.

Figma desktop: viewport 1440px, paddings 64px mõlemal pool → sisu 1312px. See vastab theme.json’i wideSize: 1312px.

Lahendus: align:"wide" Query Loop’ile (või Post Template’ile – mõlemad toimivad sarnaselt). Toolbar’s align ikoon → “Wide width”.

Pärast: Query Loop laieneb 1312px-ni, 3 kaarti jagu (umbes 420px iga + gap). Mahuvad ilusti.

NB! Ära muuda theme.json contentSize väärtust laiemaks. Tekst peaks jääma kitsamana loetavuse huvides (max ~80 tähemärki rea kohta = ~720px). contentSize = tekstid; wideSize = grid’id, banner’id.

Lõks #4: Read More duplikaat

Lisasime Post Template’i Post Excerpt’i järele Read More bloki (“Loe edasi” tekstiga). Frontend’s nägi kaart välja nii:

[pilt]
May 22, 2026
Projektipäevik #4: FSE filosoofia...
Aha-hetk Hero'ga: 1 kasutus pole pattern...
Read more       ← Post Excerpt'i sisene automaatne link
Loe edasi       ← meie eraldi Read More blokk

Kaks “Read More” elementi. Põhjus:

  • Post Excerpt blokk lisab vaikimisi automaatse “Read more” lingi excerpt’i järele
  • Meie lisasime VEEL ühe eraldi Read More bloki

Lahendus: kustuta eraldi Read More blokk, kasuta Post Excerpt’i sisemise lingi atribuuti:

<!-- wp:post-excerpt {"moreText":"Loe edasi"} /-->

Reegel: kui sama elementi annab teha kahel viisil (eraldi blokk vs atribuut), eelista atribuuti. Vähem blokke, lihtsam markup.

Lõks #5: WCAG heading hierarhia – Post Title peab olema H2

Mu esimene soovitus oli Post Title H3. Aga klient märkas kohe: “See ei tohiks H3 olla, kuna lehel on H1 ja vahepeal H2 ei ole.”

Õigus. WCAG 2.1 reegel: heading-leveleid ei tohi vahele jätta. H1 → H3 (H2 puudub) on viga. Screen reader’id ja Google tõlgendavad valesti.

Lehel:

  • H1: “Projektipäevik” (PageHero)
  • H2: postituse pealkiri (kaardid otse H1 all → H2-tase, mitte H3)

Kui meil oleks vahepeal H2 sektsioonid (“Featured posts”, “Latest”), siis kaardid sees võiksid olla H3. Aga praegu pole – niisiis kõik kaardid on H2.

Lõks #6 (suurim): Pattern ja Template-Part inline’imine

CBT eksport tegi home.html faili. Avasin selle ja vaatasin – ja **plahvatasin**. Faili sees oli kõik järgnev inline’itud:

  • Header (15 rida “Simple header with tagline” core-pattern’i markup’i otse failis)
  • PageHero (5 rida Group + post-title + post-excerpt otse failis)

Mitte ükski neist polnud reference. Iga muudatus parts/header.html-s või patterns/page-hero.php-s EI kajastu home.html-l. Kogu pattern-filosoofia idee – tsentraliseeritud muudatused – on katki.

Miks see juhtub? Site Editor’s pattern’i lisamisel inline’b ta blokid template’i sisse (vaikimisi non-synced pattern’itega). See on WP-i mudel:

  • Synced patterns = jagatud sisu, kõik kasutuskohad sünkis → reference säilib
  • Non-synced patterns = struktuuriline mall, sisu varieerub kasutuskohas → inline’itakse

Aga template’is ME EI TAHA inline’imist. Me tahame dünaamilist taaskasutust – kui PageHero pattern muutub, peab muutus kajastuma kõikjal.

Lahendus: kirjutame pattern reference’i ja template-part reference’i KÄSITSI markup’i:

<!-- wp:template-part {"slug":"header","tagName":"header"} /-->

<!-- wp:group {"tagName":"main","layout":{"type":"constrained"}} -->
<main class="wp-block-group">
    <!-- wp:pattern {"slug":"fse-theme/page-hero"} /-->

    <!-- wp:query {"query":{"inherit":true,...},"align":"wide","layout":{"type":"constrained"}} -->
    <div class="wp-block-query alignwide">
        <!-- wp:post-template {"layout":{"type":"grid","columnCount":3}} -->
            <!-- wp:post-featured-image {"isLink":true,"aspectRatio":"16/9"} /-->
            <!-- wp:post-date /-->
            <!-- wp:post-title {"level":2,"isLink":true} /-->
            <!-- wp:post-excerpt {"moreText":"Loe edasi"} /-->
        <!-- /wp:post-template -->

        <!-- wp:query-pagination -->
            <!-- wp:query-pagination-previous /-->
            <!-- wp:query-pagination-numbers /-->
            <!-- wp:query-pagination-next /-->
        <!-- /wp:query-pagination -->
    </div>
    <!-- /wp:query -->
</main>
<!-- /wp:group -->

<!-- wp:template-part {"slug":"footer","tagName":"footer"} /-->

Kaks võtmerada:

  • <!-- wp:template-part {"slug":"header"} /--> – Header tuleb parts/header.html-st
  • <!-- wp:pattern {"slug":"fse-theme/page-hero"} /--> – PageHero tuleb patterns/page-hero.php-st

WP loeb need igal page-render’il, leiab vastava faili, ja renderdab selle sisu. Muudatused propageeruvad automaatselt.

Boonus: “Author” indikaator Templates vaates

Site Editor’s Templates kaardivaates iga eelvaate all on “Author” väli. Selle väärtus paljastab:

  • Teema nimi (nt “FSE Theme”) → template on koodis (templates/*.html, Git’is, deploy’iv)
  • Kasutaja nimi (admin, juhokalberg) → template on ainult andmebaasis (wp_posts, ei lähe Git’i)

Praktiline tagajärg:

  • Author = kasutaja nimi → tee CBT eksport, et liiguks Git’i
  • Author = teema nimi → kõik korras

Sama loogika kehtib Template Parts’idele ja Patterns’idele.

Boonus: “Posts Page” notice tähendus

Kui avada admin’s Page’i, mis on määratud page_for_posts-iks (näiteks Projektipäevik / Blogi), näeb teavitust:

You are currently editing the page that shows your latest posts.

See tähendab: Frontend’s selle Page sisu EI rendita – selle asemel home.html template. Aga Page’i title ja excerpt ON KASUTUSEL (PageHero pattern loeb need).

Niisiis Page’is olev sisu pole oluline. Tähtsaim: Page Title (“Projektipäevik”) ja Excerpt (“Mõtted, õppetunnid ja juhendid.”) on korras.

functions.php täiendus: Page Excerpt UI

Aga väike lõks selles töös: kui üritasin Blogi Page’ile Excerpt-välja sisestada (kirjeldus “Mõtted, õppetunnid ja juhendid.”), siis Site Editor’i ja klassikalise Block Editor’i sidebar’s Excerpt-paneeli polnud üldse näha.

Põhjus: WordPress’i vaikimisi Pages’idel pole Excerpt-välja UI-d. Andmebaasi veerg post_excerpt on olemas, aga UI on peidetud. Vajalik lisada teema-toetus:

Mida lisada functions.php-sse

Olemasolevasse fse_theme_setup() funktsiooni lisa üks rida:

add_post_type_support( 'page', 'excerpt' );

Pärast lisamist – salvesta. Ava klassikaline Pages → Blogi → Edit. Parem sidebar peaks nüüd näitama Excerpt-paneeli. Kui ei näe, ⋮ → Preferences → Panels → Excerpt → SISSE.

Terve functions.php pärast seda etappi

Versioon 2 – ainus muudatus võrreldes versiooniga 1 (#3 lõpus) on add_post_type_support( 'page', 'excerpt' ) rida fse_theme_setup() funktsioonis:

<?php
/**
 * fse-theme functions.php
 *
 * Theme support + block styles + pattern categories + page excerpt UI.
 */

if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

/**
 * Theme support deklaratsioonid.
 */
function fse_theme_setup() {
    add_theme_support( 'post-thumbnails' );

    add_theme_support( 'html5', [
        'search-form',
        'comment-form',
        'comment-list',
        'gallery',
        'caption',
        'style',
        'script',
    ] );

    add_theme_support( 'wp-block-styles' );

    // UUS: Page Excerpt UI sisselülitamine.
    add_post_type_support( 'page', 'excerpt' );
}
add_action( 'after_setup_theme', 'fse_theme_setup' );

/**
 * Block style: Secondary Button.
 */
function fse_theme_register_block_styles() {
    register_block_style( 'core/button', [
        'name'  => 'secondary',
        'label' => __( 'Secondary', 'fse-theme' ),
    ] );
}
add_action( 'init', 'fse_theme_register_block_styles' );

/**
 * Pattern kategooriad.
 */
function fse_theme_register_pattern_categories() {
    register_block_pattern_category( 'fse-theme-hero', [
        'label' => __( 'FSE Theme – Hero', 'fse-theme' ),
    ] );

    register_block_pattern_category( 'fse-theme-card', [
        'label' => __( 'FSE Theme – Cards', 'fse-theme' ),
    ] );

    register_block_pattern_category( 'fse-theme-section', [
        'label' => __( 'FSE Theme – Sections', 'fse-theme' ),
    ] );
}
add_action( 'init', 'fse_theme_register_pattern_categories' );

Õppetundide kokkuvõte

  • WP 6.x ümberkirjutamised: “Inherit query” → “Query Type: Default”. Otsing võtab aega.
  • Grid layout on Post Template’is, mitte Query Loop’s. Toolbar’s Stack ↔ Grid valik.
  • Wide width (1312px) grid’idele, contentSize (720px) tekstidele. Ära ühista neid.
  • Read More duplikaat: Post Excerpt’il on sisene link – kasuta atribuuti moreText:"Loe edasi", ära lisa eraldi Read More blokki.
  • Heading hierarhia (WCAG): H1 → H2 → H3. Ei tohi vahele jätta. Post Title kaartides = H2.
  • Site Editor inline’b non-synced pattern’eid template’isse. Pattern reference (<!-- wp:pattern slug -->) tuleb käsitsi markup’i kirjutada.
  • Template-part reference alati: header/footer mitte kunagi inline.
  • Author indikaator Site Editor’s näitab, kus element elab (Git vs DB).
  • Posts Page notice on kasulik teavitus: Page sisu ei rendita, aga title + excerpt loetakse.

Kõik 6 lõksu + boonused on detailselt dokumenteeritud project/casestudy.md Case 11–12-s. Järgmistele arendajatele soovitan: pärast CBT-eksporti loe template fail HARLIKULT üle. Lihtne checklist:

  • Header – template-part reference?
  • Footer – olemas?
  • Pattern reference (mitte inline)?
  • Main wrapper sisaldab kõike content’i?
  • Read More duplikaat puudub?
  • align width on Query Loop / Post Template’il?