21

私は現在、Tridion 2009 SP1 に機能を実装しています。この機能では、ユーザーはフィルターを利用して、ブローカーに一致基準を照会し、コンポーネント プレゼンテーションをページに返します。返される各アイテムには、コンポーネント リンクが含まれています。

もともと動的 CP は HTML フラグメントとしてブローカー DB に保存されていましたが、この方法で CP を保存すると、Tridion がコンテンツからコンポーネント リンクを削除し、HTML に空白スペースを残すことが発見されました。

次に、動的 CP が ascx コントロールとしてファイルストアに保存されるように設定を切り替えました。この設定を使用すると<tridion:ComponentLink ... />、ascx ファイルに正常に保存されます。

ただし、結果を画面に表示すると、コンポーネント リンクが解決されず<tridion:ComponentLink ... />、結果のソースに が残ります。

現在、このGetComponentPresentationメソッドを使用して CP コンテンツを返しています。CP コンテンツは List に追加されてから、Repeater にバインドされて表示されます。

要約されたコードは以下のとおりです。

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関数がこれを行わない理由を知っている人はいますか?

私が別の方法でやるべきことはありますか、それとも私がこれを実装している方法では不可能ですか?

tridionweb.configにtagprefixが正しく登録されていることを確認しました。

私はTridionにかなり慣れていないので、どんな助けも大歓迎です!

アップデート

私のシナリオにとって最も適切な解決策のように思われるため、Will の提案を実装しようとしましたが、以下のコードで Will の提案を使用しようとすると、(かなり当たり障りのない) エラーが発生します。

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

実際には (一見) ランダムに発生する 2 つのエラーがありますが、常に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 &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>

更新 2

Ryan のおかげで、DCP (ASCX) ファイルが wwwroot フォルダー内のアプリケーションのフォルダー内で公開されていないことがわかりました。これにより、<tridion:ComponentLink ... />タグがソースに直接出力されるという問題が解決されました。現在レンダリング中ですが、リンクはまだ解決されていません。<a ... />タグが出力されていません。これは、アセンブラーがうまく機能する場所です。これを機能させることができれば。

より多くのロギングとチェックを実装し、jar ファイルが見つからないか、バージョンが正しくない可能性があることを示唆するエラーに関する詳細情報を入手しました。

Exception Details: Java.Lang.ClassNotFoundException: com.tridion.dcp.ComponentPresentationFactory

興味深いことに、ComponentPresentationFactoryクラスを使用すると (内部リンクを解決せずに) 動作しますが、アセンブラーを使用するとすぐに上記のエラーがスローされます。

また、Alvin の提案に従って Page をコンストラクターに追加しようとしましたが、出力は同じです。

4

4 に答える 4

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 フラグメントとしてデータベースに公開し、マークが言及しているようにリンクを後処理する方が安全です。

Frank が 2011 SP1 で言及しているように、REL を使用してこの後処理を行うことができます。詳細については、この記事を参照してください

于 2012-05-10T12:35:03.830 に答える
11

すでに説明したように、問題を解決するには、ComponentPresentationAssemblerクラスではなくクラスを使用する必要がありますが、名前空間内でクラスComponentPresentationFactoryを使用するようにする必要があります。ComponentPresentationAssemblerTridion.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"));

また、次のことを確認する必要があります。

  • 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>
    

上記の場所は大文字と小文字が区別されることに注意してください

于 2012-05-11T17:47:32.187 に答える
10

マークの回答は、お使いのバージョンの Tridion にとって最も重要な部分を既にカバーしています。コントロールが ASP.NET によって実行されるようにするには、ASCX ファイルをディスクに公開する必要がありtridion:CompontentLinkます。

Tridion 2011 では、これに対する代替ソリューションとして REL が導入されました。REL を使用する場合は、HTML フラグメントを再度公開するだけでtcdl:ComponentLink、データベースにそのまま保存されます (tridion:ComponentLink展開時に変換されません)。次に、(ComponentPresentationTransformerまたは新しいコンテンツ配信 OData Web サービスを介して) コンテンツを取得すると、tcdl:ComponentLink(およびその他のtcdl:*タグ) が解決され、必要な結果が得られます。

于 2012-05-10T12:19:16.037 に答える
9

ユーザーコントロールとして文字列を実行するのではなく、動的コンポーネントプレゼンテーションのコンテンツを文字列としてロードしています。

問題を解決するには、次の 2 つのソリューションのうちの 1 つを使用できます。

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);
}
于 2012-05-10T11:12:27.950 に答える