Renders any WordPress entity (post, page, etc.) as an iframe. Supports toggling the iframe on/off via the Interactivity API, making it useful for creating toggleable embedded content displays.
| Property | Value |
|---|---|
| Namespace | prc-block/entity-as-iframe |
| Category | embed |
| Version | 0.1.0 |
| API Version | 3 |
| Example | Yes (iframeTemplate: content — inserter preview) |
Assets: block.json registers the frontend module as viewScriptModule (formerly viewModule).
| Feature | Value |
|---|---|
| Anchor | true |
| HTML editing | false |
| Block gap | true |
| Spacing margin | true (default controls enabled) |
| Spacing padding | true (default controls enabled) |
| Interactivity | true |
| Attribute | Type | Default | Description |
|---|---|---|---|
ref |
number |
— | The post/entity ID to render as an iframe. |
allowedBlocks |
array |
— | Override the default list of allowed inner blocks (for the entity editor in the block editor). |
iframeTemplate |
string |
content |
Embeds output variant: content (post body / core/post-content only, no theme iframed-post-content part) or branded (legacy full iframe chrome when applicable). Sent as iframeTemplate on the iframe URL. |
The block loads …/iframe/ with:
| Parameter | Values | Default | Purpose |
|---|---|---|---|
prc_entity_iframe |
1 |
— | Marks requests from this block; suppresses branded masthead/title when combined with defaults. |
iframeTemplate |
content, branded |
omitted (branded behavior for plain /iframe/ URLs without the param) |
content: minimal body output (no theme iframed-post-content template part, no branded header). branded: previous full-iframe behavior including optional template part and masthead when not in entity-only mode. |
The embeds layer (@prc/embeds) reads iframeTemplate on /iframe/ requests. Existing URLs without iframeTemplate keep branded defaults.
None.
In the editor, this block uses useEntityBlockEditor to render the referenced entity's content as editable inner blocks. Default allowed blocks are core/group and core/paragraph.
On the frontend, inner blocks are not rendered -- the entity is displayed as an iframe instead.
None. Can be placed anywhere.
- Insert the Entity as Iframe block from the block inserter (under the Embed category).
- A placeholder appears with two options:
- Search for an existing entity (post/page).
- Create a new entity.
- Once an entity is selected, its content appears as editable inner blocks in the editor.
- The inspector panel shows the entity's title (editable) and a link to open the entity in a new window.
- On the frontend, the entity is rendered as an iframe using the entity's
/iframe/URL withprc_entity_iframe=1andiframeTemplate=content|branded(see table above). - Third-party code or parent container blocks (tabs, details, dialog, accordion, etc.) can set whether the entity iframe should load by updating the Interactivity API store (see Container integration below).
Developer API for toggling:
store('prc-block/entity-as-iframe').state[iframeId].isActive = true;Use the iframe’s DOM id (from server render, e.g. prc-entity-iframe-…) as iframeId. The block’s global state uses isActive, not open.
In post_content (editor saves inner blocks as entity content):
<!-- wp:prc-block/entity-as-iframe {"ref":12345} -->
<!-- inner blocks from the referenced entity -->
<!-- /wp:prc-block/entity-as-iframe -->The Entity_As_Iframe PHP class provides a server-side render callback:
- Resolves the
refattribute to a post permalink. - Appends
prc_entity_iframe=1,iframeTemplate, and the/iframe/path for iframe-specific rendering. - Reads iframe height from post meta (
iframe_height), defaulting to 500px. - Enqueues the iframe resizer parent script (
prc-platform-iframe-embeds-resizer-script) provided by the@prc/embedsplugin. - Registers Interactivity API state with
isActive: falseandresizer: nullfor the iframe ID (resizerholds a reference used after iframe-resizer runs; see Frontend Interactivity). - Renders the block wrapper with Interactivity API directives:
data-wp-interactive="prc-block/entity-as-iframe"data-wp-contextwith iframe ID, entity URL, andsrc(initially empty)data-entity-iframe-prefetch-url— same URL ascontext.urlfor optional prefetch by parent UI (tabs, details, dialog, etc.)data-wp-watch--on-activatefor activation callbackdata-wp-class--is-activefor active state styling
- The inner
<iframe>is built withwp_sprintfusing only id (%1$s) and height (%2$s). The entity URL is not inlined in the iframe tag; it is provided via context and bound withdata-wp-bind--src="context.src"(lazy load until active).
Rendered output:
<div
class="wp-block-prc-block-entity-as-iframe"
data-ref-id="12345"
data-wp-interactive="prc-block/entity-as-iframe"
data-wp-context='{"id":"prc-entity-iframe-1","url":"https://example.com/post/iframe/?prc_entity_iframe=1&iframeTemplate=content","src":""}'
data-entity-iframe-prefetch-url="https://example.com/post/iframe/?prc_entity_iframe=1&iframeTemplate=content"
data-wp-watch--on-activate="callbacks.onActivate"
data-wp-class--is-active="callbacks.isActive"
data-iframe-height
>
<iframe
id="prc-entity-iframe-1"
data-wp-bind--src="context.src"
height="500px"
width="100%"
scrolling="no"
frameborder="0"
></iframe>
</div>Uses the WordPress Interactivity API with store namespace prc-block/entity-as-iframe.
Per-iframe state (by iframe DOM id):
state[iframeId].isActive— Whether the iframe should load (srcset) and participate in resizing.state[iframeId].resizer— After activation, may hold the iframe element reference returned by@iframe-resizer/parentv5 (seeonActivate); cleared on deactivate.
State (derived):
state.active— Returns theisActiveflag for the current iframe from the global state (viagetContext().id).
Actions:
activate()— Toggles the iframe's active state on/off.
Callbacks:
isActive()— Returns the current active state (used for CSS class binding).onActivate()— Runs whenisActivechanges (viadata-wp-watch--on-activate):- Activated: Sets
context.srctocontext.url, then calls the parent iframe-resizer v5 API (@iframe-resizer/parent):- Resolves
window.iFrameResizefirst (registered by@prc/embeds/prc-platform-iframe-embeds-resizer-script), then falls back towindow.iframeResizeif present. - Calls
resize(options, iframe)withlicense: 'GPLv3',direction: 'vertical',heightCalculationMethod: 'taggedElement'. - v5 returns a frozen array of iframe elements. The code only uses
result[0]whenArray.isArray(result) && result.length > 0; otherwise it stores theiframeelement passed in. This avoids throwing when the return value isundefinedor an empty array. - Stores that element on
state[context.id].resizerfor bookkeeping; teardown uses the iframe’s API below.
- Resolves
- Deactivated: Clears
context.src, then callsiframe.iframeResizer/iframe.iFrameResizer.disconnect()when available, and setsstate[context.id].resizertonull.
- Activated: Sets
When this block is nested inside tabs, details, dialog, accordion, etc., parent blocks should drive isActive so the iframe loads only when the panel is visible. Shared helpers live under src/entity-as-iframe/shared/:
sync-entity-iframe-active.js—syncEntityIframeActive(containerEl, isActive)finds.wp-block-prc-block-entity-as-iframeinsidecontainerEland setsstore('prc-block/entity-as-iframe').state[iframeId].isActive.prefetch-entity-iframe.js— Prefetches the URL fromdata-entity-iframe-prefetch-urlon the wrapper (best-effort cache warm before first open).
See core-tabs.md, core-details.md, and core-dialog.md for how each container wires watches and prefetch. For legacy PRC accordion trees, see accordion-controller.md.
- Requires
@prc/embedsto be active for full functionality. This block depends on:- The
prc-platform-iframe-embeds-resizer-scriptparent script handle (exposeswindow.iFrameResizein the v5 UMD bundle). - The
?iframe=trueendpoint/template behavior used for iframe rendering. - The iframe template’s
data-iframe-heightmarker, which is required byheightCalculationMethod: 'taggedElement'.
- The
Commonly embedded inside core/tabs, core/details, prc-block/dialog, core/accordion, and similar patterns that control visibility; see Container integration above.