如何更改 Orchard 中列表项形状的 DisplayType?
How to change DisplayType of List item shape in Orchard?
我有一个内容 MyContainer
,其中附加了一个 Container
部分。
然后我有几个 MyContainerItem
内容附有 Containable
部分,这些内容被分配给 MyContainer
。
现在,如果呈现内容 MyContainer
,它在内部使用列表形状,因此每个 MyContainerItem
内容都使用 Summary
显示类型呈现,这似乎是硬编码的在果园。
有没有办法在不改变核心代码的情况下,将MyContainerItem
的显示类型改为Detail
?
我在替补中尝试了变形技术,但无济于事。
嗯,我走错了路。
我想到替代方案会是更好的解决方案,因为它不会改变列表行为。
现在我是这样理解的:列表通常应该显示每个项目的摘要,当我单击该项目时会显示详细信息,这是有道理的。
因此,与其更改 DisplayType
,不如根据文档创建一个具有适当名称的替代项:
http://docs.orchardproject.net/Documentation/Accessing-and-rendering-shapes#NamingShapesandTemplates
在我的例子中,替代方案是 Content.Summary-MyContainerItem.cshtml
,内容如下:
@Model.Content.Items[0].Html
我之前在其他内容部分遇到过这个问题(不记得是哪个),但您可以采取以下步骤:
1 创建自定义部分并记录以附加到具有 ContainerPart 的内容类型:
public CustomContainerPart : ContentPart<CustomContainerPartRecord> {
public string DisplayType {
// property setter and getter
}
}
2 创建一个处理程序,将 CustomContainerPart 附加到具有 ContainerPart 的内容类型:
public class CustomContainerPartHandler : ContentHandler {
private readonly IContentDefinitionManager _contentDefinitionManager;
public CustomContainerPartHandler(IContentDefinitionManager contentDefinitionManager) {
_contentDefinitionManager = contentDefinitionManager;
}
protected override void Activating(ActivatingContentContext context) {
base.Activating(context);
// weld the CustomContainerPart dynamically, if the type has the ContainerPart
var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(context.ContentType);
if (contentTypeDefinition == null) {
return;
}
if (contentTypeDefinition.Parts.Any(part => part.PartDefinition.Name == typeof(ContainerPart).Name)) {
context.Builder.Weld<CustomContainerPart>();
}
}
}
3 为自定义部件创建驱动程序并使用此显示方法:
protected override DriverResult Display(CustomContainerPart part, string displayType, dynamic shapeHelper) {
return ContentShape("Parts_Container_CustomContained", () => {
var containerPart = part.As<ContainerPart>();
// copy code from Orchard.Core/Containers/Drivers/ContainerPartDriver.cs here and tweak it to use the CustomContainerPart display type property
// ..
var listShape = shapeHelper.List();
listShape.AddRange(pageOfItems.Select(item => _contentManager.BuildDisplay(item, part.DisplayType))); // here use your custom part setting
// ..
});
}
4 最后是你的 Placement.info:
<Place Parts_Container_Contained="-" />
<Match DisplayType="Detail">
<Place Parts_Container_CustomContained="Content:7.5"/>
</Match>
我有一个内容 MyContainer
,其中附加了一个 Container
部分。
然后我有几个 MyContainerItem
内容附有 Containable
部分,这些内容被分配给 MyContainer
。
现在,如果呈现内容 MyContainer
,它在内部使用列表形状,因此每个 MyContainerItem
内容都使用 Summary
显示类型呈现,这似乎是硬编码的在果园。
有没有办法在不改变核心代码的情况下,将MyContainerItem
的显示类型改为Detail
?
我在替补中尝试了变形技术,但无济于事。
嗯,我走错了路。
我想到替代方案会是更好的解决方案,因为它不会改变列表行为。
现在我是这样理解的:列表通常应该显示每个项目的摘要,当我单击该项目时会显示详细信息,这是有道理的。
因此,与其更改 DisplayType
,不如根据文档创建一个具有适当名称的替代项:
http://docs.orchardproject.net/Documentation/Accessing-and-rendering-shapes#NamingShapesandTemplates
在我的例子中,替代方案是 Content.Summary-MyContainerItem.cshtml
,内容如下:
@Model.Content.Items[0].Html
我之前在其他内容部分遇到过这个问题(不记得是哪个),但您可以采取以下步骤:
1 创建自定义部分并记录以附加到具有 ContainerPart 的内容类型:
public CustomContainerPart : ContentPart<CustomContainerPartRecord> {
public string DisplayType {
// property setter and getter
}
}
2 创建一个处理程序,将 CustomContainerPart 附加到具有 ContainerPart 的内容类型:
public class CustomContainerPartHandler : ContentHandler {
private readonly IContentDefinitionManager _contentDefinitionManager;
public CustomContainerPartHandler(IContentDefinitionManager contentDefinitionManager) {
_contentDefinitionManager = contentDefinitionManager;
}
protected override void Activating(ActivatingContentContext context) {
base.Activating(context);
// weld the CustomContainerPart dynamically, if the type has the ContainerPart
var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(context.ContentType);
if (contentTypeDefinition == null) {
return;
}
if (contentTypeDefinition.Parts.Any(part => part.PartDefinition.Name == typeof(ContainerPart).Name)) {
context.Builder.Weld<CustomContainerPart>();
}
}
}
3 为自定义部件创建驱动程序并使用此显示方法:
protected override DriverResult Display(CustomContainerPart part, string displayType, dynamic shapeHelper) {
return ContentShape("Parts_Container_CustomContained", () => {
var containerPart = part.As<ContainerPart>();
// copy code from Orchard.Core/Containers/Drivers/ContainerPartDriver.cs here and tweak it to use the CustomContainerPart display type property
// ..
var listShape = shapeHelper.List();
listShape.AddRange(pageOfItems.Select(item => _contentManager.BuildDisplay(item, part.DisplayType))); // here use your custom part setting
// ..
});
}
4 最后是你的 Placement.info:
<Place Parts_Container_Contained="-" />
<Match DisplayType="Detail">
<Place Parts_Container_CustomContained="Content:7.5"/>
</Match>