Szekciók, blokkok és elemstílusok
Hozz létre témaszekciókat és -blokkokat a defineSection és defineBlock segítségével, adj hozzájuk beállításokat és stílusfunkciókat, és regisztráld őket a webáruházhoz és a témaszerkesztőhöz.
Ezen az oldalon
Minden szekciót és blokkot, amelyet egy téma hozzáad, egyszer deklarálsz, TSX-ben, közvetlenül a komponense mellett.
Egyetlen defineSection({...}) vagy defineBlock({...}) objektum tartalmazza a típuskulcsot, a választó
címkéjét és ikonját, az inspector beállításait, az elfogadott gyermekelemeket, a stílusfunkciókat és
a komponenst. A téma fordítója ezeket az objektumokat kód futtatása nélkül olvassa be, és ebből buildeli fel
a témaszerkesztő katalógusát, a kódszerkesztő elrendezéshez használt JSON Schema-ját és a közzétételi ellenőrzéseket.
Nincs külön manifest.
Az elrendezés és a tartalom a kód mellett, JSON-ban marad: pages/*.json, pages/custom/*.json,
layout/*.json és settings/values.json. A témaszerkesztő és a kódszerkesztő ugyanazokat a
fájlokat módosítja. A témaszerkesztő soha nem módosítja a theme.json fájlt.
Egy szekció
import { EditableText, Slot, defineBlock, defineSection, field } from '@poltura/theme-sdk/elements';
import { cn } from '@poltura/theme-sdk/ui';
export const wallQuote = defineBlock({
type: 'wall-quote',
label: 'Quote',
icon: 'quote',
category: 'content',
settings: {
quote: field.textarea({ label: 'Quote', default: 'Best purchase this year.' }),
author: field.text({ label: 'Author' }),
},
style: ['typography', 'color', 'spacing'],
component: ({ settings }) => (
<figure>
<EditableText setting='quote' as='blockquote' className='text-lg' />
{settings.author ? <figcaption>{settings.author}</figcaption> : null}
</figure>
),
});
export const quoteWall = defineSection({
type: 'quote-wall',
label: 'Quote wall',
description: 'Customer quotes in a grid',
icon: 'quote',
category: 'marketing',
templates: ['home', 'page'],
settings: {
heading: field.text({ label: 'Heading', default: 'What customers say' }),
columns: field.range({ label: 'Columns', min: 1, max: 4, default: 3 }),
},
blocks: { accepts: [wallQuote], max: 12 },
style: ['spacing', 'background', 'visibility'],
component: ({ attrs }) => (
<section {...attrs} className={cn(attrs.className, 'theme-container py-14')}>
<EditableText setting='heading' as='h2' className='mb-8 text-3xl font-semibold' />
<Slot className='grid gap-6 md:grid-cols-3' />
</section>
),
});- A
typeaz a kulcs, amelyet az elrendezés JSON használ. A kulcsok témánként egyediek; egy platformkulcs (hero,heading,button,link-list…) újbóli használata mindenhol felülírja a platformelemet. - A
settingsegy objektumkonstans. A kulcsai a setting ID-k, a sorrendje az inspector sorrendjét követi, a komponenssettingspropja pedig ebből kap típust az alapértelmezett értékek alkalmazásával és a vásárló nyelvének feloldásával. Minden komponens megkapja a{ settings, attrs, id }objektumot. A definíción kívül megírt komponens, amely egyconst-ban tartott setting objectre épül,ElementProps<typeof schema>típust kap. - A
blocks.acceptsfelsorolja a gyermekelemek típusait: importált definíciókat, típuskulcsokat vagy egy helyettesítő karaktert (lásd alább). Ablocks.maxkorlátozza a darabszámot. - A
templatestemplate ID-kra (home,product,collection,page, …) korlátozza a szekciót. Hagyd el, ha a szekciót mindenhol elérhetővé tennéd. - A
slots: [{ name: 'media', label: 'Media' }, …]nevesített régiókat deklarál; mindegyiket a<Slot name='media' />segítségével jelenítheted meg. - Egy
defineSectionkomponensnek kötelező azattrsobjektumot átadnia (spread) egyetlen root node-nak. Ez a node hordozza az element ID-t, amelyet a témaszerkesztő kiválaszt, a kereskedő horgonyát (anchor) és a kereskedő Stílus fülének scope-ra korlátozott CSS-ét. A scope-ra korlátozott CSS egy olyan class-t céloz, amelyet a spread azattrs.classNamemezőben hoz be, így a node saját class-ai a@poltura/theme-sdk/uicsomagból származócn(attrs.className, 'py-14')segítségével fésülhetők össze vele. Egy egyszerűclassName='py-14'a spread után felülírja ezt a class-t: a kereskedő térközei, háttere és láthatósága ekkor hatástalanná válnak, és a témaellenőrzés ezt hibaként jelzi. - Egy blokknak nincs szüksége semmire a root elementjén: a platform minden blokkot a saját keretén (frame) belül rajzol ki, egy
div-ben (vagy ali, illetvespanelemben, amelyet aframemegnevez), amely magában foglalja a szerkesztő horgonyát, az oldalon belüli horgonyt és a kereskedő stílusát, a blokknak pedig egy üresattrsértéket ad át. A kereskedők külön fejlesztői ráfordítás nélkül bármelyik blokkot újrastílusozhatják. - A
context: { requires: ['product'] }deklarálja, hogy egy blokk a legközelebbi termék adatait olvassa (useNearestProducta@poltura/theme-sdk/productcsomagból); aprovidesdeklarálja azokat a scope-okat, amelyeket egy elem a gyermekei számára megnyit. A terméksablon, minden termékkártya és aProductScopeproduct scope-ot nyit. A gyűjtemény-, kategória- és minden terméket felsoroló oldalak collection scope-ot nyitnak, amelynek listázási adatait auseListingolvassa a@poltura/theme-sdk/listingcsomagból. A témaszerkesztő visszautasítja az olyan blokkot, amely olyan helyen kér scope-ot, ahol az nem elérhető. - A
presetsnevesített kiindulási konfigurációk (beállítások, stílus, gyermekelemek). Csak adefaultazonosítójú preset kerül alkalmazásra, amikor a kereskedő beszúrja az egyszerű elemet. Minden más preset saját csempeként jelenik meg a választóban közvetlenül az elem után,Element (Preset)címkével. Annak a presetnek, amellyel egy containernek indulnia kell, add adefaultnevet, különben üres marad. - A
keywords: ['kosárba', 'ATC']keresési kifejezéseket ad a választóhoz. Szekcióknál agroups: ['header']a fejléc- vagy lábléc-csoportban kínálja fel a szekciót, alimit: 1pedig sablononként vagy csoportonként korlátozza a példányainak számát.
Mit jelent a „statikus”?
A fordító a component kivételével mindent kiértékel anélkül, hogy futtatná a kódot. Engedélyezett: literálok,
field.* hívások literál argumentumokkal, field.group('Label') és field.note('…'),
hivatkozások ugyanazon fájlban lévő const literálokra, valamint importált definíciók az accepts mezőben.
Minden más (függvényhívás, másik modulból származó spread, számított kulcs) schema
hibát eredményez a témaellenőrzésben és a kódszerkesztőben a forrásbeli pozíció megjelölésével. A component lehet helyi
függvény vagy inline arrow function, és egyetlen komponens több típust is kiszolgálhat.
Szekcióhoz tartozó blokkok
Minden blokk rendelkezik component értékkel, és egy régión keresztül rajzolja ki magát. A témaellenőrzés
accepted-without-component hibát jelez az olyan elfogadott blocknál, amely nem rendelkezik ilyennel. Az a blokk, amelyet név szerint csak egyetlen szekció
fogad el, ahhoz a szekcióhoz tartozik: a választó csak ott kínálja fel és sehol máshol, mint
például az alapértelmezett téma GYIK osztott kérdései és a megamenü oszlopai esetében.
Mezőkészítők (field builders)
A field a @poltura/theme-sdk/elements csomagból érkezik. Minden builder fogadja a label paramétert, és opcionálisan a következőket:
description, placeholder, visibleIf: { field, value }, translatable, content,
renamedFrom és purpose (egy egysoros leírás arról, mit fejez ki az érték, eligazítást adva a szövegírónak).
A legtöbb builder elfogad default értéket is; a video és a katalógusválasztók (product, collection és
hasonlók) nem. A text, textarea és richtext mezők a maxLength értéket is fogadják, amely a dizájn által megengedett maximális karakterszám.
A select és a radio a renamedValues: { old: 'new' } beállítást is fogadja: ha átnevezel egy opcióértéket, az az áruház, amely a régit mentette, az új értéken megtartja a választását. Az értéket átnevező frissítés előbb a kereskedőt kérdezi, azt pedig, amelyik átnevezés nélkül hagy el egy opciót, nem lehet közzétenni.
| Builder | Érték |
|---|---|
text, textarea, richtext | string, alapértelmezetten fordítható |
number, range (min, max, step, unit) | number |
checkbox | boolean |
select, radio (options; a radio kaphat icon-t) | az opcióértékek uniója |
color (darkDefault hozzáadja: <id>_dark), gradient | string |
image | egy media:// vagy asset:// hivatkozás |
url | bolton belüli útvonal vagy abszolút URL |
video | egy forrás, vagy { src, poster?, autoplay?, loop?, muted?, alt? } |
link (withLabel) | { href, new_tab?, rel?, label? } |
font | CSS fontkészlet (font stack) |
linkList | linkek opcionális gyermekelemekkel |
product, collection, category | egyetlen azonosító |
products | azonosítók tömbje |
collectionList (max, alapértelmezetten 12) | { kind: 'collection' | 'category', handle }[] a kereskedő sorrendjében |
page | tartalmi oldal útvonala (pl. /about); a usePage olvassa |
post | { kind: 'post' | 'guide', slug }; a usePost olvassa |
menu | egy menü handle-je, amelyet a useMenu olvas |
menuItem | annak a menünek az egyik legfelső szintű link ID-ja, amelyben az elem található |
list (fields, min, max, alapértelmezetten 24 sor) | a sorok beállításai sorrendben |
colorScheme | a téma egy nevesített színsémája; ha üres, megtartja a szülőét, a useColorScheme olvassa |
colorSchemeGroup | a téma színsémái témabeállításként |
partnerBadges | { order, hidden } jelvénykulcsok |
icon | egy Lucide ikonnév vagy feltöltött SVG |
datetime | ISO 8601 string időeltolódással (offset), vagy üres |
copy (key) | nincs: egy szöveget szerkeszt a texts/ alatt |
group('Label'), note('Text') | nincs: inspector címsor és súgószöveg |
variable | csak e-mail: az e-mail egyik változójának neve |
keyValues | csak e-mail: fordított címke és változóérték sorai |
steps | csak e-mail: számozott sorok fordított címmel és leírással |
links | csak e-mail: fordított hivatkozásszöveg és a címet tároló változó sorai |
html | csak e-mail: HTML változatlan formában elküldve |
promotion | csak e-mail: egy kóddal rendelkező bolti promóció azonosítója |
A modulban található fieldSet olyan beállításokat csoportosít, amelyeken több elem osztozik, mint például egy gomb
címkéje és linkje: a készlet előtaggal történő meghívása <prefix>_<key> formában illeszti be a mezőit a schemába.
A defineThemeSettings a témabeállítások paneljét deklarálja az src/settings.ts fájlban ugyanezen field.* builderek használatával.
Egy icon beállítás a teljes Lucide készletből választ (shopping-bag,
truck), vagy a kereskedő által feltöltött, megtisztított és beágyazottan tárolt SVG-t tartalmaz. Rajzold ki
a @poltura/theme-sdk/ui csomagból származó <Icon value={settings.icon} /> komponenssel: a webáruház csak azokat az
ikonokat ágyazza be, amelyeket az oldal ténylegesen használ, így nem kerül felesleges ikonkönyvtár a böngészőbe.
A partnerBadges beállítás a bolt aktív feedjeinek jelvényeit tárolja
{ order: [...], hidden: [...] } formában: minden aktív jelvény megjelenik, amely nem szerepel a hidden listában; először az order-ben lévő kulcsok,
a többi pedig a feedek közzétételi sorrendjében, így a később élesedő jelvény magától megjelenik.
A szüneteltetett feedek kulcsai megmaradnak az értékben arra az esetre, ha újra aktívvá válnának.
A datetime beállítás naptárral és a bolt órája szerinti időponttal választható ki, és az
eltolódásával együtt kerül tárolásra (2026-12-31T23:59:00+01:00). A @poltura/theme-sdk/content csomagból származó useCountdown ugyanúgy olvassa be,
ahogyan a platform visszaszámlálója: a puszta dátum éjfélkor indul, az eltolódás nélküli időpont pedig
a bolt órája szerint kerül értelmezésre, mindkettő a bolt időzónájában.
A link beállítás a bolt oldalai, termékei, gyűjteményei, kategóriái és űrlapjai közül választható ki,
vagy címként gépelhető be, új lapos kapcsolóval, más oldalak esetén pedig nofollow és sponsored értékekkel.
A default a kezdő href (field.link({ label: 'Link', default: '/products' })), az elrendezési fájlban lévő
egyszerű string pedig href-ként értelmeződik. Add át az értéket a @poltura/theme-sdk/routing csomag Link komponensének,
amely ellenőrzi a href-et, alkalmazza az új lapot és a rel attribútumot, új lap esetén pedig hozzáadja a
noopener noreferrer értéket:
<Link href={settings.cta} className='pol-cta' />A withLabel: true a link látható szövegét is kéri, amelyet label néven tárol; a Link ezt jeleníti meg,
ha nem foglal magában semmit. Ez a szöveg nyelvenként külön fordítható, míg a href, a lap és a rel
minden nyelven ugyanaz marad.
A richtext beállítás egy eszköztárral szerkeszthető (félkövér, dőlt, linkek akár új lapon megnyitva,
pontozott és számozott listák, 3-as és 4-es szintű címsorok; Cmd/Ctrl+B, I és K), és egyszerű formázást tartalmazó
szövegként tárolódik, soha nem HTML-ként: **bold**, *italic*, [label](/path),
[label](https://…){target=_blank}, - item, 1. item, ### Heading, #### Subheading, és
üres sor a bekezdések között. Megjelenítéséhez használd az EditableRichText komponenst a
@poltura/theme-sdk/elements csomagból, amely kirajzolja a szöveget, és lehetővé teszi a kereskedőknek, hogy a vásznon szerkesszék. A formázott szövegként érkező bolti szövegek, például a termékleírások rendereléséhez
használd a RichText komponenst a @poltura/theme-sdk/content csomagból.
A font beállítás egy CSS fontkészletet tárol a betűtípus-választóból, például:
ui-serif, Georgia, Cambria, serif; alkalmazd a style={{ fontFamily: settings.font }} formában. A
rendszerkészletek mindig renderelődnek; a webes betűtípus akkor jelenik meg, ha a téma betöltötte. A number és a range
egy mértékegységet (unit: px, %, em, rem, vh, vw, ms, s, deg) is elfogad, amely az érték mellett jelenik meg; a
tárolt érték egyszerű szám marad.
A video beállítás YouTube- vagy Vimeo-linket, illetve a kereskedő által feltöltött, legfeljebb 20 MB-os
MP4- vagy WebM-fájlt fogad el borítóképpel, lejátszási beállításokkal (automatikus lejátszás, ismétlés, némítás) és szöveges alternatívával.
A @poltura/theme-sdk/media csomagból származó useVideoSetting feloldja ezt a megjelenítendő fájlra vagy lejátszóra.
A text, textarea és richtext mezőkben lévő kereskedői szövegek lefordításra kerülnek a bolt
nyelveire (settings_i18n az elrendezési fájlban). A style értékei soha nem kerülnek lefordításra.
Az image, video, url és link beállítások minden nyelven közösek mindaddig, amíg a kereskedő valamelyik
nyelvnek nem ad meg egyedit (például egy magyar nyelvű bannert, egy /hu/… linket) a témaszerkesztő „Másik használata ehhez: …” funkciójával.
Ez az érték a lefordított szöveghez hasonlóan a settings_i18n[<locale>] alatt tárolódik, soha nem
kerül gépi fordításra, az „A(z) … használata” gombbal pedig törölhető, így a nyelv újra az alapértéken osztozik.
A settings prop már eleve a vásárló nyelvét tartalmazza, így az elemnek nincs szüksége semmi pluszra
a megfelelő kép megjelenítéséhez.
A kép- és videobeállítások a bolt médiatárát is felkínálják: a bolt adminfelületén keresztül feltöltött összes kép és videó elérhető, fájlnév szerint kereshető formában. A nem használt fájlok a választóból törölhetők.
Megjelenés és tartalom
Minden mező vagy megjelenés (look) – amelyet egy stíluspreset felülírhat –, vagy tartalom (content), amelyhez egy preset
soha nem nyúl hozzá. A színek, színátmenetek, betűtípusok, legördülő listák (select), választógombok (radio), számok, csúszkák és checkboxok a
megjelenéshez tartoznak; minden más tartalom. A content: true megtart egy olyan megjelenés típusú értéket, amely valójában a
kereskedő döntése, a content: false pedig a megjelenés részévé tesz egy tartalom típusú mezőt:
showReviews: field.checkbox({ label: 'Show reviews', default: true, content: true }),Az src/settings.ts fájlban található globális beállítások ugyanezt a content kulcsot fogadják; lásd:
Stíluspresetek.
Stílusfunkciók
A style felsorolja azokat a Stílus fülön megjelenő csoportokat, amelyeket egy elem kínál. Az inspector csak ezeket jeleníti meg, a
témaellenőrzés és a témaszerkesztő pedig hibát jelez az ezeken kívül eső tárolt stílusok esetén.
| Funkció | Vezérlők |
|---|---|
layout | elrendezés (display), irány (és fordított), törés (wrap), igazítás (justify, align), rés (gap), oszlopok, overflow |
align | az elem elhelyezkedése a siblingjei között: balra, középre vagy jobbra rendezés, nyújtás (grow), sorrend, rögzítés (sticky), z-index |
spacing | belső és külső margók (padding és margin) |
size | szélesség (beleértve a törtrészeket, pl. 1/3), maximális szélesség, minimális magasság, képarány |
media | hogyan illeszkedik az elem saját képe vagy videója a keretéhez, és annak fókuszpontja |
typography | méret, vastagság, igazítás, transzformáció, betűköz, sormagasság, betűszerepkör, dőlt, díszítés, sorok száma (line clamp) |
color | szövegszín (szerepkör vagy egyéni szín), hover szövegszín |
background | háttérszín (szerepkör vagy egyéni) vagy színátmenet, lebegtetési kitöltés |
border | vastagság és egyes oldalak, stílus, szín, lekerekítés és egyes sarkok, hover keretszín |
effects | árnyék, áttetszőség, szűrők, háttérelmosás, hoverkor: árnyék, áttetszőség, kiemelés (lift), szűrők |
background-media | háttérkép és -videó eszközönként, illeszkedés, fókuszpont, rögzített görgetés, overlay |
motion | belépési animáció, amely akkor indul el, amikor az elem a képernyőre görgődik |
dividers | alakzatos elválasztók (shape dividers) a szekció felső és alsó szélén |
visibility | elrejtés asztali gépen, táblagépen vagy mobilon |
Az értékek tokenek, soha nem pixelek. A színek szigorúan ellenőrzött egyéni színek is lehetnek.
Bármely érték lehet reszponzív: { "base": "lg", "tablet": "md", "mobile": "sm" }, ahol a tablet
64rem alatt, a mobil pedig 48rem alatt érvényes. A tablet örökli a base értéket, a mobil pedig a tabletet. A base hiányában az asztali nézet megtartja az
elem saját dizájnját, és csak a felülírt eszközök változnak.
Design tokenek
| Stílusútvonal | Tokenek | CSS-változó |
|---|---|---|
spacing.padding.*, layout.gap | none, 3xs, 2xs, xs, sm, md, lg, xl, 2xl, 3xl | --pt-sp-* |
spacing.margin.* | a térközskála plusz auto | --pt-sp-* |
size.minHeight | a térközskála plusz half-screen, screen | --pt-sp-*, svh |
size.width | auto, full, fit, vagy a parent törtrésze: 1/4, 1/3, 1/2, 2/3, 3/4 | nincs |
size.aspect | auto, 1:1, 4:3, 3:2, 16:9, 21:9, 3:4, 2:3, 4:5 | nincs |
media.fit, media.position | cover, contain; top-left, top, top-right, left, center, right, bottom-left, bottom, bottom-right | nincs |
size.maxWidth | narrow, prose, content, wide, full | --pt-maxw-* |
typography.size | xs, sm, body, lg, h4, h3, h2, h1, display (beállítja a hozzá tartozó sormagasságot) | --pt-fs-* |
typography.weight | regular, medium, semibold, bold | --pt-fw-* |
typography.leading | tight, normal, relaxed (felülírja a mérethez társított sormagasságot) | --pt-lh-* |
typography.tracking | tight, normal, wide | --pt-tracking-* |
typography.align | left, center, right, justify | nincs |
typography.transform | none, uppercase, lowercase, capitalize | nincs |
typography.family | heading, body, accent (a téma betűszerepkörei) | --pt-font-* |
typography.style, typography.decoration | normal, italic; none, underline, line-through | nincs |
typography.clamp | none, vagy legfeljebb 1 és 4 sor között | nincs |
layout.display | block, flex, grid | nincs |
layout.direction, layout.wrap | row, column, row-reverse, column-reverse; wrap, nowrap | nincs |
layout.overflow | visible, hidden, clip, auto | nincs |
layout.justify | start, center, end, between, around | nincs |
layout.align | start, center, end, stretch | nincs |
layout.columns | egész számok 1 és 6 között (display: grid esetén) | nincs |
layout.self | left, center, right (az align funkció) | nincs |
layout.grow, layout.order | fill, fit; first, 1–6, last (az align funkció) | nincs |
layout.position, layout.top | static, relative, sticky; header (az alapértelmezett) vagy a térközskála | --pt-sticky-header, --pt-sp-* |
layout.zIndex | base, raised, overlay, top | --pt-z-* |
color.text, border.color | színszerepkörök: foreground, muted-foreground, primary, primary-foreground, secondary, secondary-foreground, accent, accent-foreground, background, card, card-foreground, muted, border, destructive; vagy egyéni szín (lásd alább) | --<role> |
color.background | egy színszerepkör, egyéni szín, vagy linear-gradient(<0-999>deg, #hex <0-999>%, …) 2–8 hex színponttal | --<role> |
border.width, border.sides.* | none, thin, medium, thick; a sides értékei: top, right, bottom, left | --pt-border-* |
border.style | solid, dashed, dotted (a stílus nélküli vastagság folytonos vonalat rajzol) | nincs |
border.radius, border.corners.* | none, sm, md, lg, pill; a corners értékei: topLeft, topRight, bottomRight, bottomLeft | --pt-radius-* |
effects.shadow | none, sm, md, lg | --pt-shadow-* |
effects.opacity | százalék, 0 és 100 között 5-ös lépésközzel | nincs |
hover.text, .background, .borderColor | megegyezik a color.text, color.background és border.color értékeivel | --<role> |
hover.shadow, .opacity, .lift | megegyezik az effects.shadow és effects.opacity értékeivel; lift: none, sm, md, lg | --pt-lift-* |
hover.transition | none, fast, normal, slow (normal, ha be van állítva hover érték) | --pt-duration-* |
effects.blur, effects.backdropBlur | none, sm, md, lg, xl | --pt-blur-*, --pt-backdrop-* |
effects.brightness, .contrast, .saturate | százalék, 0 és 200 között 5-ös lépésközzel (100 a változatlan) | nincs |
effects.grayscale | százalék, 0 és 100 között 5-ös lépésközzel | nincs |
hover.blur, .brightness, .contrast, .grayscale, .saturate | megegyezik az effects szűrőivel; mindegyik csak a saját szűrőjét cseréli le | a fentiek szerint |
background.image, background.video | oldalon belüli útvonal (/media/…) vagy legfeljebb 512 URL-biztos karakterből álló http(s) URL, illetve none az adott eszközön való elhagyáshoz | nincs |
background.poster | egy cím a fentiek szerint; egyetlen érték minden eszközre | nincs |
background.fit, background.position | megegyezik a media.fit és media.position értékeivel | nincs |
background.attachment | scroll, fixed | nincs |
background.overlay, .overlayOpacity | színszerepkör vagy egyéni szín; százalék 5-ös lépésközzel (50, ha nincs megadva) | --<role> |
motion.entrance | none, fade, fade-up, fade-down, zoom, slide-left, slide-right | nincs |
motion.duration, motion.delay | fast, normal, slow; none, sm, md, lg | --pt-enter-*, --pt-delay-* |
motion.repeat | once, repeat; egyetlen érték minden eszközre | nincs |
dividers.top, dividers.bottom | pattern (egy érték): wave, curve, tilt, triangle, zigzag; height: none, sm, md, lg, xl; color: egy szín; flip: none, mirror | --pt-divider-* |
visibility.desktop, .tablet, .mobile | a false érték csak az adott eszközön rejti el az elemet | nincs |
Az egyéni szín pontosan #rgb, #rrggbb, #rrggbbaa, rgb(r, g, b) vagy
rgba(r, g, b, a) formátumú lehet (csatornák 0 és 255 között, alfa 0 és 1 között, legfeljebb egy opcionális szóköz az egyes
vesszők után). A színnevek, a var(…), a hsl(…) és a szóközökkel körülvett stringek elutasításra kerülnek. Változatlanul kerül
beírásra a CSS-be. A háttérszínnel rendelkező link vagy gomb root eleme a hoverhez is kap egy árnyalatot ebből a
színből, a szövegszíne felé keverve, mivel az elem saját kitöltése felülírja a változat hover-színét.
Az Elhelyezés (layout.self, amelyet az align funkció biztosít) automatikus sorirányú külső margókkal (auto inline margins) mozgatja az elem saját dobozát,
így ott is működik, ahol a typography.align nem: gombnál, visszaszámlálónál,
árnál vagy korlátozott méretű képnél. Elhelyezi az elemet flex vagy grid parentben (minden platformkonténerben),
és parent blockban minden olyan dobozban, amely keskenyebb nála. Az elhelyezett elem megtartja saját
szélességét a nyújtás helyett; egy alapértelmezetten teljes szélességű elem elhelyezése akkor válik láthatóvá, ha a
size.maxWidth korlátozza. A typography.align csak a dobozon belüli szöveget igazítja. Add meg az align funkciót
minden olyan elemnek, amelyet a kereskedő szabadon elhelyezhet egy konténerben.
Törtrészek és sorrend. A size.width törtrésze a parent százalékos aránya; flex sorban a
részek együtt zsugorodnak, hogy helyet adjanak a résnek (gap), így az 1/3 és a 2/3 egymás mellett helyezkedik el.
A layout.grow: fill hatására a gyermekelem kitölti a sorában maradt helyet. A layout.order és a
fordított irányok csak a vizuális sorrendet változtatják meg eszközönként: a „képernyőn kép jobbra, telefonon kép
legfelül” beállítás: direction: { base: "row-reverse", mobile: "column" }.
A Rögzülő (layout.position: sticky) nézetben tartja az elemet a layout.top pozíciótól kezdve, alapértelmezetten a
bolt fejléce alatt, és megakadályozza, hogy a sorához nyúljon, ami miatt nem tudna hova
rögzülni. A layout.zIndex pozicionálja is az elemet, hogy érvényesüljön a rétegszintje. A header követi a
fejlécet, ahogy az elrejtőzik, megjelenik vagy összemegy (lásd: A bolt fejléce).
Keretek. A border.width és a border.radius minden oldalt és sarkot beállít; a border.sides és a
border.corners egyedi értékeket ír felül, így a felső szegély: { "sides": { "top": "thin" } }. Elválasztón
(egy <hr> root elemen) a minden oldalra érvényes vastagság egyetlen vonalat rajzol, soha nem kettőt egymásra téve.
Képarány és média. A size.aspect határozza meg a doboz formáját. Az elem saját képe vagy videója – a root elem
közvetlen gyermeke – kitölti a dobozt, amelyet a media.fit vág körbe (alapértelmezetten cover) a
media.position fókuszpont körül.
Színséma. A színséma beállítás, nem pedig stílus: minden dobozt rajzoló szekció és blokk
fogadja a settings.color_scheme értéket, amely a téma nevesített színsémáinak egyike
(a color_schemes témabeállítás). A doboz és minden benne lévő elem a séma
színeivel jelenik meg, így minden színszerepkört használó gyermekelem újrastílusozás nélkül olvasható marad rajta; ha üres, megtartja a
parent sémáját. A kifejezetten megadott color.text vagy color.background felülírja a sémát.
Hover. A hover csoport tartalmazza mindazt, ami megváltozik, amikor a kurzor az elem felett van,
billentyűzetfókuszt kap, vagy a témaszerkesztő előnézetet jelenít meg róla (data-pe-state="hover" a root elemen). Minden leaf elem
a nyugalmi megfelelőjének képességével rendelkezik. A hover szín a színátmenetes kitöltést is felülírja,
és a hover kitöltés nélküli színátmenet is saját árnyalatot kap. Az átmenetek sebességét a
--pt-duration-* határozza meg, amelyet a rendszer nullára állít azoknál a vásárlóknál, akik csökkentett mozgást kértek.
Hátterek (background-media). A kép és a videó a tartalom mögött, a
kitöltési szín vagy színátmenet felett helyezkedik el, mindkettő felett pedig egy fedőszín található. Minden eszköznek lehet saját képe
vagy videója, vagy none; csak az töltődik be, amelyik megjelenik az adott eszközön. A fixed rögzítve tartja a képet, miközben az
oldal elgördül felette, kivéve azoknál a vásárlóknál, akik csökkentett mozgást kértek. A videó némított és
ismétlődik, csak akkor töltődik be, amikor a nézőtérhez közeledik, csak addig játszódik le, amíg a képernyőn van, és csökkentett mozgás esetén
megáll az első képkockáján vagy a poster képnél. A fedőszín a dobozon belül oldódik fel, így a
szerepkör követi a színsémát: egy sötét séma background overlay-jel a séma alapjával színezi a képet,
és világossá teszi a szöveget. A címek csak a DOM-attribútumokba jutnak el, a CSS-be soha.
A platform Konténer, Oszlop és Egyéni szekciója kirajzolja; a background-media képességet deklaráló témaelem pedig
a @poltura/theme-sdk/elements csomagból származó <ElementBackground /> komponenst rendereli a root elem első childjaként.
Szűrők (effects). A fényerő, a kontraszt, a szürkeárnyalat, a telítettség és az elmosás rögzített sorrendben érvényesül
az elem saját képpontjaira; a backdropBlur homályossá teszi azt, ami átlátszik az áttetsző
kitöltésen keresztül (üveg hatású panelekhez). A hover szűrő csak a saját funkcióját váltja fel, és a
hover átmenettel animálódik, így egy szürkeárnyalatos logófal hoverkor színessé válhat.
Belépők (motion). A belépő animációval rendelkező elem a szerveroldali jelölésben a data-pe-motion attribútumot hordozza,
és semmi olyat, ami elrejtené. Amint a JavaScript lefut, a webáruház az első képkockán tartja,
és elindítja a presetet, amikor az egyhatoda láthatóvá válik: once, vagy minden alkalommal, amikor újra
láthatóvá válik. JavaScript nélkül semmi sem rejtőzik el, és semmi sem mozog a csökkentett mozgást kérő vásárlók számára. A none
egy eszközön kikapcsolja a belépést. A témaszerkesztő a Motion csoportból játssza újra a belépést.
Alakzatos elválasztók (dividers). Beépített, inline SVG a szekció felső vagy alsó szélén,
a kisegítő technológiák elől elrejtve, alapértelmezetten az oldal háttérszínével, így a sáv
vágottnak tűnik. A minta eszközönként egyetlen érték; állítsd a magasságot none értékre az adott eszközön történő elhagyáshoz.
Az Egyéni szekció kirajzolja őket; a dividers funkciót deklaráló témaszekció pedig a
@poltura/theme-sdk/elements csomagból származó <ElementDividers /> komponenst rendereli a root elemén belül.
Bármi más (pixelérték, ismeretlen kulcs, url(…), tetszőleges CSS string) figyelmen kívül marad,
mielőtt elérné a CSS-t, és a témaszerkesztő, a témaellenőrzés és a kódszerkesztő a JSON-útvonalával együtt jelzi,
így egy kézzel szerkesztett elrendezési fájl soha nem fecskendezhet be CSS-t.
{
"id": "q1",
"type": "wall-quote",
"settings": { "quote": "Fast delivery." },
"settings_i18n": { "hu": { "quote": "Gyors szállítás." } },
"style": {
"typography": { "size": "h3" },
"spacing": { "padding": { "top": { "base": "md", "mobile": "sm" } } }
}
}A tokenek semleges CSS-változókra képződnek le (--pt-sp-*, --pt-fs-*, --pt-lh-*, --pt-fw-*,
--pt-radius-*, --pt-shadow-*, --pt-maxw-*, --pt-gutter, --pt-font-*, --pt-z-*, --pt-lift-*,
--pt-duration-*, --pt-sticky-header, --pt-blur-*, --pt-backdrop-*,
--pt-enter-*, --pt-delay-*, --pt-divider-*, --pt-page-background), a színszerepkörök pedig a téma --primary,
--foreground és egyéb változóira. A platform biztosítja az alapértelmezett értékeket. Képezd le a semleges réteget a
saját skáládra az src/styles/tokens.css fájlban, hogy a kereskedő választásai natívnak hassanak:
:where(:root) {
--pt-sp-md: var(--my-space-4);
--pt-fs-h1: var(--my-font-h1);
--pt-radius-md: var(--my-radius);
--pt-font-heading: var(--my-display-font);
--pt-font-body: var(--my-text-font);
--pt-font-accent: var(--my-accent-font);
--pt-maxw-content: var(--my-container);
--pt-gutter: var(--my-gutter);
}A --pt-maxw-content és a --pt-gutter felel meg a .theme-container class-odnak: a border-box maximális szélességének és
az oldalsó paddingjének. Egy dobozos Egyéni szekció pontosan ezzel a párossal húzza be a tartalmát, ezért képezd le mindkettőt
a konténered által használt értékekre, különben a kereskedői szekciók nem fognak egy vonalba esni a tieiddel.
A webáruház rendereléskor minden szekció stílusát egyetlen, [data-pe="<id>"] scoped <style> szabálykészletbe
fordítja, ezért kötelező a deklarált szekció rootjának hordoznia az attrs értéket.
Honnan veszik a stílusukat a platformelemek?
- Grid-natív elemek. Az Oszlopok, a Termékrács és a Gyűjteménylista saját rácsot jelenítenek meg
(
layout_default: 'grid'a sémájukban). Az irány vagy a törés soha nem alakítja őket flexxé; csak a kifejezettlayout.displayteszi ezt meg. A saját breakpoint oszlopaik megmaradnak, amíg egy eszköz nem kap sajátlayout.columnsértéket: az asztali darabszám megmarad az asztali nézetben, a telefon pedig a táblagép darabszámát követi. - A belső részek öröklik. A betűvastagság, a szín, a kis-/nagybetűs írásmód és a betűköz – ahol az elem felkínálja őket – átadódik az akciós árnak, a visszaszámláló számainak és címkéinek, a fülcímkéknek, a harmonika törzsének és a listaikonoknak.
- Szövegszín dobozon. A Konténer, az Oszlop és az Egyéni szekció esetében a szövegszín beállítja a
dobozon belüli
--foregroundszerepkört és a lágyabb--muted-foregroundértéket is, így a benne lévő címsorok és szövegek követik azt; a színséma pedig a doboz egészét átszínezi. - A Kosárba gomb mindig saját dobozban helyezkedik el (
data-pe-group), amely az opcióválasztóit tartalmazza: a térköz és a méret ezt a dobozt stílusozza, a kitöltés és a keret pedig a gombot. - Konténerlink. A linkkel ellátott konténer egésze kattintható a doboz feletti valódi hivatkozáson keresztül, elérhető a Tab billentyűvel, a nevét pedig a benne lévő első címsorról, gombról vagy képről kapja.
- Egyéni szekció. A minimális magasság, a tartalom elhelyezkedése és a háttérkép a
Stílus fülről érkezik (
size.minHeight,layout.justify,background). A dobozos tartalom a témakonténerre illeszkedik (--pt-maxw-content,--pt-gutter), a széles a--pt-maxw-wideértékre ugyanazzal az oldaltávolsággal, az oldalsó padding pedig hozzáadódik ehhez a távolsághoz. A teljes szélesség a háttereket a szélekig futtatja, és megtartja a téma oldaltávolságát a tartalom számára, amíg az oldalsó padding felül nem írja a behúzást: anonea tartalmat a szélekig futtatja.
Gyermekelemek: Slot és helyettesítő karakterek
A parent soha nem maga rajzolja ki a childot. A name nélküli <Slot /> azokat a gyermekelemeket rendereli, amelyeket a kereskedők
az aktuális elem alapértelmezett régiójába helyeztek, az elmentett sorrendben, mindegyiket a saját
komponensén és keretén keresztül, egyetlen className attribútumot hordozó burkoló div-ben. A <Slot name='media' />
ugyanezt teszi egy deklarált slottal. Az as határozza meg a régió címkéjét (div, ul, ol, nav, vagy none,
ha nincs szükség dobozra); az as='ul' vagy as='ol' formában megjelenített régió csak olyan blokkokat fogad el, amelyek frame értéke li.
Az üres régió semmit sem renderel és nem foglal helyet sem az éles oldalon, sem a témaszerkesztőben:
a témaszerkesztő a behúzási célterületét az oldal fölé rajzolja ki a slot label címkéjével ellátva.
A @poltura/theme-sdk/elements csomagból származó useChildBlocks('media') visszaadja a régió megjelenített gyermekeit
(id, type és a beállítások a vásárló nyelvén) darabszámokhoz, fülekhez és elrendezési döntésekhez;
rajzold ki őket a Slot segítségével.
A blocks.static fejlesztői azonosítókkal ellátott fix gyermekelemeket deklarál. Ez a definíciórészlet
hármat deklarál:
blocks: {
accepts: [ELEMENT_WILDCARD],
static: [
{ id: 'title', type: 'heading', slot: 'details' },
{ id: 'buy', type: 'add-to-cart', slot: 'details', required: true },
{ id: 'summary', type: 'text' },
],
},A kereskedők elrejthetik és újrastílusozhatják a statikus elemeket, de nem mozgathatják vagy törölhetik őket; a required
elemek nem is rejthetők el. A slot értékkel rendelkező statikus elem abban a régióban renderelődik a kereskedő blokkjai között;
amelyik nem rendelkezik ilyennel, az az alapértelmezett régióban jelenik meg a <Slot /> által kirajzolva.
Két helyettesítő karakter használható az accepts mezőben:
ELEMENT_WILDCARD('@element'): minden elem, amelyet bármely aktív szolgáltató kínál. Ez magában foglalja a platformelemeket (konténer, címsor, szöveg, gomb, kép, termékkártya…), valamint minden olyan plugint, appot vagy témablokkot, amely kirajzolja magát.THEME_BLOCK_WILDCARD('@theme'): az összes szolgáltató eleme a platform kivételével, vagyis a plugin-, app- és témablokkok.
A szekció saját nevesített gyermekelemei mindig először a szekció saját blokklistájában oldódnak fel,
így egy olyan témablokk, amelynek kulcsa megegyezik egy platformszekció childjának kulcsával (stat, quote, item),
soha nem módosítja az adott platformszekciót.
Slotok és az általuk elfogadott elemek
Egy slot szűkítheti az általa fogadott elemek körét a saját accepts mezőjével, amely az elem
blocks.accepts mezőjének részhalmaza. Ez a szekció az ELEMENT_WILDCARD, Slot és defineSection elemeket importálja a
@poltura/theme-sdk/elements csomagból, a cn függvényt pedig a @poltura/theme-sdk/ui csomagból:
export const promoSplit = defineSection({
type: 'promo-split',
label: 'Promo split',
icon: 'columns',
category: 'marketing',
settings: {},
blocks: { accepts: [ELEMENT_WILDCARD], max: 12 },
slots: [
{ name: 'media', label: 'Media', accepts: ['image', 'video'] },
{ name: 'body', label: 'Text and buttons' },
],
component: ({ attrs }) => (
<section {...attrs} className={cn(attrs.className, 'grid gap-8 md:grid-cols-2')}>
<Slot name='media' />
<Slot name='body' />
</section>
),
});Minden gyermekelem rögzíti a régióját a "slot": "media" mezőben az elrendezési fájlban. Az accepts nélküli
slot mindent elfogad, amit az eleme elfogad. A választó, a navigátor drag and drop funkciója,
a mentési érvényesítés, az AI-asszisztens és a kódszerkesztő JSON Schema-ja mind ugyanazt a szabályt alkalmazza,
a témaellenőrzés pedig hibát jelez az olyan deklarált slot esetén, amelyet a komponens soha nem renderel.
Inline szöveg: EditableText
Az <EditableText setting='heading' as='h2' /> az aktuális elem egy egyszerű text vagy textarea beállítását
jeleníti meg a vásárló nyelvén, és lehetővé teszi a kereskedők számára, hogy a vásznon írják át. A témaszerkesztőn
kívül pontosan <h2>text</h2> formában jelenik meg, üres szöveg esetén pedig semmi sem renderelődik.
Az <EditableRichText setting='body' className='flex flex-col gap-3' /> ugyanezt teszi a
richtext beállításnál: dupla kattintással megnyílik a formázásával együtt, a Cmd/Ctrl+B és a Cmd/Ctrl+I
váltja a félkövér és dőlt stílust, az Enter új bekezdést indít, a Cmd/Ctrl+Enter vagy egy kattintás máshova pedig
elmenti. Az Escape billentyű elveti a módosítást.
Kereskedelmi elemek
Hat platformelem jelenít meg élő katalógusadatokat mindenhol, ahol az elrendezés elemeket fogad el:
| Elem | Típuskulcs | Mit mutat |
|---|---|---|
| Termékkártya | product-card | egy termék: kép, név, ár, opcionális jelvény és kosárba gomb |
| Termékrács | product-grid | 2–24 termék egy gyűjteményből, kategóriából vagy kézi kiválasztásból |
| Ár | price | a termék ára, akció esetén az eredeti árral |
| Kosárba | add-to-cart | gomb a termék opcióival (méret, szín…) |
| Gyűjteménylista | collection-list | 2–24 csempe, amely gyűjteményekre vagy egy kategória alkategóriáira mutat |
| Visszaszámláló | countdown | napok, órák, percek és másodpercek az end_at időpontig (datetime beállítás) |
A price és az add-to-cart üres product értékkel annak a termékoldalnak a termékét használja,
amelyen elhelyezkedik. A beállítások azonosítókat tartalmaznak, soha nem a katalógusadatok másolatait, így a nevek, az árak és a készlet mindig
naprakészek, a vásárló nyelvén és pénznemében jelennek meg.
A webáruház összegyűjti azokat a katalógusadatokat, amelyekre az oldalon lévő összes kereskedelmi elemnek szüksége van (beleértve a sablonokat, az oldalakat, a fejlécet és a láblécet, valamint a megamenü paneleit), és egyetlen batch kérésben tölti be őket a szerveroldali renderelés során, így az elemek az első kirajzoláskor (first paint) teljesen megjelennek minden útvonalon. A témaszerkesztőben a hozzáadott elem egyetlen követő kéréssel tölti be az adatait. Az üresen hagyott címkék (kosárba helyezés szövegezése, visszaszámláló mértékegységei) a platform szövegezését használják a bolt minden nyelvén. A kitöltött címkék kereskedői szövegek, és a többihez hasonlóan fordíthatók.
Bolti data bindingok
A text, textarea, richtext, image, url vagy link beállítások a saját érték tárolása helyett
élő bolti adatokat is beolvashatnak. A kereskedők az inspectorban a mezőcímke melletti adatbázis gombbal bindelhetnek be egyet.
Az elrendezési fájlban a beállítás egy binding objektumot tárol:
{
"id": "b_12",
"type": "heading",
"settings": {
"text": {
"$bind": { "source": "product", "id": "organic-tee", "field": "title", "fallback": "Our tee" }
}
}
}| Forrás | Mezők |
|---|---|
product | title, subtitle, description, price, compare_at_price, vendor, image, url |
collection | title, url |
category | title, description, url |
store | name, tagline |
customer | first_name |
- Az
ida termék, gyűjtemény vagy kategória handle-je, ahogyan azt a termékválasztók tárolják. Hagyd el, ha azt szeretnéd beolvasni, amiről az oldal szól: egy termékoldal termékét, egy kategóriaoldal kategóriáját, vagy azt a gyűjteményt, amely szerint a lista szűr. A témaszerkesztőben a terméket nem tartalmazó sablonon lévő product binding egy mintaterméket jelenít meg. - A
fieldmezőnek illeszkednie kell a beállításhoz: a szöveges beállítások szöveges mezőket (és adescriptionmezőt) fogadnak, azimagebeállítások azimage-et, azurléslinkbeállítások pedig azurl-t. A mentési érvényesítés elutasít minden mást, és az elrendezés JSON Schema-ja csak a megfelelő mezőket kínálja fel. - A
fallback(legfeljebb 500 karakter) akkor jelenik meg, ha a boltban nincs érték: törölt vagy ismeretlen termék, alcím nélküli termék, vagy vendég vásárló acustomeresetén. Fallback érték nélkül a beállítás saját alapértelmezett értéke érvényesül.
A kötött értékek a szerveren oldódnak fel a renderelés során, ugyanazon a kötegelt kérésen keresztül,
mint a kereskedelmi elemek, így az első kirajzoláskor már láthatók, és az oldal soha nem indít kötésenként külön kérést.
Az árak a vásárló pénznemében formázódnak. A címek és leírások a vásárló nyelvén érkeznek
a bolt katalógusfordításaiból. A kötött beállítás soha nem kerül gépi fordításra, és nem tartalmaz
settings_i18n bejegyzést: egy mező bekötése törli a fordításait.
A leírások bolti szövegek, gyakran importálásból származó HTML-ek. Soha nem kerülnek az oldalra formázott jelölésként: a
richtext beállítás a rich text szabályrendszer szerint olvassa be őket (bekezdések, címsorok, listák, félkövér,
dőlt, biztonságos linkek), minden más szöveges beállítás pedig egyszerű szövegként olvassa őket.
Az elemkomponensek a feloldott értéket a settings propban kapják meg, mint bármely más beállítást. Az EditableText
kihagyja a bindelt beállítást a vásznon történő közvetlen szerkesztésből.
Alapnyelv
Minden elrendezési fájl alap settings értékei a bolt alapértelmezett nyelvét tartalmazzák, amelyet a
settings/values.json fájlban a base_locale határoz meg. Minden más nyelv egy override (overlay)
a settings_i18n[<locale>] alatt, amely csak az eltérő mezőket tartalmazza. A téma alapértelmezett szövegét
azon a nyelven írd meg, amelyen kiadod, és a base_locale értékét a tiszta nyelvkódra állítsd ("hu", nem
"hu-HU"); az e nélküli témát a rendszer angolnak tekinti.
- A vásznon és az inspectorban végzett közvetlen szerkesztés az alapbeállításokat az alapnyelven írja, az override-ot pedig a kiválasztott egyéb nyelven.
- Ha a bolt alapértelmezett nyelve eltér a téma alapnyelvétől, a témaszerkesztő felajánlja az rebase-t: az adott nyelv override-jai válnak az alappá, a régi alap override-dá válik, és a fordítási ujjlenyomatok követik ezt, így semmi sem vész el és nem kerül újrafordításra.
- A boltba bekerülő téma (telepítés, induló sablon betöltése, visszaállítás) csak akkor alapozódik újra automatikusan, ha a bolt nyelve már tartalmazza az összes szöveget; ellenkező esetben a kiadott állapotában marad.
Feltételek és horgonyok
Minden szekció és elem tartalmazhat egy opcionális conditions kulcsot a settings és a
style mellett, amely a Haladó fülön, a Láthatóság alatt szerkeszthető:
{
"id": "b_07",
"type": "button",
"settings": { "label": "Sign in for 10% off", "anchor": "member-offer" },
"conditions": {
"audience": "guests",
"from": "2026-11-27T00:00:00+01:00",
"until": "2026-12-01T00:00:00+01:00"
}
}audience:guests(be nem jelentkezett vásárlók) vagycustomers(bejelentkezett vásárlók). Azallaz alapértelmezett, és soha nem kerül tárolásra.from/until:datetimeértékek a bolt órája szerint. Afromaz első pillanat, amikor az elem megjelenik, azuntilpedig az első pillanat, amikor már nem látható. A puszta dátum az adott nap kezdetének éjfélét jelenti a bolt időzónájában.settings.anchor: az elem oldalon belüli hivatkozási célpontja. Az ugyanazon az oldalon lévő#member-offerlink odagörget hozzá. Kisbetűsa-z,0-9,-és_, egyedi az elrendezési fájlon belül; soha nem fordítható. Bármely elem beállíthatja anélkül, hogyanchormezőt kellene deklarálnia.
A webáruház a szerveren értékeli ki a feltételeket. A másik célközönségnek szánt vagy az
időzítésen kívül eső elem kimarad a renderelt HTML-ből és a benne szerializált oldaldatokból,
így a csak vásárlóknak szóló kód soha nem jut el a vendégekhez. Az elemkomponensek soha nem látják a feltételeket:
a block- és section renderer-ek kezelik őket, és a horgonyt id-ként helyezik el az elem gyökerén
(az attrs segítségével, ezért fontos a spread).
A témaszerkesztő vászna követi az Előnézet mint beállítást: a másik célközönség pontosan úgy marad ki, mint a webáruházban. Az időzítésükön kívül eső elemek a vásznon sávozott felülettel és „Most rejtve: időzítve” jelvénnyel maradnak meg, a navigátorsorukban pedig egy óra jelenik meg.
A feltételek minden kérésnél kiértékelődnek, így az oldal soha nem jelenít meg lejárt promóciót, és nem rejt el
már elindultat sem. A megnyitott oldal a rajta lévő bármely elem következő from vagy until időpontjában újratölti az adatait.
A mentési érvényesítés elutasítja az ismeretlen feltételkulcsokat, az ismeretlen célközönséget, a hibás formátumú dátumot és a
hibás vagy ismétlődő horgonyt. A from előtti until megengedett: az ilyen elem soha nem jelenik meg, és a
szerkesztő ezt jelzi is.
Korlátok
A mentési érvényesítés ugyanazokat a korlátokat kényszeríti ki a témaszerkesztőben, a kódszerkesztőben, az AI-asszisztensben és közzétételkor, a kódszerkesztő JSON Schema-ja pedig gépelés közben jelzi őket:
Korlát (limit a hibában) | Maximum elrendezési fájlonként |
|---|---|
elements | 1 000 szekció és beágyazott blokk összesen |
sections | 40 szekció |
children | 24 gyermekelem szekciónként vagy konténerenként (a séma blocks.max értéke csak csökkentheti) |
depth | 8 blokkszint egy szekció alatt, mind a témaszerkesztőben, mind a témaellenőrzésben |
style_size | 12 KiB szerializált style elemenként (minden levél minden eszközön, a leghosszabb hét háttércímmel körülbelül 10,3 KiB) |
string_length | 20 000 karakter stringenként a settings vagy settings_i18n mezőkben |
file_size | 1 MiB szerializált JSON |
A korlátot túllépő mentést a rendszer egészében elutasítja egy layout_limit_exceeded hibával, amely megnevezi a korlátot,
a maximumot és a tényleges értéket. A témaszerkesztő ezt a saját nyelvén magyarázza el a kereskedőnek,
és már a művelet előtt visszautasítja a beszúrást, a beillesztést vagy a duplikálást, ha az túllépné a korlátot.
A bolt fejléce
A promóciós sáv és a fejléc egyetlen közös dobozon, a [data-theme-chrome="header"] elemen belül jelenik meg, amelynek
görgetési viselkedését a header section saját beállításai határozzák meg a layout/header.json fájlban. A
webáruház ezt minden témánál futtatja. A téma csak az állapotokat stílusozza. A beállítások a következők:
| Beállítás | Értékek |
|---|---|
behavior | sticky (az alapértelmezett), reveal (lefelé görgetve eltűnik, felfelé visszatér), static |
pin | all (az alapértelmezett) vagy last_row: csak az utolsó sáv marad a képernyőn; csak sticky és reveal esetén |
shrink | a true érték összecsukja a rögzített fejlécet az oldal görgetésekor; csak sticky és reveal esetén |
transparent | off (az alapértelmezett), home, all: átlátszó az első szekció felett |
mobile_from | tablet (az alapértelmezett), mobile vagy desktop: ettől a mérettől lefelé a menügomb váltja fel a menüsávot |
drawer_side | left (az alapértelmezett) vagy right: az oldal, amelyről a mobilmenü kinyílik |
drawer_width | sm, md (az alapértelmezett) vagy full: a mobilmenü szélessége |
A beállítások minden nyelven közösek. A beállítás nélküli header section az alapértelmezett értéket kapja, az ismeretlen érték pedig mezőnként esik vissza az alapértelmezettre. Az átlátszó és a görgetett színek a header section stílusállapotai a Stílus fülön, nem pedig beállítások.
A doboz attribútumként hordozza az állapotot. A szerver rendereli a data-header-behavior,
data-header-pin, data-header-overlay (átlátszó ezen az oldalon) és data-header-shrink attribútumokat.
A runtime hozzáadja a data-header-scrolled (meghaladta a fejléc magasságát), data-header-hidden
(reveal lefelé görgetés közben) és data-header-shrunk értékeket. A header section rootja a
data-header-mobile-from attribútumot hordozza.
- Nincs elrendezési elcsúszás (layout shift). Az átfedő fejléc az első bájttól kezdve kikerül a document flow-ból, így semmi
sem mozdul el az oldal görgetésekor. Az összecsukódó fejléc pontosan
--pt-header-shrink-byértéket veszít, amelyet a platform a doboz alsó margójaként ad vissza ugyanabban az átmenetben. Az összecsukódást alkalmazó téma ezt a hosszt a:rootelemen deklarálja, és ezzel csökkenti egy sor magasságát::where([data-header-shrunk]) .my-row { height: calc(var(--my-row-h) - var(--pt-header-shrink-by)); }. Deklaráció nélkül csak a logó méreteződik át. - A fejléc alatt. Az átfedő fejléc elfedné az oldal tetejét, ezért az oldaltörzs
alatta kezdődik: a platform nyugalmi állapotban a fejléc magasságával tolja le (a promóciós sávval együtt), ami
soha nem változik, miközben a fejléc elrejtőzik vagy összecsukódik. Az a teljes szélességű szekció, amelynek az
átlátszó fejléc alatt kell elhelyezkednie, ezt a gyökerén lévő
data-header-underlayattribútummal jelzi; amikor ez nyitja az oldalt, a letolás megszűnik, és a szekció a saját tartalmát tolja le a--pt-header-underlayértékkel (mindenhol máshol0px):padding-top: calc(4rem + var(--pt-header-underlay, 0px)). - Eltolás (Offset). A
--pt-header-heighta rögzített fejléc tényleges magassága: a téma--sticky-topértéke nyugalmi állapotban, csökkentve az összenyomódással, rejtett vagy statikus állapotban pedig0px. A--pt-sticky-header(alayout.top: headereltolás) és a--sticky-topköveti ezt, így a rögzülő elemek közvetlenül a fejléc alatt helyezkednek el annak mozgása közben. - Átlátszó. Átlátszó állapotban a fejlécsáv
--backgroundés--borderértéketransparent, a--foregroundés a--muted-foregroundpedig a sötét séma értékeit olvassa be (--pt-header-overlay-fg,--pt-header-overlay-muted), amíg az átfedési stílusállapot át nem színezi őket. Az egyéb szerepkört színező fejléc (egy--cardsáv, egy saját színű tömb) törli azt a:where([data-header-overlay]:not([data-header-scrolled]):not(:focus-within))szabály alatt. A lebegtetés és a billentyűzetfókusz tömörré teszi, így a nyitott menük és a kereső soha nem látszanak átlátszó alapon. - Billentyűzet. Az elrejtett fejléc a tab orderben marad, és visszatér, ha bármely eleme fókuszt kap, így a fókusz soha nem kerül alá.
- Keresés. A
fieldformában megjelenítettsearchblokk a mező alá rögzített előugró ablakban ([data-search-results]) nyitja meg a javaslatait és találatait, így a fejléc megtartja a magasságát a vásárló gépelése közben; aziconegy ilyen előugró ablakban nyitja meg a mezőt, azoverlaypedig egy modalban. A nyílbillentyűkkel lépkedhetsz a lehetőségek között, az Enter megnyitja a kiválasztottat, az Escape vagy a kívülre kattintás pedig bezárja az ablakot. - Mozgás. Az átmenetek a
--pt-header-duration(--pt-duration-normal) időtartammal futnak, ami nulla azoknál a vásárlóknál, akik csökkentett mozgást kértek.
Az a fejléc, amelynek felső sorainak el kell gördülniük, a header section pin értékét last_row-ra állítja:
a doboz ekkor felemelkedik az utolsó sáv feletti sorok magasságával (a promóciós sávval együtt), amit a
runtime a --pt-header-pin-offset változóba mér be, és csak az az utolsó sor marad a képernyőn. Az Editorial így rögzíti az
élőfejét, a Pop pedig azt a sort rögzíti, amely a lebegő gombját hordozza. A Launch a
mobile_from értéket desktop-ra állítja, ami minden képernyőméreten a gomb mögött tartja a menüt.
Platformelemek restyle-olása
Ha meg szeretnéd tartani egy platformszekció vagy -blokk beállításait, és csak a jelölését módosítanád, írd felül a rendererjét egy olyan fájlban, amelynek a neve megegyezik a típusával:
Itt a CatalogHero a saját témád egyik komponense:
import { overrideSection } from '@poltura/theme-sdk/elements';
import { CatalogHero } from '../components/catalog-hero';
export const hero = overrideSection('hero', CatalogHero);import {
overrideBlock,
type ElementRenderProps,
type PlatformBlockSettings,
} from '@poltura/theme-sdk/elements';
function ContactHero({ settings }: ElementRenderProps<PlatformBlockSettings<'contact-hero'>>) {
return <h1 className='text-5xl font-semibold'>{settings.heading}</h1>;
}
export const contactHero = overrideBlock('contact-hero', ContactHero);A komponens megkapja a { settings, attrs, id } objektumot. A platform megtartja a sémát, az inspectort
és az adatokat, és maga rajzolja meg a felülírt elem keretét, így az attrs üres az
override-ban, és a renderer semmit sem ad át spreadként. A beállítások a tárolt formában érkeznek, a platform közzétett schema-jából tipizálva
(ElementRenderProps<PlatformSectionSettings<'hero'>>, PlatformBlockSettings<'faq-item'>),
ezért az opcionális mezőknek adj meg alapértelmezett értéket. Ha a beállításokat is módosítani szeretnéd,
használd a defineSection függvényt ugyanezzel a típuskulccsal.
A pénztár kivétel: a Poltura önállóan rajzolja ki. Ott semmilyen témaszekció, blokk vagy elem nem renderelődik.
A fejléc sora és az összegző oszlopa csak a checkout blockokat fogadja el (logó, megbízhatósági jelvény,
breadcrumb, megjegyzés), valamint a platform címsorát, szövegét, képét, ikonját, elválasztóját, térközét és fizetési
ikonjait, és a téma client code-ja sem töltődik be rajta. A téma stylesheetje és tokenjei továbbra is
érvényesülnek, így a téma CSS-sel, a platformjelölés data-checkout hookjain keresztül stílusozhatja a pénztárat.
A GYIK, a vélemények, a logólista, a statisztikák és a lépések szekciók blokkként jelenítik meg a soraikat, így a téma
külön stílusozhatja a szekció keretét és az egyes sorokat: írd felül a szekciót a címsor és a <Slot />
kirajzolásához, a row type-ot pedig az overrideBlock segítségével. A row type-ok: faq-item, quote,
partner-logo, stat és step.
import {
EditableRichText,
Slot,
overrideBlock,
overrideSection,
type ElementRenderProps,
type PlatformBlockSettings,
type PlatformSectionSettings,
} from '@poltura/theme-sdk/elements';
function Faq({ settings }: ElementRenderProps<PlatformSectionSettings<'faq'>>) {
return (
<section className='theme-container py-16'>
<h2>{settings.heading ?? ''}</h2>
<Slot className='divide-y' />
</section>
);
}
function Question({ settings }: ElementRenderProps<PlatformBlockSettings<'faq-item'>>) {
return (
<details open={settings.open_by_default ?? false}>
<summary>{settings.question ?? ''}</summary>
<EditableRichText setting='answer' />
</details>
);
}
export const faq = overrideSection('faq', Faq);
export const faqItem = overrideBlock('faq-item', Question);Minden platformszekció saját rendererje a @poltura/theme-sdk/sections csomagból származik (BentoSection,
FaqSection, HeroSection, TestimonialsSection és a többi), így az override becsomagolhatja
vagy delegálhatja a feladatot, és a platformjavítások továbbra is eljutnak a témához. A product blockok ugyanezt teszik a
@poltura/theme-sdk/product részeivel: a variant-picker felülírása a VariantPicker komponenst rajzolja ki
a classes propjaival, a product-reviews felülírása pedig a Reviews komponenst a className és
listClassName értékekkel.
import { overrideSection } from '@poltura/theme-sdk/elements';
import { BentoSection } from '@poltura/theme-sdk/sections';
export const bento = overrideSection('bento', (props) => (
<div className='theme-frame'>
<BentoSection {...props} />
</div>
));A bento maga rajzolja meg a rácsát és az opcionális legnépszerűbb termékek sávját; a csempéi a kereskedő elemei a régiójában, alapértelmezés szerint képek, product cardok és link cardok rácsa.
Regisztráció
Minden olyan elem, amely az src/sections/ vagy src/blocks/ alatti fájlból kerül exportálásra, közvetlenül
vagy újraexportálva regisztrálja magát. Nincs külön regisztrációs fájl: a fordító ezekből az exportokból építi fel
a téma elemeinek listáját, a webáruház pedig ebből rajzol.
- Fájlonként egy elem, és a fájlnév a típusa: az
src/sections/quote-wall.tsxaquoteWallelemet exportálja, azsrc/blocks/product-title.tsxaproductTitleelemet. Az exportot a típus után camelCase formátumban nevezd el. - Azok a blokkok, amelyek csak egyetlen szekción belül léteznek (a fenti
wall-quote, a megamenümenuColumnéspromoCardelemei), az adott szekció fájljában maradnak, és onnan kerülnek exportálásra. Az a blokk, amelyet egy másik szekció is elfogad, saját fájlt kap azsrc/blocksalatt. - Azok a segédfüggvények, amelyek nem elemek, az
src/componentsvagy azsrc/libmappába tartoznak.
A fordító és a kódszerkesztő a következőket jelzi problémaként:
| Probléma | Súlyosság |
|---|---|
| Két elem ugyanazt a típust regisztrálja | hiba |
| A fájlnév nem egyezik a típussal | hiba |
| Egy blokk megosztja a szekciója fájlját, de egy másik szekció is elfogadja | hiba |
Egy defineSection, defineBlock vagy felülírás nincs exportálva, vagy az src/sections és src/blocks mappán kívül található | hiba |
A definíció be van csomagolva (w(defineSection(...))), vagy namespace-en keresztül hívják meg (E.defineSection(...)) | hiba |
| Az override olyan típust nevez meg, amelyet egyetlen szolgáltató sem definiál | figyelmeztetés |
A témabejegyzések elfedik az azonos kulcsú platform-, plugin- és appbejegyzéseket.
Elemszolgáltatók
A téma a négy elemszolgáltató egyike. A másik három a platform, a Poltura alapvető extensionjei és a telepített appok. Mindegyikre ugyanazok a szabályok vonatkoznak:
- Definíció: minden szolgáltató ugyanazokat a
defineSectionésdefineBlockobjektumokat és ugyanazokat afield.*buildereket használja. - Kinyerés: ugyanaz a statikus olvasó olvassa az összes szolgáltatót. Egyik szolgáltató kódja sem fut le.
- Katalógus: a platform a szolgáltatókat egyetlen katalógusba vonja össze, és minden ezt olvassa: a témaszerkesztő, a mentési és közzétételi ellenőrzések, a fordítás, a kódszerkesztő elrendezési JSON Schema-ja és a webáruház.
Minden elem hordozza a provider értékét ({ kind, id }). A választó ez alapján csoportosít: Ez a téma a
témaelemeknél, Appok az appelemeknél, a platform- és pluginelemeknél pedig kategória szerint.
| Szolgáltató | Hol van definiálva | Típuskulcsok | Feltétele |
|---|---|---|---|
| platform | @poltura/theme-elements primitive-ek, platform sectionök | tiszta, fenntartott | soha |
| plugin | egy Poltura alap-extension | tiszta; egyedi a platformon és az összes pluginon belül | a plugin saját be- és kikapcsolója |
| app | az app forráskódja | app:<id>/<name>; a nyilvános appok telepítésenként kapnak kulcsot | telepítve és engedélyezve |
| téma | a téma TSX kódja | tiszta | soha |
Az elsőbbségi sorrend: platform, majd plugin, majd app, majd téma:
- A téma újradefiniálhat egy platform- vagy plugintípust. A sémája ekkor felülírja az övékét.
- A téma egy apptípust csak restyle-olhat az
overrideBlock/overrideSectionsegítségével. - Bármilyen más ütközés hibát eredményez, és az első definíció marad érvényben.
Ha egy feltételhez kötött szolgáltató ki van kapcsolva, az elemei eltűnnek a választóból és minden accepts
listából, és semmit sem renderelnek az éles oldalon. Az őket használó mentett elrendezések továbbra is átmennek az
ellenőrzésen, így a szolgáltató visszakapcsolása minden elhelyezést visszaállít. A témaszerkesztő és a
webáruház ugyanazt a be- és kikapcsolt állapotot olvassa be a boltból.
Ellenőrzések
A témaellenőrzés (poltura theme check <dir>, amelyet a kódszerkesztő minden mentéskor, a közzétételkor
és a téma buildelésekor futtat) a pozíciók megjelölésével jelzi a következőket:
- nem statikus definíciók, ismeretlen ikonok, kategóriák vagy sablonok, ismeretlen
acceptstípusok és duplikált típuskulcsok; - olyan szekció
componentnélkül, amelyet egyetlen platform renderer sem fed le; usage: hiba, ha egy komponens (és az általa hívott, azonos fájlban lévő függvények) olyan beállítást olvas, amelyet a saját definíciója nem deklarál; figyelmeztetés, ha egy deklarált beállítást soha nem olvas;children: minden olyan child type-ot, amelyet egy szekció vagy blokk elfogad, a komponensének ki kell rajzolnia: régió nélkül mentett gyermekek esetén a<Slot />segítségével, a típust elfogadó<Slot name>segítségével, vagy a platform renderer-en keresztül. Az a típus, amely csak akkor rajzolódik ki, ha egy beállítás egy bizonyos értékkel egyenlő (source === 'blocks'), kirajzolatlannak számít, mert a kereskedő által bármely más állapotban hozzáadott blokk soha nem jelenne meg. A módosítás által érintett fájlok hibát jelentenek; a téma többi része figyelmeztetést ad;accepted-without-component: elfogadott témablokkcomponentnélkül; hiba a módosítás által érintett fájlokban, figyelmeztetés máshol;checkout-locked: a pénztár kizárólag a platformhoz tartozik. Hiba, ha egy téma definiálja vagy felülírja acheckoutszekciót, a checkout sectionhöz tartozó bármely blokkot (checkout-brand,checkout-trust-badge,checkout-breadcrumbs,checkout-express,checkout-address,checkout-shipping,checkout-payment,checkout-summary,checkout-note) vagy a kosárcart-checkoutgombját, és a közzététel, valamint a téma buildelése visszautasítja. A webáruház figyelmen kívül hagyja az ilyen komponenst, és a Poltura sajátját rajzolja ki. A téma csak CSS-sel és tokenekkel stílusozhatja a pénztárat;slots: deklarált slot, amely soha nem kerül renderelésre a<Slot name>segítségével (missing-slot),slotnélkül deklarált statikus elem olyan komponensben, amely nem rajzol ki alapértelmezett vagy dinamikus<Slot>-ot (static-not-rendered), valamintas='ul'vagyas='ol'formában renderelt régió, amely nemlikeretű blokkokat fogad el (frame-mismatch);- olyan elrendezési fájlok, amelyek beállításai vagy stílusa kívül esik az elemük schema-ján, vagy amelyek átlépnek egy korlátot;
media/*: a képeknek médiatári fájlnak (media://<id>) vagy a téma által szállított fájlnak kell lenniük (asset://<path under assets/>, vagyasset('<path>')kódban). A távoli cím (media/no-remote-url) figyelmeztetés a CLI-ben és a kódszerkesztőben, és hiba a téma telepítésekor; ajavascript:,data:ésfile:címek (media/unsafe-url), a nem kiszolgált útvonalak, például/images/hero.jpg(media/unresolvable-path), a hiányzó asset (media/unknown-asset) és amedia://kódban (media/ref-in-code) hibák. Az alt szöveg nélküli kép (media/image-alt), a keretét túllépő kép és az ismeretlen médiatári fájl (media/unknown-media, csak kódszerkesztő és telepítés esetén) figyelmeztetések; a korlátot meghaladó asset vagy a nem woff2 formátumú betűtípus (media/asset-size) hiba; a sehol sem használt asset (media/unused-asset) megjegyzés. A teljes táblázatot a Theme assetek és média tartalmazza.