Orchard CMS - 在主页旁边创建垂直导航菜单

Orchard CMS - create vertical Navigation Menu next to Home

我是 Orchard 的新手,正在尝试弄清楚它在代码方面的工作原理。 因此,我通过代码创建了一个自定义内容类型,并且我能够在此内容类型下创建内容项。我在内容项的编辑器页面上有 'Show on the Menu' 复选框。但是当我检查它并且 select 我希望将这个新创建的自定义项目添加到的菜单时,它被添加为垂直菜单项,而我需要它作为垂直子菜单添加到根目录之一项目。 请找到描述现在发生的事情和我需要什么的图片。 Current behavior Expected behavior

Product2 是自定义内容项,应作为条目添加到垂直菜单中,如第二张图片所示

这个任务比较复杂。涉及几个步骤。

  1. 了解如何创建子主题

    查看 official documentation,创建子主题并启用它

  2. 了解形状交替的概念

    official documentation

  3. 在管理区配置菜单

    进入管理区,点击菜单中的导航,添加一些菜单项和子项,例如

    [ Home (Content Menu Item) ]
    [ Service (Content Menu Item) ]
      [ Document Storage (Custom Link) ]
    

    一旦你有了这个结构,Orchard 就会通过主题中的 @Zone(Model.Navigation) 调用呈现这个结构。这个调用的位置你自己去搜索吧,要看主题。

    我的子主题使用 Layout.cshtml 替代方法,在需要时调用 @Zone(Model.Navigation)

    @{
      Func<dynamic, dynamic> Zone = x => Display(x); // Zone as an alias for Display to help make it obvious when we're displaying zones
    }
    
    <div class="wrapper">
        @* Navigation bar *@
        @if (Model.Navigation != null)
        {
          <div id="layout-navigation" class="group navbar navbar-default" role="navigation">
            @Zone(Model.Navigation)
          </div>
        }
    
        ...
    </div>
    

    现在,如果 Orchard 自己呈现菜单,它会使用 Menu.cshtml 形状模板,因此下一步将为 Menu.cshtml 提供一个形状替代。

  4. 正在为您的子主题中的菜单创建替代形状

    转到您的子主题文件夹并添加一个文件 Views\Menu.cshtml 并开始在那里渲染菜单,例如

    <ul class="nav navbar-nav">
      @DisplayChildren(Model)
    </ul>
    

    @DisplayChildren(Model) 调用将开始通过 MenuItem.cshtml 形状模板呈现菜单项,因此下一步将为 MenuItem.cshtml 提供形状替代。

  5. 正在为您的子主题中的菜单项创建替代形状

    转到您的子主题文件夹并添加一个文件 Views\MenuItem.cshtml 并开始呈现菜单项。这是我的 MenuItem.cshtml 文件的内容,它根据 bootstrap 规范将菜单项呈现为 <li> 结构:

    @*
      this shape alternate is displayed when a <li> element is rendered
      whereas the following code is based on Orchard.Core\Shapes\Views\Menu.cshtml
    *@
    
    @{
        // odd formatting in this file is to cause more attractive results in the output.
        var items = Enumerable.Cast<dynamic>((System.Collections.IEnumerable)Model);
    }
    @{
        if (!HasText(Model.Text)) {
            @DisplayChildren(Model)
        }
        else {
            if ((bool) Model.Selected) {
                Model.Classes.Add("current");
            }
    
            if (items.Any()) {
                Model.Classes.Add("dropdown");
            }
    
            @* morphing the shape to keep Model untouched*@
            Model.Metadata.Alternates.Clear();
            Model.Metadata.Type = "MenuItemLink";
    
            @* render the menu item only if it has some content *@
            var renderedMenuItemLink = Display(Model);
            if (HasText(renderedMenuItemLink)) {
                var tag = Tag(Model, "li");
                @tag.StartElement
                @renderedMenuItemLink
    
                if (items.Any()) {
                    <ul class="dropdown-menu">
                        @DisplayChildren(Model)
                    </ul>
                }
    
                @tag.EndElement
            }
        }
    }
    

    您还可以提供替代项来覆盖特定的菜单项类型,例如 Custom Link。该文件将是 MenuItemLink.cshtml,内容类似于

    @* 
      this shape alternate is displayed when menu link is _not_ of type "Content Menu Item" otherwise MenuItemLink-ContentMenuItem.cshtml is used
      whereas the following code is based on Orchard.Core\Shapes\Views\MenuItemLink.cshtml
    *@
    <a href="@Model.Href" @if (Model.Item.Items.Length > 0) { <text>class="dropdown-toggle" data-toggle="dropdown"</text> }>@Model.Text</a>
    

    如您所见,工作量很大但非常灵活。