我目前正在Tridion 2009 SP1中实现功能,用户可以使用过滤器,该过滤器依次查询代理以匹配条件,然后将组件演示文稿返回到页面。 返回的每个项目都包含一个组件链接。
最初动态CP作为HTML片段存储在代理DB中,但是发现当以这种方式存储CP时,Tridion将从内容中剥离组件链接并在HTML中留下空白。
然后我切换了设置,以便动态CP现在作为ascx控件存储在文件存储中。使用此设置时,<tridion:ComponentLink ... />
已成功存储在ascx文件中。
但是,当我将结果渲染到屏幕时,组件链接没有得到解决,而我在结果源中留下了<tridion:ComponentLink ... />
。
目前,我使用GetComponentPresentation
方法返回CP内容,然后在绑定到Repeater进行显示之前将其添加到List中。
汇总代码如下:
ComponentPresentationFactory CPFactory = new ComponentPresentationFactory();
List<string> componentPresentations = new List<string>();
for (int i = 0; i < tbl.Rows.Count; i++)
{
ComponentPresentation cp = CPFactory.GetComponentPresentation(
tbl.Rows[i][0].ToString(),
strComponentTemplate.ToString());
if (cp != null)
{
componentPresentations.Add(cp.Content);
}
}
此列表以通常的方式绑定到转发器:
rptOffer.DataSource = componentPresentations;
rptOffer.DataBind();
有谁知道我如何强制解决组件链接以及为什么GetComponentPresentation
函数不能帮我解决这个问题?
我是否应该采用不同的方式做某些事情,或者这与我实施此方式的方式无法实现?
我已确认tridion
tagprefix已在web.config中正确注册。
我对Tridion相当新,所以非常感谢任何帮助!
更新
我试图实施Will的建议,因为它似乎是我的方案最合适的解决方案,但是当我尝试使用Will&#39;时,我收到了一个(相当乏味的)错误。我的代码如下建议:
ComponentPresentationAssembler cpa = new ComponentPresentationAssembler("tcm:35-62652-64");
string content = cpa.GetContent(tbl.Rows[i][0].ToString(), strComponentTemplate.ToString());
实际上有两个错误(看似)随机发生但总是在cpa.GetContent(...)
调用。错误是:
Exception occurred during configuration callback
OR
com.tridion.dcp.ComponentPresentationFactory
我似乎无法弄清楚为什么错误会在我运行代码的时间之间发生变化。即使没有进行代码更改,错误也会更改。
有人知道我在这里失踪的是什么吗?我认为与Broker存储等连接存在问题,但后来我记得当我使用ComponentPresentationFactory
类时该部分正在工作。
如果有帮助,存储在文件存储为ascx的DCP包含以下HTML:
<div class="content-list-item offer redesign noImage">
<h2><span>Mike Offer 01/06 - 10/06 & 20/06 - 10/07</span> Exp May 20th</h2>
<div class="content-list-item-text">
<p>Body Text</p>
<div class="input-btn burgundy">
<tridion:ComponentLink runat="server" PageURI="tcm:0-0-0" ComponentURI="tcm:35-31685" TemplateURI="tcm:0-0-0" AddAnchor="false" LinkText="Button Text<span class="rm">: Button Text</span>" LinkAttributes=" alt="Button Text" target="_self" " TextOnFail="true"/>
</div>
<p>Sub Title</p>
</div>
<div class="offers-list">
<ul>
<li>Offer ends: 20 May 2012</li>
<li>Offer available at all hotels</li>
</ul>
</div>
<div class="back-to-top">
<a href="#content">Back to top</a>
</div>
更新2
感谢Ryan,我发现我的DCP(ASCX)文件没有在wwwroot文件夹中的应用程序文件夹中发布,该文件夹解决了输出{{{ 1}}直接标记到源。它现在正在渲染,但链接仍未解决。未输出<tridion:ComponentLink ... />
标记。这是汇编程序有望进入的地方 - 一旦我能够将其发挥作用。
我已经实施了更多的日志记录和检查,并且有关于错误的更多信息,这表明我可能缺少jar文件或版本不正确:
<a ... />
有趣的是,当我使用Exception Details: Java.Lang.ClassNotFoundException: com.tridion.dcp.ComponentPresentationFactory
类时,它可以工作(不解析内部链接)但是只要我使用汇编程序,它就会抛出上述错误。
我也尝试按照Alvin的建议将Page添加到构造函数中,但输出是相同的。
答案 0 :(得分:18)
要执行DCP,而不是仅仅获取已发布的内容,您需要使用ComponentPresentationAssembler
类,而不是ComponentPresentationFactory
类。
以下简单示例:
ComponentPresentationAssembler cpa =
new ComponentPresentationAssembler("tcm:69-6212-64",this.Page);
Response.Write(cpa.GetContent("tcm:69-2882", "tcm:69-6339-32"));
请注意,如果您要发布大量(即数百个)组件演示文稿(并经常发布),使用ascx不是一个好主意 - ASP.NET批处理重新编译包含的文件夹可能会出现一些性能问题全部,或触发应用程序重启。
将它们作为(X)HTML片段发布到数据库更安全,并像Mark提到的那样对链接进行后处理。
正如Frank在2011 SP1中提到的,您可以使用REL为您进行后期处理。有关详细信息,请参阅this article
答案 1 :(得分:11)
如前所述,为了解决您的问题,您需要使用ComponentPresentationAssembler
类,而不是ComponentPresentationFactory
类,但您需要确保使用ComponentPresentationAssembler
类内的Tridion.ContentDelivery.WAI
类。 Tridion.ContentDelivery.WAI.ComponentPresentationAssembler presentationAssembler = new Tridion.ContentDelivery.WAI.ComponentPresentationAssembler("tcm:5-44410-64",this.Page);
Response.Write(presentationAssembler.GetContent("tcm:5-62700", "tcm:5-62627-32"));
命名空间:
<Bindings>
您还需要确保:
您的ASCX文件已发布到文件系统
这是在<Binding Name="ASPComponentPresentation" Class="com.tridion.broker.componentpresentations.FSASCXComponentPresentationHome"/>
部分的cd_broker_conf.xml文件中设置的,例如<Publications>
您的ASCX文件发布在.Net Web应用程序中。
这是在<Publication Id="5" DocumentRoot="C:/Inetpub/wwwroot/website1" DataRoot="C:/Inetpub/wwwroot/website1/dcp">
<Dcp>
<Asp Location="C:/Inetpub/wwwroot/website1/dcp"/>
</Dcp>
</Publication>
部分的cd_broker_conf.xml文件中设置的,例如
{{1}}
请注意,您在上面看到的位置区分大小写
答案 2 :(得分:10)
Mark的回答已经涵盖了您的Tridion版本最重要的部分:您必须将ASCX文件发布到磁盘,以便ASP.NET执行tridion:CompontentLink
控件< /强>
Tridion 2011引入了REL作为替代解决方案。使用REL时,您只需再次发布HTML片段,tcdl:ComponentLink
将按原样存储到数据库中(因此在部署时不会转换为tridion:ComponentLink
)。然后,当您检索内容时(通过ComponentPresentationTransformer
或通过新的Content Delivery OData网络服务),tcdl:ComponentLink
(以及其他tcdl:*
标记)将被解析,您将获得你想要的结果。
答案 3 :(得分:9)
您正在将动态组件表示的内容作为字符串加载,而不是像用户控件那样执行字符串。
要解决您的问题,您可以使用以下解决方案之一:
1)使用cp.Content
上的正则表达式通过Tridion API处理链接。
2)将动态内容作为用户控件发布到文件系统,并将此控件加载到页面/用户控件上,从而执行它
using (var cpf = new ComponentPresentationFactory(publicationId))
{
var cp = cpf.GetComponentPresentation(componentId, componentTemplateId);
fileLocation = cp.FileLocation;
}
if (!String.IsNullOrEmpty(fileLocation))
{
var crtl = this.LoadControl(MapPathReverse(fileLocation));
phldControls.Controls.Add(crtl);
}