Skip to Content
ConceptsFor WordPress Developers

Concepts for WordPress Developers

Most of our team comes from WordPress, so this page exists to be direct about where the analogy in Concepts holds up and where it doesn’t: methodology, not just terminology. Everything linked below is confirmed elsewhere in this documentation; this page is the WordPress-shaped index into it.

Terminology, fuller than the quick table

WordPressP1Where it actually differs
A WP install (wp-config.php, one database)A SiteOne Site pairs with one Next.js codebase and one CCR content backend. See Sites, branches, and workstreams.
Post / Page (wp_posts row)DocumentSame idea, different storage: a document is a CCR object at a path, not a DB row with a post_status column. See Workflows.
Draft → Publish (post_status)Autosave → Publish → CheckpointNot a status field. Publish is an explicit API call that creates a checkpoint; the public read path only ever serves checkpoints. See Publishing.
RevisionsVersionsEvery autosave creates one, same spirit as WP revisions. See Publishing.
TrashSoft delete + restore()Same idea. See Publishing.
Staging site / manual syncBranch (Workstream) + real mergeA true fork/merge, not a plugin-driven file/DB copy. See Branches.
Custom Post Type + ACF Field GroupTemplateMetadata (name, label, URL pattern) is scriptable; the actual field layout is not: it’s built by hand in the Puck editor, every time. See Templates.
Gutenberg blockPuck componentA plain JS/TS object, not a PHP render callback + block.json + JS edit/save pair. See Components: Puck’s answer to blocks.
ACF fieldPuck fieldDeclared inline on the component, not a separately-managed field group. See Fields Reference.
User role (Administrator/Editor/Author/Contributor)ContentRole (admin/editor/author/junior-editor)Names line up almost exactly, but P1’s roles only govern structural editing rights in the Puck canvas: much coarser than WP’s full capability system. See Permissions & Roles.
functions.php / a custom plugin(no direct equivalent)See “Habits to unlearn” below.

Content modeling: register_post_type + ACF → Template

In WordPress, standing up a new content type is code you write once (register_post_type(), an ACF field group) and content editors then use forever without touching it again. In P1, Template creation is metadata-only: name, label, description, URL pattern can be scripted via the Templates API, but the component layout itself has no write API at all. Someone has to build it by hand in the Puck editor, and there’s no register_post_type()-with-fields shortcut. This is confirmed directly from CreateTemplateParams’ own type comment: “Metadata only; the layout is authored on the editor canvas afterwards.” See Templates for the full mechanics, and Products Template / Cocktails Template for what that looked like in practice on a real brand site.

The upside WordPress doesn’t have: changing a Template’s structure after real content already exists against it comes with dry-run previews and one-call rollback, self-serve. See Templates. A WP developer’s usual dread of “we need to add a field to 4,000 existing posts” has a real answer here.

Publishing: Draft/Publish → autosave/Publish/Checkpoint

WordPress shows you the state on the page (post_status: draft|publish). P1’s equivalent has no visible status field: it’s autosave-as-draft-version, with an explicit Publish action that creates a checkpoint the public site actually reads from. Easy to miss coming from WP, because there’s nothing in the editor UI that visually says “draft” the way WordPress does. Full mechanics, confirmed from the SDK source: Publishing.

Staging & multi-environment: no plugin, a real branch

WordPress staging is typically a second install (a host’s staging environment, or a migration plugin) you later sync back to production: file copies and DB merges, essentially. P1’s Workstream is an actual branch with a real merge operation (checkMergeabilitypreviewexecute, or a full merge-request review flow closer to a GitHub PR than anything native to WordPress). See Branches.

Multisite has no equivalent. WordPress Multisite (one codebase, one database, many independently-managed subsites via Network Admin) doesn’t map onto anything in P1. A P1 Site is closer to a single normal WP install than to a multisite network node: there’s no shared-codebase-many-subsites concept, and (confirmed directly from SitesEndpoint, which only exposes get() and list()) no API to clone or duplicate a site’s content into a new one. If your team has used WP Multisite to stand up per-market subsites before, read Localization: it addresses this exact question and lays out what building the equivalent on P1 would actually take.

Blocks → components: no PHP, no block.json

A Gutenberg block is a block.json manifest, a JS edit/save pair (or dynamic rendering via a PHP callback), registered through register_block_type(). A Puck component is one plain object (label, fields, defaultProps, render) imported into puck.config.tsx. No manifest file, no PHP, no separate registration call; the object is the registration. See Components: Puck’s answer to blocks for the shape, and Components Reference for what ships out of the box.

Things WordPress gives you for free that P1 doesn’t

WordPress core (or one install-and-activate plugin) covers a lot of ground P1 leaves for you to build. Confirmed absent, each with the plan for filling it:

  • Menus & widget areas (Appearance → Menus, sidebar widgets): nothing built in. See Managing the Header & Footer.
  • A form builder (Gravity Forms, WPForms, Contact Form 7): nothing native to P1 or Puck. See Form Builder.
  • Form entry storage (Gravity Forms’ own entries table) and SMTP/transactional email (WP Mail SMTP and similar): P1 has neither. See Form Builder → Submission Storage and Email Delivery.
  • An SEO plugin (Yoast, RankMath): P1’s per-page SEO/OG fields are real and built in, but sitemap.xml, robots.txt, and JSON-LD structured data are not generated automatically the way an SEO plugin gives you on install. See SEO & GEO.
  • The Media Library’s automatic responsive images: WordPress core has generated multiple image sizes and a srcset automatically since 4.4. Nothing in @pantheon-systems/p1-media’s exported surface produces a srcset for you; each component controls exactly one delivered width/height/format per call. See Media Library.
  • A plugin directory: there’s no P1-equivalent marketplace of install-and-activate extensions. Extending a site means installing an npm package (like p1-media) or building a component yourself; there’s no ecosystem of third-party P1 plugins to browse.

Habits to unlearn

  • No functions.php. There’s no single “put your customizations here” file: logic lives in Next.js route handlers, Puck components, and installed packages.
  • No template hierarchy (single.php, archive-product.php, etc.). Rendering is driven by Templates and dynamic routes, not a file-naming convention. See Dynamic (templated) routes.
  • No hooks/filters system. There’s no add_action/add_filter equivalent for hooking into core behavior; extension points are whatever a package’s own config object exposes (see how p1-media’s fieldNamePatterns or p1-form-builder’s webhookAllowlist work as the closest analogs).
  • No wp-admin. The P1 dashboard (content.pantheon.io) and the in-page Puck editor cover content authoring; there’s no separate settings/plugins/users admin screen the way wp-admin bundles everything into one place.
Last updated on