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,但是可行!
我一直卡在“对象引用未设置到对象的实例”错误消息上。
我们正在尝试使用附加到 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,但是可行!