可视化内容片段 — 随发布URL一起提供 visual-content-fragments-deliver-with-the-publish-url
发布基于附加HTML模板的模型的内容片段时,该片段的渲染的HTML可通过以下结构的URL中的Adobe Experience Manager (AEM) as a Cloud Service发布层使用:
https://publish-p<programId>-e<envId>.adobeaemcloud.com/adobe/stable/previewtemplates/contentFragments/<templateId>/<fragmentId>/<variation>.html
此URL返回可嵌入到任何Web上下文中的自包含HTML文档(包括内联CSS和结构)。
嵌入技术 — 概述 embedding-techniques-overview
可通过三种不同方法从主机页面上的可视内容片段使用HTML。 每个页面都具有风格隔离、布局行为、可访问性和复杂性的独特特性。
fetch() URL,通过innerHTML将响应HTML插入<div><iframe src="publishURL">fetch() HTML,将其注入连接的影子DOM根中width/height或基于JS的自动调整大小title属性fetch()加载的内容未被大多数爬虫编入索引<script>标记,则存在脚本冲突风险内联元素(fetch + innerHTML) inline-element-fetch-and-innerhtml
最简单的方法:
- 获取发布URL
- 将HTML注入容器元素
内联元素嵌入示例:
<div id="cf-container"></div>
<script>
fetch("<publish-url>")
.then(r => r.ok ? r.text() : Promise.reject(r.status))
.then(html => {
document.getElementById("cf-container").innerHTML = html;
})
.catch(err => console.error("Failed to load fragment", err));
</script>
何时使用:
- 快速原型制作或概念验证页面
- 用于控制主机页面和片段样式的同域上下文
- 当最大布局灵活性比样式封装更重要时
<style>块、字体声明和元素选择器)合并到主机页面的层叠中。iframe iframe
直接将发布URL作为<iframe>的src加载。 不需要JavaScript。
iframe嵌入示例:
<iframe
src="<publish-url>"
title="Content Fragment Preview"
width="100%"
height="600"
frameborder="0"
style="border: none;"
></iframe>
您还可以自动调整iframe的大小(这是可选的)。
要动态地将iframe调整到其内容高度(避免使用滚动条),请使用postMessage模式或适当的库。
轻量化方法的一个示例是:
<iframe id="cf-iframe" src="<publish-url>" title="Content Fragment Preview"
width="100%" frameborder="0" style="border:none; overflow:hidden;"
onload="this.style.height = this.contentDocument.documentElement.scrollHeight + 'px';"
></iframe>
onload自动调整大小方法仅适用于相同原点 iframe。postMessage的解决方案或设置固定高度。何时使用:
- Edge Delivery Services嵌入块(默认集成 — 请参阅以下部分)
- 完整CSS/JS隔离很重要的上下文
- 未配置CORS的跨源嵌入
- 零代码快速集成(只需粘贴URL)
自定义元素+影子DOM(推荐) custom-element-and-shadow-dom-recommended
定义一个可重复使用的<cf-visualization>自定义元素,用于获取发布URL并将HTML注入到封装的影子DOM根中。
此元素提供:
- 阴影DOM隔离
- 片段的标记和样式将封装在影子根中,从而防止与主机页面的CSS层叠发生冲突。
- 内联布局参与率
- 呈现的内容参与主机文档的正常流,响应容器大小调整和Flexbox/Grid上下文,无需手动维度管理。
- 单个浏览上下文
- 不创建辅助文档上下文;片段内容共享页面的JavaScript运行时,并且可由辅助技术完全遍历。
- 最小开销
- 单个
fetch调用从发布层检索预渲染的HTML。 无需客户端渲染框架。
- 单个
要定义自定义元素,请每页包含一次以下脚本。 该页面上的所有<cf-visualization>实例都将使用此定义:
<script>
class CfVisualization extends HTMLElement {
connectedCallback() {
const src = this.getAttribute("src");
if (!src) return;
const shadow = this.attachShadow({ mode: "open" });
fetch(src)
.then((r) => (r.ok ? r.text() : Promise.reject(r.status)))
.then((html) => {
shadow.innerHTML = html;
})
.catch((err) => {
console.error("cf-visualization: failed to load", src, err);
});
}
}
if (!customElements.get("cf-visualization")) {
customElements.define("cf-visualization", CfVisualization);
}
</script>
要使用自定义元素,请执行以下操作:
<cf-visualization src="<publish-url>"></cf-visualization>
何时使用:
- 使用核心组件的AEM Sites页面(这是内置行为)
- 需要干净且可重复使用的集成的外部/第三方网站
- 需要样式隔离和布局流参与的任何上下文
与Edge Delivery Services(嵌入块)集成 integration-with-edge-services-embed-block
在Edge Delivery Services中,发布URL通过 嵌入块 使用,这会将其呈现为<iframe>。
-
确保项目中存在Embed块。
如果您的EDS项目尚未包含嵌入块,请从aem-block-collection存储库复制该块:
code language-cmdline # From the aem-block-collection repo, copy blocks/embed/ into your project's blocks/ directory cp -r aem-block-collection/blocks/embed/ your-eds-project/blocks/embed/ -
在文档创作编辑器中创作嵌入(在Edge Delivery Services中)
在文档创作中,块以表形式表示。 要添加可视化内容片段嵌入,请执行以下操作:
table 0-row-1 1-row-1 嵌入 (将发布URL粘贴为超链接) 或者,如果您的项目或Sidekick在其块库中配置了嵌入块,则可以通过斜杠菜单插入该嵌入块,并将发布URL粘贴到块内容中。
-
结果
嵌入块呈现
<iframe>中的发布URL。 片段内容在EDS页面布局中以完整的CSS隔离方式加载。
集成 — AEM Sites与核心组件 integration-aem-sites-with-core-components
内容片段核心组件(core/wcm/components/contentfragment/v1/contentfragment)已内置对使用客户元素+影子DOM技术呈现可视化内容片段的支持。
工作原理:
-
创作模式:
当组件的
displayMode设置为vcf时,创作clientlib (vcfRenderer.js)从预览API中提取片段HTML并将其内联渲染到创作画布中。例如,“作者”预览端点为:
code language-html GET /adobe/sites/cf/fragments/{fragmentId}/preview?templateId={templateId}&variation={variation} -
发布模式:
在发布的页面(
wcmmode.disabled)上,HTL模板呈现一个内联脚本,该脚本从发布URL中提取并将HTML注入影子DOM根中。示例核心组件可视化内容片段(templates.html):
code language-html <div class="cmp-contentfragment cmp-contentfragment--vcf" data-cmp-contentfragment-id="{fragmentId}" data-cmp-contentfragment-vcf-template="{templateId}" data-cmp-contentfragment-variation="{variation}"> <!-- Only rendered when wcmmode.disabled (publish) --> <div data-vcf-url="{vcfPublishUrl}" class="cmp-contentfragment__vcf-loader" style="display:none"></div> <script> (function() { var script = document.currentScript; var loader = script.previousElementSibling; var el = script.parentElement; if (!el || !loader) return; var url = loader.dataset.vcfUrl; if (!url) return; loader.remove(); var shadow = el.attachShadow({ mode: "open" }); var body = document.createElement("body"); body.style.display = "none"; shadow.appendChild(body); fetch(url) .then(function(r) { return r.ok ? r.text() : Promise.reject(r.status); }) .then(function(html) { body.innerHTML = html; body.style.display = ""; }); })(); </script> </div>发布URL格式:
Sling模型(
ContentFragmentImpl)使用以下模式构建发布URL:code language-html /adobe/experimental/previewtemplates-expires-20260301/contentFragments/{templateId}/{fragmentId}/{variation}.html运行时将针对发布主机解析此相对URL。
与外部站点集成 integration-with-external-sites
对于非AEM网站,请使用Customer Element + Shadow DOM技术。 这为您提供了干净的声明性集成,而无需依赖框架。
示例为:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Product Page</title>
</head>
<body>
<h1>Product Details</h1>
<p>Some host-page content here...</p>
<!-- Embed the Content Fragment visualization -->
<cf-visualization
src="https://publish-p12345-e67890.adobeaemcloud.com/adobe/experimental/previewtemplates-expires-20260301/contentFragments/product_template/abc-123/master.html"
></cf-visualization>
<p>More host-page content below the fragment...</p>
<!-- Custom Element definition (include once) -->
<script>
class CfVisualization extends HTMLElement {
connectedCallback() {
const src = this.getAttribute("src");
if (!src) return;
const shadow = this.attachShadow({ mode: "open" });
fetch(src)
.then(r => r.ok ? r.text() : Promise.reject(r.status))
.then(html => { shadow.innerHTML = html; })
.catch(err => console.error("cf-visualization: failed to load", src, err));
}
}
if (!customElements.get("cf-visualization")) {
customElements.define("cf-visualization", CfVisualization);
}
</script>
</body>
</html>
<cf-visualization>元素放置到具有不同src URL的同一页面上。 自定义元素定义只需包含一次。CORS和安全注意事项 cors-and-security-considerations
/adobe/**路径上配置CORS。Inline Element (撷取+ innerHTML)🔗 1和Customer Element + Shadow DOM技术(使用
fetch())要求主机页面的原点位于允许列表中。iFrame技术不需要CORS。
Content-Security-Policy或X-Frame-Options标头。 如果您的CDN或Dispatcher添加了这些标头,请验证它们是否允许从您的主机源进行成帧(对于iFrame)或fetch()访问(对于内联/影子DOM)。选择适当的技术 choose-the-appropriate-technique
使用下列内容作为决策指南,帮助您选择适当的技术:
其他资源 additional-resources
其他资源可供使用: