Tridion Component Link无法在动态组件演示中解析

Mik*_*val 21 tridion tridion2009 tridion-content-delivery

我目前正在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);
    }
}
Run Code Online (Sandbox Code Playgroud)

此列表以通常的方式绑定到转发器:

rptOffer.DataSource = componentPresentations;
rptOffer.DataBind();
Run Code Online (Sandbox Code Playgroud)

有谁知道我如何强制解决组件链接以及为什么GetComponentPresentation函数不为我这样做?

有什么东西我应该做的不同或者这是不可能的我正在实施这个?

我已确认tridiontagprefix已在web.config中正确注册.

我对Tridion很新,所以非常感谢任何帮助!

UPDATE

我试图实现Will的建议,因为它似乎是我的场景最合适的解决方案,但当我尝试使用Will的建议时,我收到了一个(相当乏味的)错误:

ComponentPresentationAssembler cpa = new ComponentPresentationAssembler("tcm:35-62652-64");
string content = cpa.GetContent(tbl.Rows[i][0].ToString(), strComponentTemplate.ToString());
Run Code Online (Sandbox Code Playgroud)

实际上有2个错误(看似)随机发生但始终在cpa.GetContent(...)通话中.错误是:

Exception occurred during configuration callback
OR
com.tridion.dcp.ComponentPresentationFactory
Run Code Online (Sandbox Code Playgroud)

我似乎无法弄清楚为什么错误在我运行代码的时间之间发生变化.即使没有进行代码更改,错误也会更改.

有人知道我在这里缺少什么吗?我认为这将是与Broker存储等连接的问题,但后来我记得当我使用ComponentPresentationFactory该类时该部分正在工作.

如果有帮助,存储在文件存储为ascx的DCP包含以下HTML:

<div class="content-list-item offer redesign noImage">
<h2><span>Mike Offer 01/06 - 10/06 &amp; 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&lt;span class=&#34;rm&#34;&gt;: Button Text&lt;/span&gt;" LinkAttributes=" alt=&#34;Button Text&#34; target=&#34;_self&#34; " 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>
Run Code Online (Sandbox Code Playgroud)

更新2

感谢Ryan,我发现我的DCP(ASCX)文件没有在wwwroot文件夹中的应用程序文件夹中发布,这解决了它<tridion:ComponentLink ... />直接将标签输出到源的问题.它现在正在渲染,但链接仍未解决.该<a ... />标签没有被输出.这是汇编程序有望进入的地方 - 一旦我能够实现这一点.

我已经实现了更多的日志记录和检查,并且有关于错误的更多信息,这表明我可能缺少一个jar文件或者版本不正确:

Exception Details: Java.Lang.ClassNotFoundException: com.tridion.dcp.ComponentPresentationFactory
Run Code Online (Sandbox Code Playgroud)

有趣的是,当我使用ComponentPresentationFactory该类时,它可以工作(不解析内部链接)但是一旦我使用Assembler,就会抛出上述错误.

我也尝试按照Alvin的建议将Page添加到构造函数中,但输出是相同的.

Wil*_*ill 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"));
Run Code Online (Sandbox Code Playgroud)

请注意,如果要发布大量(即数百个)组件演示文稿(并经常发布),使用ascx不是一个好主意 - ASP.NET批处理可能会出现一些性能问题,重新编译包含它们的文件夹,或触发应用程序重启.

将它们作为(X)HTML片段发布到数据库更安全,并像Mark提到的那样对链接进行后处理.

正如Frank在2011 SP1中提到的那样,您可以使用REL为您执行此后处理.有关更多信息,请参阅此文章

  • @Mike - 为了让CP汇编程序工作,你需要bin/conf/cd_wai_conf.xml和bin/lib/cd_wai.jar(参见我在这个问题上的评论) - 这可能是这里的问题 (2认同)

Rya*_*kin 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"));
Run Code Online (Sandbox Code Playgroud)

您还需要确保:

  • 您的ASCX文件已发布到文件系统这是在<Bindings>部分内的cd_broker_conf.xml文件中设置的<Binding Name="ASPComponentPresentation" Class="com.tridion.broker.componentpresentations.FSASCXComponentPresentationHome"/>

  • 您的ASCX文件发布在.Net Web应用程序中.这是在<Publications>部分内的cd_broker_conf.xml文件中设置的,例如

    <Publication Id="5" DocumentRoot="C:/Inetpub/wwwroot/website1" DataRoot="C:/Inetpub/wwwroot/website1/dcp">
        <Dcp>
            <Asp Location="C:/Inetpub/wwwroot/website1/dcp"/>
        </Dcp>
    </Publication>
    
    Run Code Online (Sandbox Code Playgroud)

请注意,您在上面看到的位置区分大小写

  • 除非我错了,否则你必须确保你拥有使用WAI功能的许可.只是一个注释......我不希望任何人实现这一点,然后发现他们没有必要的Tridion许可证! (2认同)

Fra*_*len 10

Mark的答案已经涵盖了您的Tridion版本最重要的部分:您必须将ASCX文件发布到磁盘,以便tridion:CompontentLinkASP.NET执行控件.

Tridion 2011引入了REL作为替代解决方案.使用REL时,您将再次发布HTML片段,并将tcdl:ComponentLink原样存储到数据库中(因此tridion:ComponentLink在部署时不会转换为).然后,当您检索内容(通过ComponentPresentationTransformer或通过新的Content Delivery OData Web服务)时,tcdl:ComponentLink(和其他tcdl:*标签)将被解析,您将获得所需的结果.


Mar*_*per 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);
}
Run Code Online (Sandbox Code Playgroud)

  • 谢谢Dominic.我不知道ComponentPresentationAssembler.你每天学习新的东西. (3认同)