2012-05-10 2 views
20

Ich implementiere derzeit Funktionalität in Tridion 2009 SP1, wo der Benutzer einen Filter verwenden kann, der wiederum den Broker nach übereinstimmenden Kriterien abfragt und dann die Komponentenpräsentationen an die Seite zurückgibt. Jedes zurückgegebene Element enthält einen Komponentenlink.Tridion Component Link aufgelöst in Dynamische Komponentenpräsentation

Ursprünglich wurden die dynamischen CPs in der Broker-DB als HTML-Fragmente gespeichert, aber es wurde entdeckt, dass Tridion beim Speichern der CPs den Komponentenlink vom Inhalt streichen und einen leeren Bereich im HTML hinterlassen würde.

Ich habe dann die Einstellung so geschaltet, dass die dynamischen CPs jetzt im Dateispeicher als ascx-Steuerelemente gespeichert sind. Wenn diese Einstellung verwendet wird, wird <tridion:ComponentLink ... /> erfolgreich in der Datei ascx gespeichert.

Wenn ich jedoch komme, um die Ergebnisse auf dem Bildschirm zu rendern, wird die Komponentenverknüpfung nicht aufgelöst und ich werde mit der <tridion:ComponentLink ... /> in meiner resultierenden Quelle belassen.

Momentan verwende ich die Methode GetComponentPresentation, um den CP-Inhalt zurückzugeben, der dann zu einer Liste hinzugefügt wird, bevor er zur Anzeige an einen Repeater gebunden wird.

Zusammengefasst Code ist unten:

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); 
    } 
} 

Diese Liste der an den Repeater auf die übliche Weise gebunden ist:

rptOffer.DataSource = componentPresentations; 
rptOffer.DataBind(); 

Wer weiß, wie ich die Komponente Verbindung zu lösenden zwingen kann, und Warum macht die GetComponentPresentation Funktion dies nicht für mich?

Gibt es etwas, was ich anders machen sollte, oder ist das nicht möglich in der Art, wie ich das umsetze?

Ich habe bestätigt, dass der Tagprefix tridion korrekt in der web.config registriert ist.

Ich bin ziemlich neu zu Tridion, so dass jede Hilfe sehr geschätzt wird!

UPDATE

Ich habe versucht Will Vorschlag umzusetzen, da es wie die am besten geeignete Lösung für mein Szenario scheint, aber ich bin ein (ziemlich langweilig) Fehler zu erhalten, wenn ich versuche meinen Willen Vorschlag zu verwenden, um mit Code unten:

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

Es gibt tatsächlich zwei Fehler, die (scheinbar) zufällig, sondern immer am cpa.GetContent(...) Anruf auftreten. Die Fehler sind:

Ich kann nicht herausfinden, warum der Fehler zwischen den Zeiten ändert, die ich den Code ausführe. Der Fehler ändert sich, auch wenn keine Codeänderungen vorgenommen werden.

Weiß jemand, was ich hier vermisse? Ich nahm an, dass es ein Problem mit der Konnektivität zu dem Broker-Speicher usw. sein würde, aber dann erinnerte ich mich, dass dieser Teil funktionierte, als ich die Klasse ComponentPresentationFactory verwendete.

Wenn es hilft, das DCP, die auf dem Dateispeicher als ascx gespeichert wird, enthält die folgende 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> 

UPDATE 2

Dank Ryan, I‘ Ich habe entdeckt, dass meine DCP (ASCX) -Dateien nicht im Ordner der Anwendung im Ordner wwwroot veröffentlicht wurden, der das Problem der Ausgabe des Tags <tridion:ComponentLink ... /> direkt an die Quelle gelöst hat. Es wird jetzt gerendert, aber die Verbindung wird immer noch nicht aufgelöst. Die <a ... /> Tags werden nicht ausgegeben. Hier kommt hoffentlich der Assembler rein - sobald ich das zur Arbeit bringen kann.

Ich habe mehr Logging durchgeführt und überprüft und haben mehr Informationen über den Fehler was darauf schließen lässt, dass ich eine JAR-Datei fehlt oder die falsche Version haben:

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

Interessant ist das, wenn ich die ComponentPresentationFactory Klasse, es funktioniert (ohne Auflösung der internen Link), aber sobald ich den Assembler verwenden, löst es den obigen Fehler.

Ich habe auch versucht, die Seite zum Konstruktor hinzuzufügen, wie von Alvin vorgeschlagen, aber die Ausgabe ist die gleiche.

+0

Hey Mike, Willkommen bei Tridion. Du schaffst es, deine Neuheit ziemlich gut zu verstecken. :-) Sie werden feststellen, dass die meisten Mitglieder der Tridion Community sehr hilfreich sind. Wenn Sie dies noch nicht getan haben, empfehlen Sie bitte unseren Tridion-Vorschlag auf area51: http://area51.stackexchange.com/proposals/38335/tridion?referrer=lav544jo87qNn9xqeeO2NA2 –

+0

Das Problem ist mit CPFactory - verwenden Sie stattdessen CPAssembler, wie Will zeigt in seiner Antwort –

+0

Auf den Fehler .getContent(), eine Chance, dass es mehrere Präsentationsserver und/oder die Komponentenpräsentationen tatsächlich unveröffentlicht werden, wenn Sie den Code ausführen? –

Antwort

11

Wie bereits diskutiert, um Ihr Problem zu lösen, müssen Sie die ComponentPresentationAssembler Klasse verwenden, nicht die ComponentPresentationFactory Klasse, aber Sie müssen sicherstellen, dass Sie die ComponentPresentationAssembler Klasse innerhalb des Tridion.ContentDelivery.WAI Namespace verwenden:

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")); 

Sie müssen auch sicherstellen:

  • Ihre ASCX-Dateien in das Dateisystem veröffentlicht werden Diese im cd_bro gesetzt ker_conf.xml-Datei im Abschnitt <Bindings>, z.B.

  • Ihre ASCX-Dateien werden in Ihrer .Net-Webanwendung veröffentlicht. Dies wird in der Datei cd_broker_conf.xml im Abschnitt <Publications> festgelegt, z.

    <Publication Id="5" DocumentRoot="C:/Inetpub/wwwroot/website1" DataRoot="C:/Inetpub/wwwroot/website1/dcp"> 
        <Dcp> 
         <Asp Location="C:/Inetpub/wwwroot/website1/dcp"/> 
        </Dcp> 
    </Publication> 
    

Beachten Sie, dass die Orte, die Sie oben sehen, Groß- und Kleinschreibung

+0

Prost Ryan, ich habe Wills Antwort als die akzeptierte Antwort markiert, da er Recht mit der Verwendung des ComponentPresentationAssembler hatte, aber es war wirklich praktisch, die Liste der Dinge zu haben, um sicherzustellen, dass alles dafür bereit war Arbeit. Prost! –

+0

Eigentlich denke ich, dass deine Antwort tatsächlich der Grund ist, dass ich es geschafft habe, dies zu beheben. Es stellt sich heraus, dass der Fehler, den ich bezüglich ClassNotFoundException bekommen habe (siehe Update 2), auf der Tatsache beruht, dass ich den falschen Namensraum für den ComponentPresentationAssembler verwendet habe. Das Ändern in den Tridion.ContentDelivery.WAI-Namespace behob dieses Problem und erlaubte mir, dass der Code vollständig funktionierte. Entschuldigung für das Fehlen dieses wichtigen Teils, wenn es darum ging, richtige Antworten zu markieren. –

+2

Wenn Sie sich nicht irren, müssen Sie sicherstellen, dass Sie über eine Lizenz zur Verwendung der WAI-Funktionalität verfügen. Nur eine Anmerkung ... Ich möchte nicht, dass irgendjemand dies implementiert und dann herausfindet, dass sie nicht die notwendigen Tridion-Lizenzen haben! –

9

Sie laden den Inhalt der dynamischen Komponentenpräsentation als Zeichenfolge, statt die Zeichenfolge wie ein Benutzersteuerelement auszuführen.

Ihr Problem lösen Sie 1 von 2 Lösungen verwenden können:

1) Verwenden Sie eine Regex auf cp.Content die Links über die Tridion-API zu verarbeiten.

2) Veröffentlichen Sie Dynamische Inhalte in das Dateisystem als Benutzersteuerungen und laden diese Steuerung auf Ihrer Seite/Benutzersteuerung ist es somit die Ausführung

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); 
} 
+1

-1 protokolliert wird Tridion unterstützt dies sofort mit dem ComponentPresentationAssembler –

+3

Dank Dominic. Ich war mir des ComponentPresentationAssembler nicht bewusst. Du lernst jeden Tag etwas Neues. –

10

Mark Antwort deckt bereits den wichtigsten Teil für Ihre Version von Tridion: Sie müssen die ASCX-Dateien auf der Festplatte veröffentlichen, damit die tridion:CompontentLink-Steuerelemente von ASP.NET ausgeführt werden können.

Tridion 2011 führte REL als eine alternative Lösung dafür ein. Wenn Sie REL verwenden, veröffentlichen Sie einfach HTML-Fragmente erneut und die tcdl:ComponentLink wird so wie sie ist in der Datenbank gespeichert (also bei der Bereitstellung nicht in tridion:ComponentLink umgewandelt). Wenn Sie dann den Inhalt abrufen (über den ComponentPresentationTransformer oder über den neuen OData-Webdienst für Content Delivery), werden die Tags tcdl:ComponentLink (und andere tcdl:*-Tags) aufgelöst und Sie erhalten das gewünschte Ergebnis.

18

Um einen DCP auszuführen, anstatt nur den veröffentlichten Inhalt zu erhalten, müssen Sie die Klasse ComponentPresentationAssembler verwenden, nicht die Klasse ComponentPresentationFactory.

Ein einfaches Beispiel unter:

ComponentPresentationAssembler cpa = 
    new ComponentPresentationAssembler("tcm:69-6212-64",this.Page); 
Response.Write(cpa.GetContent("tcm:69-2882", "tcm:69-6339-32")); 

Beachten Sie, dass, wenn Sie eine Menge (dh Hunderte) von Komponenten Präsentationen (und veröffentlichen sie häufig) zu veröffentlichen, es ist nicht eine gute Idee, ascx zu verwenden - Sie können erhalten einige Leistungsprobleme mit ASP.NET-Stapel, der den Ordner neu kompiliert, der sie alle enthält, oder den Neustart der Anwendung auslöst.

Es ist sicherer, sie als (X) HTML-Fragmente in der Datenbank zu veröffentlichen und die Links wie von Mark erwähnt zu bearbeiten.

Wie Frank in 2011 SP1 erwähnt, können Sie REL verwenden, um diese Nachbearbeitung für Sie zu tun. Siehe this article für weitere Informationen

+0

Gute Sachen Will. Ich sehe, dass Sie unserem Vorschlag noch nicht beigetreten sind, um einen Tridion-spezifischen StackExchange-Bereich zu erhalten. Bitte folgen Sie diesem Link und betrachten Sie es: http://area51.stackexchange.com/proposals/38335/tridion?referrer=lav544jo87qNn9xqeeO2NA2 –

+0

Danke für diese Info @Will. Ich habe dies versucht, aber ich erhalte jetzt einen Fehler, wenn ich versuche, das DCP abzurufen.Ich habe meine Fehlerdetails dem Beitrag hinzugefügt. Irgendwelche Ideen? –

+0

Ah, der klassische CP Assembler vs Factory Erklärung (mit der neuen Güte von REL), schön! @ MikePercival - Ich vermute, der Unterschied in den Fehlern war, dass Sie Null CPs in Ihrem ersten Beispiel gefangen. Wenn Sie die Prüfung entfernen, erhalten Sie den gleichen Fehler über die gleiche Gruppe von Komponenten-IDs? –

Verwandte Themen