1

約 130 ページのサイトをオーチャードに構築しています。「メイン メニュー」と呼ばれるナビゲーション メニューをセットアップし、すべてのページを階層でセットアップしました (表示している例はサンドボックス サイトのものであり、実際の開発サイトではありません)。

ここに画像の説明を入力

デフォルトのウィジェット レイヤーの「AsideFirst」ゾーンに、上記の「メイン メニュー」を参照するメニュー ウィジェットを追加しました。開始レベルは 0 に設定され、表示するレベルは 0 に設定されています。フロント エンドでは、シェイプ トレーサーを使用して、「Parts.MenuWidget-AsideFirst.cshtml」という名前の代替を作成しました。

メニューは問題なく表示されますが、現在のページに関連するページのみを表示できるように、コアの「ナビゲーション」ドライバーをどこから変更すればよいかわかりません。たとえば、「テスト II」ページを表示している場合、次の HTML をレンダリングするナビゲーションが必要です。

<ul>
    <li><a href="/testing-i/">Testing I</a></li>
    <li>
        <a href="/testing-ii/" class="active">Testing II</a>
        <ul>
            <li><a href="/bark-bark/"></a></li>
        </ul>
    </li>
    <li><a href="/testing-iii/">Testing III</a>
</ul>

私が使用している代替には、次のコードがあります。これは、最上位のセクションのいずれかにいる場合に機能しますが、より深いレベルには機能しません。次のコードは Orchard のやり方ではないため、ドライバーとハンドラーを使用してこれを適切に達成する方法を知りたいです。特に、とにかく必要なことを達成していないためです。

@{
var navTag = Tag(Model, "nav");
navTag.AddCssClass("nav-sidebar");
@navTag.StartElement;

    var ulTag = Tag(Model, "ul");
    @ulTag.StartElement
        // Model is Model.Menu from the layout (Layout.Menu)
        var items = getSectionItems((IList<dynamic>)Enumerable.Cast<dynamic>(Model.Menu.Items));

        // Add First and Last Classes
        if (items.Any())
        {
            items[0].Classes.Add("first");
            items[items.Count - 1].Classes.Add("last");
        }

        // List Items
        foreach (var listModel in items)
        {
            // Current URL
            string requestUrl = getRequestUrl();
            string modelUrl = getModelUrl(listModel);
            bool showMenu = false;

            if (isActivePage(requestUrl, modelUrl))
            {
                listModel.Classes.Add("active");
                showMenu = true;
            }

            if (showMenu)
            {
                // Sub Items
                var listItems = Enumerable.Cast<dynamic>((System.Collections.IEnumerable)listModel);
                if (listItems.Any())
                {
                    listModel.Classes.Add("dropdown");
                }

                // List Tag
                var liTag = Tag(listModel, "li");

                @liTag.StartElement;

                    listModel.Metadata.Alternates.Clear();
                    listModel.Metadata.Type = "MenuItemLink";

                    // Top Level Nav Items
                    string className = System.Text.RegularExpressions.Regex.Replace(listModel.Href, "[^A-Za-z0-9-]", "");
                    className = className.Length > 0 ? className : "home";

                    <a href="@listModel.Href" class="@className">@listModel.Text</a>

                    if (listItems.Any())
                    {
                        <ul>
                            @DisplayChildren(listModel)
                        </ul>
                    }

                @liTag.EndElement;
            }
        }

    @ulTag.EndElement;

@navTag.EndElement;
}

@functions{
private IList<dynamic> getSectionItems(IList<dynamic> sectionItems)
{
    return sectionItems;
}

private string getRequestUrl()
{
     return Request.Path.Replace(Request.ApplicationPath, string.Empty).TrimEnd('/').ToUpperInvariant();
}

private string getModelUrl(dynamic listModel)
 {
     return listModel.Href.Replace(Request.ApplicationPath, string.Empty).TrimEnd('/').ToUpperInvariant();
 }

private bool isActivePage(string requestUrl, string modelUrl)
{
    if (requestUrl == modelUrl || (!string.IsNullOrEmpty(modelUrl) && requestUrl.StartsWith(modelUrl + "/")))
    {
        return true;
    }

    return false;
}
}
4

1 に答える 1

0

更新しました

次のコードを使用してこれを解決しました。私は近くにいましたが、それでもより良い解決策があればいいのにと思います。最大 4 レベルの深さまでこれを解決します。

@{
    var navTag = Tag(Model, "nav");
    navTag.AddCssClass("nav-sidebar");
    @navTag.StartElement;

        var ulTag = Tag(Model, "ul");
        @ulTag.StartElement
            // Model is Model.Menu from the layout (Layout.Menu)
            string requestUrl = getRequestUrl();
            var menus = (IList<dynamic>)Enumerable.Cast<dynamic>(Model.Menu.Items);
            var items = getSectionItems(requestUrl, menus);

            // List Items
            foreach (var listModel in items)
            {
                // Sub Items
                var listItems = Enumerable.Cast<dynamic>((System.Collections.IEnumerable)listModel);
                if (listItems.Any())
                {
                    listModel.Classes.Add("nav-section");
                }

                // List Tag
                var liTag = Tag(listModel, "li");

                @liTag.StartElement;

                    listModel.Metadata.Alternates.Clear();
                    listModel.Metadata.Type = "MenuItemLink";

                    // Top Level Nav Items
                    string className = System.Text.RegularExpressions.Regex.Replace(listModel.Href, "[^A-Za-z0-9-]", "");
                    className = className.Length > 0 ? className : "home";

                    <a href="@listModel.Href" class="@className">@listModel.Text</a>

                    if (listItems.Any())
                    {
                        <ul>
                            @DisplayChildren(listModel)
                        </ul>
                    }

                @liTag.EndElement;
            }

        @ulTag.EndElement;

    @navTag.EndElement;
}

@functions{
    private IList<dynamic> getSectionItems(string requestUrl, IList<dynamic> sectionItems1)
    {
        foreach (var sectionItem1 in sectionItems1)
        {
            if (getModelUrl(sectionItem1) == requestUrl)
                return sectionItem1;

            foreach (var sectionItem2 in sectionItem1)
            {
                if (getModelUrl(sectionItem2) == requestUrl)
                    return sectionItem2;

                foreach (var sectionItem3 in sectionItem2)
                {
                    if (getModelUrl(sectionItem3) == requestUrl)
                        return sectionItem3;

                    foreach (var sectionItem4 in sectionItem3)
                    {
                        if (getModelUrl(sectionItem4) == requestUrl)
                            return sectionItem4;
                    }
                }
            }
        }

        return sectionItems1;
    }

    private string getRequestUrl()
    {
         return Request.Path.Replace(Request.ApplicationPath, string.Empty).TrimEnd('/').ToUpperInvariant();
    }

    private string getModelUrl(dynamic listModel)
     {
         return listModel.Href.Replace(Request.ApplicationPath, string.Empty).TrimEnd('/').ToUpperInvariant();
     }

    private bool isActivePage(string requestUrl, string modelUrl)
    {
        if (requestUrl == modelUrl || (!string.IsNullOrEmpty(modelUrl) && requestUrl.StartsWith(modelUrl + "/")))
        {
            return true;
        }

        return false;
    }
}
于 2013-05-28T20:49:15.957 に答える