Documentation

Content Fields & Sections

How a section is built, what the field-name prefixes do, and how to keep every page editable by someone who has never seen the plugin.

A section is four things

Part Holds Who edits it
template_html Markup with {{placeholder}} markers AI, or you in Advanced Mode
content_fields The actual words, images, links, icons Anyone, in Content Mode
scoped_css CSS scoped to this section AI, or you
section_js Optional JS, in an IIFE with section pre-bound AI, or you

The split is the point. Changing the design needs the AI. Changing the content never does.

<!-- template_html -->
<section class="hero">
  <h1>{{title}}</h1>
  <p>{{html_subhead}}</p>
  <img src="{{image_hero}}" alt="{{image_hero_alt}}" loading="lazy" />
  <a class="hero__cta" href="{{cta_url}}">{{cta_label}}</a>
</section>
{
  "title": "Care that starts with listening",
  "html_subhead": "Same-day appointments, <strong>no waiting room</strong>.",
  "image_hero": "https://example.com/wp-content/uploads/hero.jpg",
  "image_hero_alt": "Dentist talking with a patient",
  "cta_url": "/book/",
  "cta_label": "Book a visit"
}

Field name prefixes

The prefix decides how the value is treated on render and which input Content Mode shows.

Prefix Behaviour
(none) Plain text, HTML-escaped
html_ Safe HTML allowed — bold, links, lists
image_ Media picker. Always add a companion *_alt field
icon_ Phosphor icon picker. Value is a kebab-case icon name
shortcode_ Run through do_shortcode() on render

Icons, specifically

Put the placeholder directly inside its container. The renderer replaces it with a complete <span class="ppd-icon">…<svg>…</span>.

<div class="card__icon">{{icon_feature1}}</div>   <!-- right -->
<span data-icon="{{icon_feature1}}"></span>       <!-- wrong: SVG inside an attribute -->

For an icon that shouldn't be editable, hardcode it: <span class="ppd-icon" data-icon="shield-check" data-icon-style="fill"></span>.

Icons inherit currentColor and are sized with CSS on the .ppd-icon span. 104 ship with the plugin; 1,500+ more are fetched on demand. Never use emoji.

Site-level placeholders

These resolve at render time and need no content field:

NoLeemits · https://noleemits.com/ · 2026 · · · · · {{business:social:*}}

Template placeholders — {{post_*}}, {{archive_*}}, {{term_*}}, {{search_query}}, {{paged_*}}, {{loop_wc_*}}, {{main_query}} — are covered in Template System.

Content Mode field types

Attach a content_fields_schema and Content Mode renders a proper labelled form instead of bare text boxes. Per field you can set label, description, type, placeholder, options and required.

Available types: text, textarea, wysiwyg, url, image, icon, number, select, color.

This is UI metadata only — it never changes what renders. Always provide it on any page you hand to someone else.

Content Mode generates a labelled form from the section’s schema.Hover to pause · click for full size
Content Mode generates a labelled form from the section’s schema.

Keeping pages editable

This is the single most important habit, and the plugin enforces it:

When the AI saves a section that is mostly hardcoded text with few or no editable fields, the plugin warns it during the write that Content Mode users won't be able to edit it.

If a section slipped through anyway, its editor shows a notice explaining that its content is hardcoded and pointing at the code editor. The fix is always the same: pull the copy out of template_html and into content_fields.

Rule of thumb: if a human might ever want to change it, it belongs in a content field.

Styling

  • Use design tokens — var(--ppd-colors-primary), var(--ppd-spacing-section-y) and so on. Set them once at Settings → Design Tokens.
  • Never declare --ppd-* variables in page CSS. Tokens are owned by the token system and rendered fresh on every load; declarations in page CSS are stripped on save and on render so a stale hex can't shadow a live token.
  • Give every section a uniquely-classed wrapper.
  • Section CSS is scoped and minified. calc(), clamp(), min(), max() and var() survive minification intact.

Section JavaScript

Use section_js, not a <script> tag in the markup. It runs in an IIFE with section pre-bound:

var btn = section.querySelector('.hero__cta');

Declare libraries in js_dependenciesgsap, scrolltrigger, aos, alpinejs, swiper, splide, plyr, countup, typed, lottie — or pass a full CDN URL. They load only on pages that ask for them.

Prefer CSS. And never use IntersectionObserver on an above-the-fold section — elements already in the viewport on load may never fire the observer and stay stuck at opacity: 0. Use setTimeout for hero entrances.

Reusing sections

  • Section Library — save a section once, insert it into many pages. Edit the library item and every page using it updates. Per-page overrides are available. Library previews snapshot the source page's CSS so they render faithfully.
  • Global sections — header and footer, injected on every page, with per-page overrides and an on/off switch.