Posts block
A post listing on a page: automatic or hand-picked posts in a grid or rows, inside a section.
On this page
The Posts block drops a post listing into a page body. It exists only when the Posts module is on.
Where it is offeredLink to this section
PostsBlock — a unified posts listing block, registered only when the Posts module is enabled. A root-level, section-like block (color-system / background / padding controls; wraps the listing in <Section>).
FieldsLink to this section
| Field | Type | Label | Default | Notes |
|---|---|---|---|---|
append | richText | Append content | ||
aspectRatio | select | Media aspect ratio | 4/3 | Required; Options: 21/9 (cinema — 21:9), 16/9 (video — 16:9), 4/3 (landscape photo — 4:3), 3/2 (landscape photo — 3:2), 1/1 (square — 1:1), 3/4 (portrait photo — 3:4), 4/5 (instagram — 4:5), 9/16 (vertical video — 9:16) |
direction | select | Direction | desc | Shown when siblingData?.source!=="fixed"; Options: desc (Descending), asc (Ascending) |
dividers | checkbox | Row dividers | false | Shown when {const rowish=__name(v=>v==="row","rowish");return rowish(sibling?.view)||(sibling?.leadCount??0)>0&&rowish(sibling?.leadView)} |
filterCategories | relationship | Filter by categories | Shown when siblingData?.source!=="fixed"; Related to categories; Multiple values | |
filterPostTypes | text | Filter by post type | Shown when siblingData?.source!=="fixed"; Multiple values | |
filterTags | relationship | Filter by tags | Shown when siblingData?.source!=="fixed"; Related to tags; Multiple values | |
fixedItems | relationship | Posts | Shown when siblingData?.source==="fixed"; Related to posts; Multiple values | |
gapX | number | Items Gap X | 2 | Required |
gapY | number | Items Gap Y | 3 | Required |
highlightFirst | checkbox | Highlight first post | false | |
layoutBg | radio | Background Variant | main | Required; Options: main (Main), alternative (Alternative) |
leadCount | number | Lead posts count | ||
leadView | select | Lead posts layout | grid2 | Shown when (sibling?.leadCount??0)>0; Options: grid2 (Grid (2 columns)), grid3 (Grid (3 columns)), grid4 (Grid (4 columns)), row (Row) |
limit | number | Posts per page | 4 | |
loadMoreButton.align | select | Alignment | center | Shown when siblingData?.loading==="loadMore"; Options: left (Left), center (Center), right (Right) |
loadMoreButton.iconAfter | text | Icon after the title | Shown when siblingData?.loading==="loadMore" | |
loadMoreButton.iconBefore | text | Icon before the title | Shown when siblingData?.loading==="loadMore" | |
loadMoreButton.title | text | Button title | Load more | Shown when siblingData?.loading==="loadMore" |
loadMoreButton.variant | radio | Variant | primary | Shown when siblingData?.loading==="loadMore"; Options: primary (Primary), secondary (Secondary) |
loadMoreButton | group | Load more button | Shown when siblingData?.loading==="loadMore" | |
loading | select | Loading strategy | none | Options: none (None), pagination (Pagination), loadMore (Load more button), infinite (Infinite scroll) |
mediaGap | number | Media ↔ body gap | 3 | Required |
order | select | Order by | date | Shown when siblingData?.source!=="fixed"; Options: date (Publish date), title (Post title) |
padding | number | Padding | 0 | Required |
prepend | richText | Prepend content | ||
rowBodyAlign | select | Body alignment (Row layout) | flex-start | Shown when sibling?.view==="row"; Options: flex-start (Top), center (Center), flex-end (Bottom) |
rowMediaWidth | select | Thumbnail width (Row layout) | 1fr 2fr | Shown when sibling?.view==="row"; Options: 1fr 3fr (Narrow), 1fr 2fr (Default), 2fr 3fr (Wide), 1fr 1fr (Equal halves) |
source | radio | Source | automatic | Options: automatic (Automatic (query)), fixed (Fixed (hand-picked)) |
theme | radio | Color | default | Required; Options: default (Default), dark (Dark) |
view | select | Layout | grid4 | Options: grid2 (Grid (2 columns)), grid3 (Grid (3 columns)), grid4 (Grid (4 columns)), row (Row) |
PostsBlock — a unified listing block (automatic query or fixed picks, view, highlightFirst, the leadCount + leadView lead posts split, dividers, loading). Behaves like a Section block: root-level only (offered in the root editor's BlocksFeature, never inside a region/fragment/slot body) and carrying the same section-level presentation controls — theme (color system), layoutBg (background variant), and padding. The converter wraps the listing in <Section> (Section › Container › Posts), so a color system / background / padding choice behaves exactly as on a Section. Registered only when posts is on; its query result is injected by populateLexicalPostsBlocks before the converter renders <PostsList> inside that section.
The block shares its listing fields with the Archive page template; the full field-set, including the block-only presentation controls, is documented under Template fields.
Rendered outputLink to this section
Renders the PostsList component inside a <Section>, with optional prepend and append region content around it.
ConverterLink to this section
postsConverter reads _archiveData, which populateLexicalPostsBlocks resolves on the server. Without that data it renders nothing. It wraps PostsBlockView in Section and converts the optional prepend and append region editors. Advanced presentation settings merge into the listing's card configuration; row-only controls apply only to the row view.
CustomizingLink to this section
Import PostsBlock from @systhemaui/payload/blocks as the starting schema for a project block. Register the definition and your renderer through customBlocks, using type: 'block' and the editor tiers you intend to support. A distinct slug creates a new block; a converter registered under the existing posts slug takes precedence over the built-in converter. Keep the fields that renderer reads, including populated relationships and nested editor states.
See Registering blocks for the configuration pattern and Converters for the renderer contract. A project converter used in client-mode live preview also needs browser registration.