Orchard - 在布局文件中查询零件

Orchard - Querying the Part On A Layout File

我一直卡在“对象引用未设置到对象的实例”错误消息上。

我们正在尝试使用附加到 Page 类型的 PagePart 字段在布局文件的 HEAD 中动态 link 一个 CSS 文件。请参阅下面的代码。

<!-- DYNAMIC CSS-->
var contentItem = Model.ContentItem;
var pagePart = (PagePart)contentItem.PagePart;

if (!String.IsNullOrWhiteSpace(pagePart.FestivalProgramName))
{
    <link ref="@Url.Content("/Themes/MyTheme/Styles/festival-programs/" + pagePart.FestivalProgramName + ".css")" rel="stylesheet" type="text/css">
}

这在一个名为的文件中:

Layout.cshtml

这(显然)有些不对劲,因为当我附加到调试器并查看时 pagePart 为“null”。我知道布局文件不知道它与“页面”内容类型相关联,但此布局仅用于页面。不管怎样,这与我们 Orchard 网站其他地方的代码非常相似。非常感谢任何帮助或建议!

谢谢,T

在Layout中,Model就是Layoutobject。它与将要呈现到内容区域中的任何内容无关。

我认为您尝试做的事情应该通过覆盖页面模板 (Content-Page.Detail.cshtml) 来完成。 (请注意 Detail 部分,您可能不想在汇总显示多个页面时导入每个 css) 在那里你可以做:

@{
    var contentItem = Model.ContentItem; // The Page content item
    var pagePart = contentItem.Page; // Note that casting to PagePart won't work, because it does not exist

    if (!String.IsNullOrWhiteSpace(pagePart.FestivalProgramName.Value))
    {
        // "Orchard's" way to include styles
        Style.Include("festival-programs/" + pagePart.FestivalProgramName.Value + ".css");
    }
}

编辑:

您可能应该做的(我假设不是每个页面都是节日页面)是创建一个新的内容类型:FestivalPage。然后将以下部分附加到此内容类型(与页面内容类型相同):

  • 普通
  • 稍后发布
  • 标题
  • 自动布线
  • Body(Orchard 1.8.1 及更低版本)
  • 布局(果园 1.9.x)
  • 标签
  • 本地化
  • 菜单

你的领域:

  • 节日节目名称

然后创建一个备用 Content-FestivalPage.Detail.cshtml,内容如下:

@using Orchard.Utility.Extensions;
@{
    if (Model.Title != null) {
        Layout.Title = Model.Title;
    }

    Model.Classes.Add("content-item");

    var contentTypeClassName = ((string)Model.ContentItem.ContentType).HtmlClassify();
    Model.Classes.Add(contentTypeClassName);

    var tag = Tag(Model, "article");

    var contentItem = Model.ContentItem; // The FestivalPage content item
    var pagePart = contentItem.FestivalPage; // The FestivalPage part with the FestivalProgramName field

    if (!String.IsNullOrWhiteSpace(pagePart.FestivalProgramName.Value))
    {
        // "Orchard's" way to include styles
        Style.Include("festival-programs/" + pagePart.FestivalProgramName.Value + ".css");
    }
}

// -- Default Orchard content --
@tag.StartElement
    <header>
        @Display(Model.Header)
        @if (Model.Meta != null) {
            <div class="metadata">
                @Display(Model.Meta)
            </div>
        }
    </header>
    @Display(Model.Content)
    @if(Model.Footer != null) {
        <footer>
            @Display(Model.Footer)
        </footer>
    }
@tag.EndElement
// ----

这样您就不会妨碍应用程序的正常页面。

非常感谢您的回复。您的解决方案有效,但在我的情况下无效,因为我使用布局选择器模块并且无法在 Page.Detail 级别覆盖,因为这意味着一种布局 - 或者至少从我的角度来看似乎是这样。我找到了另一种选择,但可以解决问题。

我们已经利用 Handlers class 将 META 内容插入页面的 HEAD 并且感谢您的反馈和这个线程 Adding an element to page <head> in Orchard CMS,我突然想到使用相同的 Handler插入 CSS link.

PagePartHandler.cs。

    using System;
using MyModuleName.Models;
using Orchard.ContentManagement.Handlers;
using Orchard.Core.Title.Models;
using Orchard.Data;
using Orchard.UI.Resources;
using Orchard.Utility.Extensions;

namespace MyModuleName.Handlers {
    public class PagePartHandler : ContentHandler {
        private readonly IResourceManager _resourceManager;

        public PagePartHandler(
            IRepository<PagePartRecord> repository,
            IResourceManager resourceManager) {

            _resourceManager = resourceManager;
            Filters.Add(StorageFilter.For(repository));

            OnGetDisplayShape<PagePart>(RegisterFestivalProgramStyle);
        }

        private void RegisterFestivalProgramStyle(BuildDisplayContext context, PagePart part) {
            if (context.DisplayType != "Detail")
                return;

            if (String.IsNullOrWhiteSpace(part.FestivalProgramName))
                return;

            _resourceManager.RegisterLink(new LinkEntry
            {
                Rel = "stylesheet",
                Type = "text/css",
                Href = "/Themes/Bootstrap/Styles/festival-programs/" + part.FestivalProgramName + ".css"
            });
        }
    }
}

这使用了传统的 link 样式,而不是 ResourceManifest.cs,但是可行!