2015-04-23 12 views
5

Ich verwende Sitecore 7.5 und Sitecore 8 (2 separate Projekte mit dem gleichen Bedarf). Wir haben Inhaltselemente in Buckets gespeichert, aber sie sind keine Seitenelemente selbst (sie haben keine an sie gebundene Präsentation, sie sind nur Datenelemente und können aus verschiedenen Quellen stammen, einschließlich Objekt-Buckets).Sitecore MVC Benutzerdefinierte Route bei Verwendung der Sitecore-Rendering-Pipeline

hier ist also eine allgemeine Layout des Problems: Die Seite wollen wir Produkte machen mit /Sitecores/content/home/news etwas wie Wir müssen in der Lage sein würde, die pathinfo nach dem Punkt zu analysieren Name als Datennutzlast für das Controller-Rendering.

Also, was ich versucht habe, so weit umfasst entlang dieser Linien eine eigene Route erstellen:

  routes.MapRoute(
      "Blog", 
      "blog/{*pathInfo}", 
      new 
      { 
       scItemPath = "/sitecore/content/Home/Blog", 
       controller = "Blog", 
       action = "DefaultAction" 
      }); 

ich die Routen aus der RenderCustomRoutes Pipeline laden, und ich habe dies aus, bevor aufgerufen werden konfiguriert und nach die Sitecore InitializeRoutes-Pipeline bei verschiedenen Testversuchen.

Ich referenzierte dies von http://www.sitecore.net/learn/blogs/technical-blogs/john-west-sitecore-blog/posts/2012/10/using-sitecore-keys-in-mvc-routes-with-the-sitecore-aspnet-cms.aspx und einige verwandte Artikel.

Nach einigen weiteren Artikeln von dort, wo er seine Anweisungen revidiert oder weitergeht, um andere Probleme zu adressieren, löst mein Szenario nicht. Die Sache ist, nichts davon funktioniert. In diesem Fall wird der Controller korrekt aufgerufen, aber während ich das Element selbst im Rendering-Kontext erhalte, erhalte ich keinen Rest der Seiten-Renderings. Gibt es eine Möglichkeit, die Rendering-Pipeline von hier aus zu starten oder die Seite mithilfe der übrigen Präsentationsdetails des Blog-Elements zu erstellen und manuell auszuführen?

Der andere Weg, den ich versucht habe, hätte nur versucht, die pathinfo als Daten an die bestehenden Blog-Seite URL zu übergeben, aber ich mit einem 404.

am Ende weiß ich nicht, ob ich eine Jagd nach bin wilde Gans hier und dass es einen besseren Weg gibt oder wenn ich irgendwo ein Stück vermisse. In Webforms hätte ich wahrscheinlich URL-Rewriting durchgeführt, um das zu erreichen, ohne Querystrings zu verwenden, aber ich hatte gehofft, dass die Routen so gestaltet werden, dass die Dinge so gehandhabt werden und die Artikel, die ich sah, ließen mich glauben, dass es möglich ist.

Zusätzliche Dinge, die ich angesichts habe: John West sagt, dass es 4 Möglichkeiten für Sitecores eine MVC-Anfrage

1. Ignorieren Sie die Anfrage zu handhaben: Lassen Sie ASP.NET MVC es, als ob zu handhaben Sitecore wurde nicht installiert, ohne einen Sitecore-Kontext einzurichten.

2. Anwenden einer Route: Verwenden Sie den von einer MVC-Route angegebenen Controller und die angegebene Aktion.

3. Die angegebene Aktion anwenden: Verwenden Sie den Controller und die Aktion, die im Kontextelement angegeben sind.

4. Anwenden einer Ansicht: Verwenden Sie den Standardcontroller und die Aktion von Sitecore, um die in den Layoutdetails für das Kontextgerät im Kontextelement definierte Ansicht aufzurufen.

Was bekomme ich, wenn ich die individuelle Route zu verwenden scheint # 2, zu passen aber was ich brauche ist etwas mehr wie # 3 oder # 4 während immer noch die individuelle Route.

Antwort

3

Da die Elemente in Ihrem Bucket keine Präsentation haben, glaube ich, dass es schwierig wird, dies mit den Routen zu handhaben. Es kann möglich sein und hoffentlich wird jemand anderes hereingleiten, aber ...

Sie könnten wildcard Items verwenden, um zu erreichen, was Sie versuchen. Es hängt von der genauen Einrichtung und Struktur Ihrer Komponenten ab, aber erstellen Sie einfach ein Element namens * als Kind von /sitecore/content/Home/Blog. Sie können dann die Präsentationsdetails usw. für dieses Platzhalterelement festlegen.

Jetzt wird jede URL dieses Produkt entsprechen. Sie müssen das Element zu einem bestimmten Zeitpunkt auflösen, es könnte sich im Controller selbst befinden, Sie müssen die URL analysieren und dann das Element für die Verwendung in Ihrem Rendering nachschlagen. Hinweis die Context.Item noch die Platzhalter * Artikel ist daher würden Sie eine neue Variable im Code erstellen müssen, um dann Ihr Modell füllen:

Item requestedItem = Sitecore.Context.Database.GetItem("resolved-path"); 
Model.Name = requestedItem.Name; 
Model.MyProperty = requestedItem["My Property"]; 

Allerdings wird es wahrscheinlich besser, den Artikel zu lösen nach die ItemResolver Pipeline und dann speichern Sie die gUID in Sitecore.Context.Items Wörterbuch:

Item requestedItem = Sitecore.Context.Database.GetItem("resolved-path"); 
Sitecore.Context.Items["wildcard-guid"] = requestedItem.ID.ToString(); 

diese Weise können Sie diese in mehrere Komponenten verwenden können und es als Datenquelle für die Komponenten (von Code) ein, zB Breadcrumbs, Hauptinhalt usw. Dies kann auch aus einer Caching-Perspektive vorteilhaft sein, da Sie das Caching mithilfe der VaryByData-Option aktivieren können. Wenn das Element nicht gefunden wird, können Sie auch ein passendes 404-Objekt erstellen, indem Sie Sitecore.Context.Item = null bei Bedarf festlegen.

Sie müssen auch in der Lage sein, die Link-Generierung zu verwalten, so dass Sie create acustom LinkProvider generieren müssen, um einige freundliche URLs zu generieren.

Hoffe das macht Sinn was! Ich muss bald etwas Ähnliches machen und das ist die beste Option, die ich bisher gefunden habe ...

+0

Ich werde es versuchen. Ich teste gerade den Seiteneditor-Support für die von mir entwickelte Lösung. Ich bekomme die Seite in einer sehr einfachen Form wie erwartet zu rendern. Wenn ich meine Ansicht die anderen Renderings laden oder sogar andere Platzhalter aufdecken lasse, könnte sie alles tun, was ich brauche. Mein Gedanke wäre, dass der Controller entscheidet, welches Datenelement referenziert werden soll und welche Ansicht zurückgegeben werden soll, falls ein Bedarf dafür besteht. Ich werde mit dieser Idee ein wenig herumspielen und Sie wissen lassen, wie es sich vergleicht oder ob ich mehr davon herausholen kann! –

+0

Das ist auch eine interessante Lösung. Stimmen Sie der Trennung zu, und es sollte weiterhin mit Platzhalterknoten möglich sein.Sie übergeben im Wesentlichen die Guid des Datenelements (Blog-Post) und dann statisch in Ihrer Ansicht binden. Dafür gibt es einen zusätzlichen View-Wrapper, der nicht ideal, aber einfach genug ist. Da Ihr Rendering datenbasiert ist, funktioniert die Seiteneditor-Unterstützung weiterhin. – jammykam

+0

Ja, die Wildcard-Knoten-Idee ist fast noch einfacher als die anderen. Es ist wirklich alles was wir brauchen, um die Querystrings zu brauchen. Der Rest der Seite kann wie gewohnt eingerichtet werden und mein Controller kann das Element nur basierend auf diesem Pfad laden. Die einzige Schwierigkeit, die ich sehen kann, ist, dass die Wege mit dem Format TT/MM/JJJJ durcheinander kommen würden. Ich kann sehen, ob wir stattdessen Bindestriche verwenden können –

3

Also, eine Antwort, die ich gefunden habe, dass ich mit nicht ganz zufrieden bin, ist dies:

ich eine Kopie meines Layouts zu erstellen, die Ansicht rendern und @Html.Sitecore().Rendering("<id>", <datasource>) verwenden, um manuell den Rest der Seite zu machen . Es wird funktionieren, aber es ist nicht so elegant, wie ich es gerne hätte, also bin ich immer noch offen für eine bessere Lösung.

Verwandte Themen