Help us improve
Share bugs, ideas, or general feedback.
From data-liberation
Guides generating WordPress block patterns for themes, with rules for page-builder content (Shopify, Replo, Wix, Squarespace, Shogun) and verbatim copy requirements.
How this skill is triggered — by the user, by Claude, or both
Slash command
/data-liberation:generating-patternsThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Use this skill when generating block patterns for a theme.
Share bugs, ideas, or general feedback.
Use this skill when generating block patterns for a theme.
Load this skill alongside creating-themes or editing-themes when patterns are part of the work.
Page-builder storefronts emit div-soup markup (no semantic <section> tags) and rich, repeated components that are easy to flatten into generic static/columns blocks. Don't. The section spec's Interaction model carries the real shape — honor it and pick the matching template in references/section-mapping.md:
project-card-grid/columns. Keep prices verbatim; link to the local product page or WooCommerce.★ glyph run so it survives without a JS widget; render the captured reviews as a static, mobile-safe grid. Review/testimonial text is NEVER synthesized — source-captured verbatim or placeholdered, full stop. It is sourced (in order) from spec.reviews (the deterministic review-extract.ts extractor populates it from the served HTML), the inline carousel markup in the captured HTML, embedded JSON (schema.org Review, warmup blobs), or the widget's plain-GET JSON API. "The reviews are a JS widget" is usually false — page-builder carousels render every slide inline. Only when ALL of those fail is the band placeholdered + flagged. See the review-grid template and Missing-content fallback in references/section-mapping.md.core/search input+button (forms have no backend in the replica) and stub the real integration in the framework-widget table.The extractor now captures page-builder CDN imagery (Replo assets.replocdn.com, Shogun, image proxies) regardless of host or file extension. The faithful imagery is in the media library — use it. Do not fall back to unrelated product photos for hero/lifestyle/app slots.
Every word of visible text a pattern emits — headings, subheads, body paragraphs, list items, button/label text, review quotes — MUST be the source's captured text, reproduced verbatim, OR a clearly-marked missing-content placeholder + run-report flag. Never synthesize, paraphrase, reword, "tighten," "improve," or invent copy to fill a slot. This is not limited to reviews; it governs all prose. Reproducing copy verbatim is the whole point of a replica — paraphrase is a fidelity lie that silently rewrites the source's own words.
Where the source text lives, in order:
spec.headings, spec.buttonLabels.spec.bodyText (every captured <p>/<li> text node, verbatim — see SectionSpec.bodyText). If a template slot wants body copy that is not in spec.bodyText, do NOT write your own — re-read the section's captured html/<slug>.html and pull the real line. If the source genuinely has no text for that slot, leave the slot out or use the missing-content placeholder; never fabricate.spec.reviews → inline carousel HTML → embedded JSON → widget GET API (see review-grid).Allowed differences from the raw source byte stream are only mechanical renderings: HTML-entity encoding (’, , &), whitespace collapse, and typographic-glyph folding (smart quotes ↔ straight, en/em dash ↔ hyphen, ellipsis char ↔ ...). Anything beyond that — a different word, a reordered clause, a "punchier" rewrite — is paraphrase and is rejected.
This is enforced deterministically: liberate_validate_artifacts checks emitted text against the captured source. Headings must each be contained in a single spec.expectedText entry; body paragraphs must be substantially contained in spec.expectedText ∪ spec.bodyText — a reworded paragraph HARD-FAILS the gate (not a warning). You may not bypass that gate. An earlier getsnooz build paraphrased section body copy ("Real fan-powered sound — no loops…", "Your best shut-eye, guaranteed.") and invented three testimonials while the real lines sat in the captured HTML the whole time — exactly the failure this rule and gate exist to stop.
If a section spec references an image that could not be captured (cross-origin, 403/expired CDN, rejected content-type), emit a sized placeholder that preserves the layout slot, flag it in run-report.json (details.provenanceFlags + bump summary.provenanceFlags), and never substitute an unrelated image as if it were the source. A confident wrong image hides the extraction failure and produces a plausible-but-wrong replica — the exact mistake behind the first getsnooz build.
The same rule governs all text (per the cardinal rule above), most acutely review/testimonial copy. Never synthesize, paraphrase, or invent review quotes, author names, ratings, category labels, headings, or body paragraphs. They are source-captured verbatim or rendered as a clearly-marked placeholder ([review text not captured], or for body copy [copy not captured]) plus a run-report flag — never fabricated, and never bypass the liberate_validate_artifacts provenance gate (text ⊆ captured source). An earlier getsnooz build invented three testimonials AND paraphrased section body copy, and manually skipped that gate; the real text was in the captured HTML the entire time. See Missing-media fallback, Missing-content fallback (review/testimonial text), and the review-grid sourcing order in references/section-mapping.md.
patterns/ directoryhero-split.php, faq-accordion.php)spec.headings / spec.bodyText / spec.buttonLabels / spec.reviews (or placeholdered + flagged). Do not write your own headlines, body, or CTAs.<inner-blocks> or assume external contextEvery pattern file must begin with this PHP comment block:
<?php
/**
* Title: Hero Split
* Slug: theme-slug/hero-split
* Categories: featured, banner
* Keywords: hero, split, cta
* Block Types: core/template-part/content
*/
?>
Title: Human-readable name shown in the inserterSlug: Must be theme-slug/pattern-name using the theme's text domainCategories: Comma-separated list (use WordPress defaults: featured, banner, text, gallery, call-to-action, about, team, testimonials, contact, footer, header)Keywords: Comma-separated search terms for discoverabilityBlock Types: Optional — restricts where the pattern appearsWhen generating patterns for a landing page theme, include a varied set that covers the full page flow. Choose patterns that match the site type and audience — not every site needs the same set.
Recommended baseline (adapt per site type):
If a pattern reconstructs the site header (or a header part), it MUST mirror the SOURCE header:
core/image / core/site-logo), not core/site-title text and not a product image.core/navigation-links for the source's top-level primary menu only (label + href). NEVER use core/page-list — it dumps every published WP page (Sample Page, Checkout, account, recall pages) as junk that does not reflect the source's menu.@font-face → assets/fonts/ → theme.json fontFamilies).wp:buttons with clear, action-oriented text ("Get Started", "Book a Demo", "View Portfolio")Two-column split: heading + paragraph + CTA button on the left, full-height image on the right. Use wp:columns with a 55/45 or 60/40 split. The text column gets vertical centering; the image column uses object-fit: cover at full height.
Columns (align: full)
└── Column (width: 55%, verticalAlignment: center)
│ └── Heading (h1)
│ └── Paragraph
│ └── Buttons
└── Column (width: 45%)
└── Image (style: height 100%, object-fit: cover)
Alternate the position of text and image across consecutive sections to create a natural Z reading flow. Odd sections place text left / image right; even sections flip to image left / text right.
Section 1 — Columns (align: wide)
└── Column (text) | Column (image)
Section 2 — Columns (align: wide)
└── Column (image) | Column (text)
Section 3 — Columns (align: wide)
└── Column (text) | Column (image)
Use alternating background colors (light/dark) between sections to reinforce separation.
Three equal-width columns, each containing an icon or image, a heading, a paragraph, and an optional CTA. Use the equal-cards pattern from the card-layouts reference.
Columns (className: "equal-cards", align: wide)
└── Column (width: 33.33%, verticalAlignment: stretch)
│ └── Group
│ └── Image (icon or illustration)
│ └── Heading (h3)
│ └── Paragraph
│ └── Buttons (className: "cta-bottom") [optional]
└── Column (width: 33.33%, verticalAlignment: stretch)
│ └── Group
│ └── ...
└── Column (width: 33.33%, verticalAlignment: stretch)
└── Group
└── ...
Wrap each section in a wp:group with a contrasting background color. Pull colors from the theme palette — use has-{color}-background-color classes or inline backgroundColor attributes. Alternate between the theme's base and contrast colors.
Group (align: full, backgroundColor: base)
└── [section content]
Group (align: full, backgroundColor: contrast)
└── [section content with inverted text color]
Group (align: full, backgroundColor: base)
└── [section content]
A fixed-position bar at the bottom of the viewport with a single CTA. Use a full-width Group with custom CSS class for sticky positioning.
Group (align: full, className: "sticky-cta")
└── Buttons (layout: center)
└── Button ("Get Started Now")
Required CSS (style.css):
.sticky-cta {
position: fixed;
bottom: 0;
left: 0;
right: 0;
z-index: 50;
padding: 1rem;
}
Use the wp:details block for collapsible FAQ items inside a constrained-width Group.
Group (align: wide, layout: constrained)
└── Heading (h2, "Frequently Asked Questions")
└── Details (summary: "Question one?")
│ └── Paragraph (answer)
└── Details (summary: "Question two?")
│ └── Paragraph (answer)
└── Details (summary: "Question three?")
└── Paragraph (answer)
A single row of client or partner logos. Use a wp:columns block with evenly spaced columns, each containing a centered image. Keep logos grayscale or muted to avoid visual clutter.
Group (align: wide)
└── Paragraph (align: center, "Trusted by leading companies")
└── Columns (align: wide)
└── Column (width: 16.66%) → Image (logo, centered)
└── Column (width: 16.66%) → Image (logo, centered)
└── Column (width: 16.66%) → Image (logo, centered)
└── Column (width: 16.66%) → Image (logo, centered)
└── Column (width: 16.66%) → Image (logo, centered)
└── Column (width: 16.66%) → Image (logo, centered)
Not every site needs the same patterns. Adapt the set to the context:
When invoked as a builder subagent by the /liberate or /replicate-with-blocks orchestrator, you MUST return your output as a structured JSON envelope — not free-form prose:
{
"patterns": [
{ "slug": "theme-slug/hero-split", "php": "<?php\n/**\n * Title: Hero Split\n * ...\n */\n?>\n<!-- wp:group ... -->" }
],
"sitewideFlags": [],
"notes": []
}
patterns — array of objects with slug (the pattern's registered slug, matching the file header) and php (the full pattern file contents as a string, including the PHP comment header).sitewideFlags — optional array of strings naming sitewide concerns (e.g. "commercial-font-reckless", "missing-mobile-hero-image").notes — optional array of strings with builder observations or deferred items.Section markup comes from the references/section-mapping.md catalog. Emit all source-derived text as literal, pre-escaped HTML in the markup itself — HTML-entity-escape &, <, > (and quotes inside attributes) at authoring time. Do not wrap visible text in <?php echo esc_html(…) ?> / esc_attr(…): liberate_validate_artifacts sanctions exactly TWO PHP forms — the pattern's doc-comment header and <?php echo esc_url( get_theme_file_uri('assets/…') ); ?> for theme-shipped asset paths (see section-mapping.md) — and treats ANY other <?php, including esc_html('literal'), as injection. So: visible text → literal escaped HTML; theme-asset URLs → esc_url( get_theme_file_uri(…) ); nothing else emits PHP. The result must pass liberate_validate_artifacts (escaping/injection + provenance). A malformed or partial return — missing patterns, wrong types, raw <?php outside the two sanctioned forms — is treated as a builder failure and triggers a retry or sequential fallback. Never return partial results silently.
npx claudepluginhub automattic/data-liberation-agent --plugin data-liberationGenerates WordPress Full Site Editing block themes: theme.json configs, block templates, template parts, patterns, functions.php, and styles.
Generates WordPress block themes from scratch, focusing on home pages with FSE compatibility and theme.json config.
Creates WordPress block patterns from Figma designs or screenshots, generating PHP pattern files, SCSS stylesheets, and editor styles with accessibility and responsive defaults.