{"id":320844,"date":"2026-06-12T20:04:47","date_gmt":"2026-06-12T20:04:47","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/promptless-cpt-pages\/"},"modified":"2026-06-12T20:04:21","modified_gmt":"2026-06-12T20:04:21","slug":"promptless-cpt-pages","status":"publish","type":"plugin","link":"https:\/\/wordpress.org\/plugins\/promptless-cpt-pages\/","author":23458468,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"0.5.3","stable_tag":"0.5.3","tested":"7.0","requires":"5.0","requires_php":"7.4","requires_plugins":null,"header_name":"Promptless CPT Pages","header_author":"Promptless WP","header_description":"Render CPT single pages with structured data display, layout variants, and admin or AI population. Works standalone or with Promptless WP.","assets_banners_color":"","last_updated":"2026-06-12 20:04:21","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"https:\/\/promptlesswp.com","header_author_uri":"","rating":0,"author_block_rating":0,"active_installs":0,"downloads":29,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"0.5.3":{"tag":"0.5.3","author":"promptlesswp","date":"2026-06-12 20:04:21"}},"upgrade_notice":{"0.5.3":"<p>Documentation-only update: the External Services disclosure for the Iconify icon API now meets WordPress.org guidelines \u2014 a direct privacy-policy link, a clearer terms-of-use link, and an explicit note that the icon component is bundled locally rather than loaded from a CDN. No functional change.<\/p>","0.5.2":"<p>Bug fix: post fields (image_overlay, headline, meta_strip, footer_meta) now render correctly on Promptless WP PostGrid cards. Stale function_exists guard from the v0.5.0 rename was silently breaking the entire card hook handler. Recommended for any site using PostGrid with a PCPTPages CPT.<\/p>","0.5.1":"<p>WP.org review round 1 fixes: nonce sanitization, options_json + field_values sanitized at admin boundary, publish_posts cap check on update_post REST, Iconify documented as external service, GitHub auto-updater stripped from WP.org build. No end-user behavior change.<\/p>","0.5.0":"<p>WP.org prefix compliance: pre_\/PRE_ renamed to pcptpages_\/PCPTPages_ (3-char prefix didn&#039;t meet WP.org&#039;s 4-char minimum). Classes, hooks, options, accessor pcptpages() all renamed. class_alias keeps Post_Runtime_Engine working. No end-user behavior change.<\/p>","0.4.1":"<p>WP.org compliance pass. Main class renamed (back-compat alias preserved). Inline scripts\/styles moved to enqueued assets. No data migration. No behavior change for end users.<\/p>","0.3.4":"<p>Connector admin page UI cleanup. Status card now shows connection state at a glance with the kill-switch toggle inline. Setup steps are cleaner. App password check works correctly on local dev environments. No data changes.<\/p>","0.3.3":"<p>Admin meta-box UX rebuild plus icon and content-authoring bug fixes. Icon picker is now a category-grouped dropdown; Iconify text input still accepts 200,000+ codes. Variant gating prevents image-upload buttons from showing on icon-only layouts. Recommended for all users.<\/p>","0.3.2":"<p>Icon system is now dual-format: curated IDs keep working alongside any Iconify code (200,000+ icons). Admin dropdown becomes a text input + quick-pick row. No data migration required. Recommended for all users.<\/p>","0.3.1":"<p>Compatibility update \u2014 passes WordPress.org Plugin Check cleanly. No feature or behavior changes.<\/p>"},"ratings":[],"assets_icons":{"icon-256x256.png":{"filename":"icon-256x256.png","revision":3570491,"resolution":"256x256","location":"assets","locale":"","width":256,"height":256}},"assets_banners":[],"assets_blueprints":{},"all_blocks":[],"tagged_versions":["0.5.3"],"block_files":[],"assets_screenshots":[],"screenshots":{"1":"Admin UI for registering a custom post type \u2014 name, slug, labels, icon picker, archive on\/off","2":"Grouping definitions per CPT \u2014 define a named cluster of items sharing a layout variant and a position (above main \/ below main \/ sidebar)","3":"The per-post meta box for filling in grouping items, with the four layout-variant preview cards","4":"Frontend render of a CPT single page with the compact-grid variant for an \"amenities\" grouping","5":"Claude Cowork connector setup \u2014 opt-in App Password generation, default-disabled kill switch"}},"plugin_section":[],"plugin_tags":[2010,1487,20731,23364,129283],"plugin_category":[],"plugin_contributors":[265095],"plugin_business_model":[],"class_list":["post-320844","plugin","type-plugin","status-publish","hentry","plugin_tags-custom-fields","plugin_tags-custom-post-types","plugin_tags-post-template","plugin_tags-single-page","plugin_tags-structured-content","plugin_contributors-promptlesswp","plugin_committers-promptlesswp"],"banners":[],"icons":{"svg":false,"icon":"https:\/\/ps.w.org\/promptless-cpt-pages\/assets\/icon-256x256.png?rev=3570491","icon_2x":"https:\/\/ps.w.org\/promptless-cpt-pages\/assets\/icon-256x256.png?rev=3570491","generated":false},"screenshots":[],"raw_content":"<!--section=description-->\n<p>Promptless CPT Pages provides a constrained, opinionated primitive for repeatable structured content on custom-post-type single pages:<\/p>\n\n<ul>\n<li>Register custom post types from an admin UI \u2014 no ACF \/ MetaBox \/ Pods dependency.<\/li>\n<li>Define \"groupings\" per CPT \u2014 named clusters of items sharing a layout variant and a position (above main \/ below main \/ sidebar).<\/li>\n<li>Items follow one shape \u2014 <code>{ image-or-icon, heading, supporting_text, optional link }<\/code>.<\/li>\n<li>Four layout variants per grouping \u2014 compact-grid, card-grid, featured-card, horizontal-row.<\/li>\n<li>Three source modes \u2014 <code>manual<\/code>, <code>child_posts<\/code>, <code>taxonomy_match<\/code>.<\/li>\n<li>Curated icon library of 53 icons across 13 categories, extensible via the <code>pre_icon_library<\/code> filter.<\/li>\n<li>Connector REST API + MCP tools (18 endpoints under <code>\/wp-json\/post-runtime\/v1\/connector\/<\/code>) so AI assistants like Claude Cowork can register CPTs, define groupings, populate per-post values, and preview rendered output.<\/li>\n<li>Design-token inheritance from Promptless WP \u2014 colors, spacing, typography, radii. Graceful fallback when Promptless is not installed.<\/li>\n<\/ul>\n\n<p>Promptless CPT Pages is positioned as a free companion plugin to Promptless WP (the page builder) and Promptless Forms (the form renderer). It owns dynamic CPT single-page rendering; it does not replace Promptless for landing-page composition or Promptless Forms for forms.<\/p>\n\n<h3>External Services<\/h3>\n\n<p>This plugin connects to one third-party service: the Iconify API. It is used solely to display icons that you choose to use, and only when you opt into using them. If you do not use Iconify icons, no external service is ever contacted.<\/p>\n\n<h4>Iconify API<\/h4>\n\n<p>What it is and what it is for: the plugin bundles the open-source <code>iconify-icon<\/code> web component locally (<code>assets\/js\/iconify-icon.min.js<\/code> \u2014 it is shipped inside the plugin and is NOT loaded from any CDN). When a CPT single page, archive card, grouping item, or post field uses an Iconify-format icon identifier written in <code>collection:name<\/code> form (for example <code>mdi:home<\/code> or <code>material-symbols:business-outline<\/code>), the web component requests that single icon's SVG path data from the Iconify API at render time so the icon can be displayed. This is what makes 200,000+ open-source icons available without bundling them all into the plugin.<\/p>\n\n<p>What data is sent, and when: only the icon identifier you chose to use (for example <code>mdi:home<\/code>) is sent, as part of the request URL, at the moment a page containing that icon is viewed in a visitor's browser. The request is made by the visitor's browser \u2014 not by your server. No personal data, no user content, no site URL, and no identifiers of any kind are transmitted.<\/p>\n\n<p>When it is NOT contacted: the plugin also ships a built-in library of 53 icons that render inline as SVG with zero network requests. If you use only those built-in icons \u2014 or no icons at all \u2014 the Iconify API is never contacted.<\/p>\n\n<p>Service provider: Iconify (Iconify O\u00dc).<\/p>\n\n<p>Endpoints contacted: https:\/\/api.iconify.design (primary), with https:\/\/api.simplesvg.com and https:\/\/api.unisvg.com as automatic fallbacks used only if the primary endpoint is unreachable.<\/p>\n\n<p>Terms of use: https:\/\/iconify.design\/docs\/api\/ \u2014 the Iconify API is a free, open-source public service released under the Apache 2.0 License; the \"Public API\" section documents the terms of use.<\/p>\n\n<p>Privacy policy: https:\/\/iconify.design\/privacy\/<\/p>\n\n<!--section=installation-->\n<ol>\n<li>Upload the plugin folder to <code>\/wp-content\/plugins\/<\/code> or install via WP Admin \u2192 Plugins \u2192 Add New \u2192 Upload Plugin.<\/li>\n<li>Activate the plugin through the <strong>Plugins<\/strong> screen in WordPress.<\/li>\n<li>Visit <strong>Post Runtime \u2192 CPTs<\/strong> in the admin to register your first custom post type.<\/li>\n<li>To enable the Claude Cowork connector, visit <strong>Post Runtime \u2192 Claude Connection<\/strong> and follow the setup steps.<\/li>\n<\/ol>\n\n<p>For full documentation see <code>CLAUDE.md<\/code> and <code>docs\/<\/code> inside the plugin folder.<\/p>\n\n<!--section=faq-->\n<dl>\n<dt id=\"does%20this%20plugin%20require%20promptless%20wp%3F\"><h3>Does this plugin require Promptless WP?<\/h3><\/dt>\n<dd><p>No. PRE renders standalone with sensible default styling. When Promptless WP is active, PRE automatically inherits its <code>--aisb-*<\/code> design tokens for visual consistency.<\/p><\/dd>\n<dt id=\"can%20i%20use%20existing%20acf%20%2F%20metabox%20fields%20with%20groupings%3F\"><h3>Can I use existing ACF \/ MetaBox fields with groupings?<\/h3><\/dt>\n<dd><p>Not in this version. Promptless CPT Pages owns its own field model end-to-end via grouping items. ACF interop is out of scope for v0.x.<\/p><\/dd>\n<dt id=\"where%20is%20the%20data%20stored%3F\"><h3>Where is the data stored?<\/h3><\/dt>\n<dd><p>Per-post grouping values live in WordPress post meta. CPT and grouping definitions live in <code>wp_options<\/code>. No custom database tables.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>0.5.3<\/h4>\n\n<ul>\n<li>WordPress.org review round 2: rewrote the Iconify External Services disclosure with a direct privacy-policy link (https:\/\/iconify.design\/privacy\/), a clearer terms-of-use link, an explicit note that the icon web component is bundled locally (not loaded from a CDN), and a precise data \/ when \/ endpoints breakdown. Also synced this changelog with the full version history. No code or behavior change.<\/li>\n<\/ul>\n\n<h4>0.5.2<\/h4>\n\n<ul>\n<li>Fixed: post fields (image_overlay, headline, subtitle, meta_strip, footer_meta) now render correctly on Promptless WP PostGrid cards. A stale <code>function_exists( 'pre' )<\/code> guard left over from the v0.5.0 accessor rename was silently no-op'ing the entire card hook handler. No data migration.<\/li>\n<\/ul>\n\n<h4>0.5.1<\/h4>\n\n<ul>\n<li>WordPress.org review round 1 fixes: nonce sanitization before wp_verify_nonce(), options_json and field_values sanitized at the admin boundary, a publish_posts capability check on the update_post REST handler, Iconify documented as an external service, and the GitHub auto-updater fully stripped from the WordPress.org build. No end-user behavior change.<\/li>\n<\/ul>\n\n<h4>0.5.0<\/h4>\n\n<ul>\n<li>WordPress.org prefix-compliance rename: the 3-character <code>pre_<\/code> \/ <code>PRE_<\/code> prefix (below WP.org's 4-character minimum) was re-prefixed to <code>pcptpages_<\/code> \/ <code>PCPTPages_<\/code> across classes, hooks, options, the <code>pcptpages()<\/code> accessor, script handles and admin page slugs. <code>class_alias<\/code> keeps the old main-class name working. No data migration; no end-user behavior change.<\/li>\n<\/ul>\n\n<h4>0.4.1<\/h4>\n\n<ul>\n<li>WordPress.org compliance pass. Class <code>Post_Runtime_Engine<\/code> renamed to <code>Promptless_CPT_Pages<\/code> (<code>class_alias<\/code> preserves backward compatibility for the old name). GitHub auto-updater instantiation gated by <code>class_exists<\/code> so the WP.org build (which excludes the updater) doesn't fatal. All inline <code>&lt;script&gt;<\/code> \/ <code>&lt;style&gt;<\/code> blocks moved to enqueued asset files (<code>assets\/css\/connector-admin.css<\/code>, <code>assets\/js\/connector-admin.js<\/code>, <code>assets\/js\/admin-groupings.js<\/code>), gated to their own admin pages. <code>esc_url_raw<\/code> \u2192 <code>esc_url<\/code> in one JS output context. Plugin URI, contributors username, and dev-internal markdown file exclusions corrected for the WP.org build. No data migration. No behavior change for end users.<\/li>\n<\/ul>\n\n<h4>0.3.3<\/h4>\n\n<ul>\n<li>New: Admin meta-box icon picker rebuilt as a compact <code>&lt;select&gt;<\/code> dropdown grouped by icon category \u2014 replaces the 53-button visual quickpick grid that was burning ~330px of vertical space per item. The Iconify text input above the dropdown is unchanged, so any of the 200,000+ Iconify codes can still be typed directly when the curated 53 don't have what you need.<\/li>\n<li>New: Per-grouping variant gating in the meta box. When a grouping's effective layout variant is icon-only (compact-grid or horizontal-row), the \"Add image\" button hides per-item and an amber notice appears at the top of the grouping explaining that uploaded images are dropped at render time. Mirrors PRE_Renderer's variant-aware media resolution so the meta box never silently accepts data the renderer will discard.<\/li>\n<li>New: <code>--pre-icon-size<\/code> CSS custom property drives icon dimensions on the frontend. Every per-variant override sets one value and width \/ height \/ font-size all pick it up, keeping legacy SVG icons and Iconify web components rendered at matching sizes. Adding a new variant in the future automatically gets correct sizing for both render paths.<\/li>\n<li>New: Server-side HTML\u2192Gutenberg blocks converter in the connector. <code>POST \/posts<\/code> and <code>PUT \/posts\/{id}<\/code> now auto-wrap raw HTML in proper Gutenberg block delimiters when the input has no <code>&lt;!-- wp: --&gt;<\/code> markers. Idempotent \u2014 block-format input passes through unchanged with zero parsing cost. Handles h1-h6 (with level attr for non-h2), p, ul \/ ol (with ordered:true attr), blockquote, pre, hr, and figure-with-img; unrecognized top-level elements fall through to core\/html, matching what Gutenberg's \"Convert to blocks\" does.<\/li>\n<li>New: <code>critical_rules.post_content_is_gutenberg_blocks<\/code> replaces <code>post_content_is_html<\/code> in the connector preflight, documenting the canonical block-format contract with examples for every supported block type. The server converter is described as a defense-in-depth safety net, not a feature \u2014 AI agents that send block format directly get faster writes and full control over block attributes (heading levels, list types).<\/li>\n<li>Improved: Item layout in the admin meta box. Item height shrunk 360px \u2192 229px (36% smaller), media column width reduced 220px \u2192 160px (frees horizontal space for the fields column), preview tile 96\u00d796 \u2192 64\u00d764, icon helper text compressed to a single line.<\/li>\n<li>Fixed: Image upload silently failed on profile cards (card-grid + featured-card variants). Root cause: <code>setItemImage<\/code> referenced an undefined <code>$iconSelect<\/code> variable carried over from when the icon picker was a single <code>&lt;select&gt;<\/code> element. The <code>ReferenceError<\/code> threw after image_id was stored in the hidden input but before the thumbnail preview rendered, so the image was persisted on save with no visual confirmation. <code>$iconSelect<\/code> is now properly scoped from <code>$item.find('.pre-item__icon-select')<\/code> and the function runs to completion.<\/li>\n<li>Fixed: Iconify icon sizing mismatch on the frontend. <code>&lt;iconify-icon&gt;<\/code> web components were rendering their inner shadow-DOM SVG at 1em (16px default font-size) instead of matching the element's CSS width\/height, so an Iconify code like <code>fluent:chat-20-regular<\/code> painted at 16\u00d716 inside a 32\u00d732 wrapper \u2014 visibly smaller than the curated SVG icons next to it. The single-source-of-truth <code>--pre-icon-size<\/code> variable now drives font-size alongside width\/height, so both render paths land at the same size for every variant.<\/li>\n<\/ul>\n\n<h4>0.3.2<\/h4>\n\n<ul>\n<li>New: Dual-format icon system. <code>icon_id<\/code> and <code>default_icon<\/code> now accept BOTH the existing curated 53-icon library AND any Iconify code in <code>collection:name<\/code> form (e.g. <code>mdi:home<\/code>, <code>logos:wordpress<\/code>, <code>material-symbols:business-outline<\/code>, <code>fa6-solid:tooth<\/code>). Curated IDs render as inline SVG (zero network), Iconify codes render via the <code>&lt;iconify-icon&gt;<\/code> web component. ~200,000 additional icons across 100+ Iconify sets, browseable at icon-sets.iconify.design. Restores icon vocabulary parity with Promptless WP for connector-driven page-building workflows.<\/li>\n<li>New: Admin meta-box icon control rewritten as a monospace text input + a 28-px-thumb quick-pick row of the curated 53. Type any Iconify code; the preview updates live. Click a quick-pick to insert a curated ID. Single picker covers both formats.<\/li>\n<li>New: Connector <code>GET \/icons<\/code> response gains an <code>iconify<\/code> block (format pattern, browse URL, full legacy \u2192 Iconify map, render-pattern hint) and a per-icon <code>iconify_code<\/code> field so AI consumers learn the dual-format contract in one round trip. The MCP <code>postruntime_list_icons<\/code> description rewritten accordingly.<\/li>\n<li>New: <code>PRE_Icon_Library::is_valid_id()<\/code>, <code>is_iconify_format()<\/code>, <code>legacy_to_iconify()<\/code>, <code>get_legacy_iconify_map()<\/code>, plus <code>MAX_ICONIFY_LENGTH<\/code> constant. Public surface so themes \/ third-party plugins can validate icon IDs the same way the plugin does.<\/li>\n<li>Changed: Validator switches from <code>PRE_Icon_Library::has()<\/code> to <code>is_valid_id()<\/code> at both call sites (CPT default_icon, grouping item icon_id). Error messages now point at both discovery paths.<\/li>\n<li>Changed: Frontend asset enqueue adds the iconify-icon web-component module (~20kb gzipped, jsdelivr CDN) on registered CPT singles so Iconify codes paint correctly without per-page detection. Same module Promptless WP enqueues \u2014 browser caches one copy across pages.<\/li>\n<li>Internal: 15 new smoke assertions in <code>tests\/smoke-phase1.php<\/code> + two new unit-test methods in <code>tests\/Unit\/ValidatorTest.php<\/code> covering accept (5 Iconify formats) and reject (6 malformed shapes including over-length and uppercase) paths.<\/li>\n<\/ul>\n\n<h4>0.3.1<\/h4>\n\n<ul>\n<li>Plugin-checker compliance pass: relocated translator comments to satisfy <code>WordPress.WP.I18n.MissingTranslatorsComment<\/code>, swapped <code>parse_url()<\/code> for <code>wp_parse_url()<\/code>, added <code>phpcs:ignore<\/code> reasons to trusted-internal output sites where the Icon Library's SVG is surfaced.<\/li>\n<\/ul>\n\n<h4>0.3.0<\/h4>\n\n<ul>\n<li>Hosted pressure-test hardening: connector now ships a <code>critical_rules<\/code> rulebook and <code>field_name_hints<\/code> in preflight, defensive CDATA sanitization on <code>post_content<\/code>, link-aware cross-CPT <code>default_icon<\/code> resolution, <code>postruntime_update_post<\/code> tool, and a <code>_site<\/code> envelope on every connector response. Smoke suite extended from 99 to 138 assertions.<\/li>\n<\/ul>\n\n<h4>0.2.0<\/h4>\n\n<ul>\n<li>Frontend rendering: all four layout variants (compact-grid, card-grid, featured-card, horizontal-row) and three source modes (manual, child_posts, taxonomy_match).<\/li>\n<\/ul>\n\n<h4>0.1.0<\/h4>\n\n<ul>\n<li>Initial release: CPT registry, grouping definitions, admin meta box with variant override, three layout positions, single-position rendering.<\/li>\n<\/ul>","raw_excerpt":"Render CPT single pages with structured data display, layout variants, and admin or AI population. Works standalone or with Promptless WP.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/320844","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=320844"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/promptlesswp"}],"wp:attachment":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=320844"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=320844"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=320844"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=320844"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=320844"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=320844"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}