Hej!
Idag stötte jag på en bugg i Orchard CMS 1.5.1 (http://orchard.codeplex.com/workitem/18896)
Problemet kan kort beskrivas som följande:
När man har en orchard-site med hierarkiska menyer (3 nivåer+) så hämtas inte hierarkin korrekt. Utan modellen returnerar sub-meny-items både på den inre och den yttersta nivån inuti objektet. Följdaktligen får man dubletter.
I mitt fall har jag en toppmeny där översta menyhierarkin visas och en vänstermeny som visar övriga nivåer, och buggen artar sig såhär i vänstermenyn:
Eftersom jag inte hinner sätta mig in i källkoden för Orchard så blir det ett redigt fulhack för att komma runt problemet:
1. Kopiera meny view till aktuell Theme-katalog
Leta upp filen Menu.cshtml (under <sökvägtillorchard>\Core\Shapes\Views) och kopiera in den i din view foldern under din theme-katalog (i mitt ex. <sökvägtillorchard>\Themes\<namnpåtema>\Views\).
2. Editera och ersätt hela innehållet i filen med följande:
@functions {
public void RecurseItems(IList<dynamic> items, ref Dictionary<string, string> dict) {
if (items == null)
return;
foreach(var item in items) {
if (item.Items != null && item.Items.Count > 0)
RecurseItems(item.Items, ref dict);
if (dict.ContainsKey(item.Content.MenuPosition))
return;
else
dict.Add(item.Content.MenuPosition, string.Empty);
}
}
}
@{
// Model is Model.Menu from the layout (Layout.Menu)
var tag = Tag(Model, "ul");
var items = (IList<dynamic>)Enumerable.Cast<dynamic>(Model.Items);
if (items.Any()) {
items[0].Classes.Add("first");
items[items.Count - 1].Classes.Add("last");
}
/* Remove duplicate entries (bug: http://orchard.codeplex.com/workitem/18896) */
var alreadyAdded = new Dictionary<string, string>();
var filteredItems = new List<dynamic>();
foreach(var item in items) {
if (alreadyAdded.ContainsKey(item.Content.MenuPosition)) {
continue;
} else {
filteredItems.Add(item);
alreadyAdded.Add(item.Content.MenuPosition, string.Empty);
// Recurse inner items if any
if (item.Items != null && item.Items.Count > 0) {
RecurseItems(item.Items, ref alreadyAdded);
}
}
}
}
<nav>
@tag.StartElement
@* see MenuItem shape template *@
@DisplayChildren(filteredItems)
@tag.EndElement
</nav>
Kort och gött en rekursiv funktion som fyller en dictionary med redan tillagda poster. För varje nytt menyitem kollar vi mot dictionaryn innan vi lägger till den i den filtrerade listan. Slutligen skickar vi in den filtrerade listan som argument till DisplayChildren (istället för som tidigare Model).
Nu visas istället:
Success!
Som synes alltså riktigt fulhack med inlinekod, jag löser inte grundproblemet, och det kan ge prestandaproblem på en större site. Men det funkar för mig i detta fall eftersom jag bara bygger en prototyp.
Följer upp inlägget när Orchard-teamet löst felet, ska bli kul å se hur lång tid det tar :)
Inga kommentarer:
Skicka en kommentar