显示内容选择器字段中的容器部件项
Displaying Container Part Items From Content Picker Field
我有一个名为 DayTile 的内容类型,我设置了一个仅限于 HotelSection 类型的内容选择器字段。此类型是酒店类型的容器。
我想在 DayTile 选择该部分时呈现 HotelSection 中的所有酒店。这可能吗?
根据我目前的尝试,HotelSection 包含的项目似乎无法作为内容选择器字段进行访问。
如果我理解正确的话,这绝对是可能的。
您将希望覆盖 theme/module 中的 Fields.ContentPicker 视图,并且在 foreach 循环中,您希望显示该 HotelSection 的内容,而不是向每个 HotelSection 显示 link item,它将依次显示 HotelSection 中包含的所有酒店,如下所示:
@using Orchard.ContentPicker.Fields
@using Orchard.Utility.Extensions;
@{
var field = (ContentPickerField) Model.ContentField;
string name = field.DisplayName;
var contentItems = field.ContentItems;
}
<p class="content-picker-field content-picker-field-@name.HtmlClassify()">
<span class="name">@name</span>
@if(contentItems.Any()) {
foreach(var contentItem in contentItems) {
@Display(contentItem.ContentManager.BuildDisplay(contentItem, "Detail"))
}
}
else {
<span class="value">@T("No content items.")</span>
}
</p>
如果您希望直接从内容选择器字段中访问酒店,您将需要向视图中添加更多内容,有点乱,但像这样:
@using Orchard.ContentPicker.Fields
@using Orchard.Utility.Extensions;
@{
var field = (ContentPickerField) Model.ContentField;
string name = field.DisplayName;
var contentItems = field.ContentItems;
}
<p class="content-picker-field content-picker-field-@name.HtmlClassify()">
<span class="name">@name</span>
@if(contentItems.Any()) {
foreach(var contentItem in contentItems) {
var container = contentItem.As<ContainerPart>();
if(container == null) {
continue;
}
var hotels = contentItem.ContentManager
.Query(VersionOptions.Published)
.Join<CommonPartRecord>().Where(x => x.Container.Id == container.Id)
.Join<ContainablePartRecord>().OrderByDescending(x => x.Position);
foreach(var hotel in hotels) {
// do something
}
}
}
else {
<span class="value">@T("No content items.")</span>
}
</p>
我在顶部缺少一些 using 语句,但它的要点就在那里。
所选内容项由 ContentPickerField
s ContentItems
属性 公开(参见 Orchard.ContentPicker.Fields.ContentPickerField)。
要从 DayTile 内容项访问它,比方说从名为 "Content-DayTile.cshtml" 的 Razor 模板,您可以这样做:
@{
dynamic contentItem = Model.ContentItem; // How to access the content item depends on the context. In this case, we're in a Content shape template.
// Assuming your picker field is named "HotelSections" and attached to your DayTile content type (which in reality means it's attached to an automatically created part called "DayTile").
var picker = contentItem.DayTile.HotelSections;
var hotelSectionContentItems = picker.ContentItems; // Typed as IEnumerable<ContentItem>.
}
<ul>
@foreach(var hotelSectionContentItem in hotelSectionContentItems)
{
// You can now either access individual parts and fields of each hotel section content item and render it, or you can choose to build a shape for each item and display that. Here are examples:
<li>@hotelSectionContentItem.TitlePart.Title</li>
// or:
// Build a content shape for the content item.
var hotelSectionContentShape = BuildDisplay(hotelSectionContentItem, "Summary");
// Render the shape.
<li>@Display(hotelSectionContentShape)</li>
}
我有一个名为 DayTile 的内容类型,我设置了一个仅限于 HotelSection 类型的内容选择器字段。此类型是酒店类型的容器。
我想在 DayTile 选择该部分时呈现 HotelSection 中的所有酒店。这可能吗?
根据我目前的尝试,HotelSection 包含的项目似乎无法作为内容选择器字段进行访问。
如果我理解正确的话,这绝对是可能的。
您将希望覆盖 theme/module 中的 Fields.ContentPicker 视图,并且在 foreach 循环中,您希望显示该 HotelSection 的内容,而不是向每个 HotelSection 显示 link item,它将依次显示 HotelSection 中包含的所有酒店,如下所示:
@using Orchard.ContentPicker.Fields
@using Orchard.Utility.Extensions;
@{
var field = (ContentPickerField) Model.ContentField;
string name = field.DisplayName;
var contentItems = field.ContentItems;
}
<p class="content-picker-field content-picker-field-@name.HtmlClassify()">
<span class="name">@name</span>
@if(contentItems.Any()) {
foreach(var contentItem in contentItems) {
@Display(contentItem.ContentManager.BuildDisplay(contentItem, "Detail"))
}
}
else {
<span class="value">@T("No content items.")</span>
}
</p>
如果您希望直接从内容选择器字段中访问酒店,您将需要向视图中添加更多内容,有点乱,但像这样:
@using Orchard.ContentPicker.Fields
@using Orchard.Utility.Extensions;
@{
var field = (ContentPickerField) Model.ContentField;
string name = field.DisplayName;
var contentItems = field.ContentItems;
}
<p class="content-picker-field content-picker-field-@name.HtmlClassify()">
<span class="name">@name</span>
@if(contentItems.Any()) {
foreach(var contentItem in contentItems) {
var container = contentItem.As<ContainerPart>();
if(container == null) {
continue;
}
var hotels = contentItem.ContentManager
.Query(VersionOptions.Published)
.Join<CommonPartRecord>().Where(x => x.Container.Id == container.Id)
.Join<ContainablePartRecord>().OrderByDescending(x => x.Position);
foreach(var hotel in hotels) {
// do something
}
}
}
else {
<span class="value">@T("No content items.")</span>
}
</p>
我在顶部缺少一些 using 语句,但它的要点就在那里。
所选内容项由 ContentPickerField
s ContentItems
属性 公开(参见 Orchard.ContentPicker.Fields.ContentPickerField)。
要从 DayTile 内容项访问它,比方说从名为 "Content-DayTile.cshtml" 的 Razor 模板,您可以这样做:
@{
dynamic contentItem = Model.ContentItem; // How to access the content item depends on the context. In this case, we're in a Content shape template.
// Assuming your picker field is named "HotelSections" and attached to your DayTile content type (which in reality means it's attached to an automatically created part called "DayTile").
var picker = contentItem.DayTile.HotelSections;
var hotelSectionContentItems = picker.ContentItems; // Typed as IEnumerable<ContentItem>.
}
<ul>
@foreach(var hotelSectionContentItem in hotelSectionContentItems)
{
// You can now either access individual parts and fields of each hotel section content item and render it, or you can choose to build a shape for each item and display that. Here are examples:
<li>@hotelSectionContentItem.TitlePart.Title</li>
// or:
// Build a content shape for the content item.
var hotelSectionContentShape = BuildDisplay(hotelSectionContentItem, "Summary");
// Render the shape.
<li>@Display(hotelSectionContentShape)</li>
}