Razor Orchard-为主列表形状添加一个附加形状名称(即备用形状) 介绍问题

Razor Orchard-为主列表形状添加一个附加形状名称(即备用形状) 介绍问题,razor,orchardcms,Razor,Orchardcms,我想深刻修改乌节CMS标签列表的布局 下面是启用形状跟踪的示例 它为列表形状建议的唯一替代方法是~/Themes/themethemachine/Views/List.cshtml,因为页面呈现的是默认列表形状。我想有其他替代品,是特定的页面 阅读之后,我已经能够在razor中实现default List.cshtml。不过,我想做的是添加另一个备选模板,例如~/Themes/themetechine/Views/Parts.Tags.List.cshtml,而不是实现默认的List.cshtm

我想深刻修改乌节CMS标签列表的布局

下面是启用形状跟踪的示例

它为列表形状建议的唯一替代方法是
~/Themes/themethemachine/Views/List.cshtml
,因为页面呈现的是默认列表形状。我想有其他替代品,是特定的页面

阅读之后,我已经能够在razor中实现default List.cshtml。不过,我想做的是添加另一个备选模板,例如
~/Themes/themetechine/Views/Parts.Tags.List.cshtml
,而不是实现默认的List.cshtml模板

问题似乎是页面正在呈现通用的
列表
形状

相反,页面呈现的是
Parts\u Blogs\u BlogPost\u List
形状,这意味着
~/themesmachine/Views/Parts.Blogs.BlogPost.List.cshtml
可用

搜索和研究 下面的所有引用都来自博客文章,它解释了如何添加列表项替代项(而我想添加列表替代项)

我们真正想要的是一个替代模板。。。恰如其分地称之为形状 交替。。。[因此]启用形状跟踪。。。然后在列表中选择一篇文章。。。 [你会看到]我们已经有了一些可能的替代方案

我的列表内容也有一些可能的替代项。酷

我们需要以某种方式进入列表呈现。。。[t] 他被定义为违约 在代码中。。。[cshtml]模板可以在我们的 主题

好的。这是有道理的。我们可以覆盖列表渲染

正如形状跟踪所显示的那样,我们可以覆盖形状的列表渲染 通过创建Parts.blog.BlogPost.List.cshtml模板创建博客

这适用于alog,但不适用于blog标记页面()。你看,博客显示一个**Parts\u Blogs\u BlogPost\u列表形状,并建议一个合适的替代项,但是博客标签页面显示默认的列表形状,除了List.cshtml之外没有其他替代项

博客页面有大量备选页面

博客标签页面带有一个备用列表。cshtml

因此,我创建了一个List.cshtml而不是Parts.Blog.BlogPost.List.cshtml模板,并将其保存在我的主题视图目录中。(这里的一个问题是,一旦我们让它工作起来,我们将覆盖默认的列表呈现。)

然后我添加Razor代码(从Bertrand的帖子中复制粘贴)以覆盖列表的默认呈现当我刷新站点时,浏览器会呈现一个空白页面。它不工作。代码如下:

这在List.cshtml中不起作用

@using Orchard.DisplayManagement.Shapes;
@{
    var list = Model.ContentItems;
    var items = list.Items;
    var count = items.Count;
    var listTag = Tag(list, "ul");
    listTag.AddCssClass("content-items");
    listTag.AddCssClass("blog-posts");
    var index = 0;
}
@listTag.StartElement
    @foreach (var item in items) {
        var itemTag = Tag(item, "li");
        if (index == 0) {
            itemTag.AddCssClass("first");
        }
        else if (index == count - 1) {
            itemTag.AddCssClass("last");
        }
        @itemTag.StartElement
        @Display(item)
        @itemTag.EndElement
        ++index;
    }
@listTag.EndElement
@using Orchard.DisplayManagement.Shapes;
@{    
    //var list = Model.ContentItems; 
    //var items = list.Items;   

    var items = Model.Items; 
    var count = items.Count;

    //var listTag = Tag(list, "ul"); 

    var listTag = Tag(Model, "ul");    
    listTag.AddCssClass("content-items");
    listTag.AddCssClass("blog-posts");
    var index = 0;
}
@listTag.StartElement
    @foreach (var item in items) {
        var itemTag = Tag(item, "li");
        if (index == 0) {
            itemTag.AddCssClass("first");
        }
        else if (index == count - 1) {
            itemTag.AddCssClass("last");
        }
        @itemTag.StartElement
        @Display(item)
        @itemTag.EndElement
        ++index;
    }
@listTag.EndElement
作为故障排除步骤,我将List.cshtml替换为Hello world。

。Orchard按预期呈现标记。因此,Bertrand博客中的Razor代码和标签列表之间存在不兼容

为了找出什么是不兼容的,我一次尝试一行Betrand的代码,看看它在哪里中断(是的,VS比WM更好)。每次更改时,我都会重新启动WebMatrix并查看结果。这是破坏它的最小代码

罪犯

@using Orchard.DisplayManagement.Shapes;
@{
    var list = Model.ContentItems;
    var items = list.Items;
}
列表。项目在此处不合适。因此,我再次对其进行注释,并再次运行
Hello World

版本。此外,形状跟踪显示,在“我的标记/标记名”页面上,内容区域现在呈现列表两次。这正常吗

作为另一个步骤,我将
Model.ContentItems
替换为
Model
它可以工作。似乎,要覆盖List.cshtml模板,我们不能使用Model的ContentItems属性。以下是新的工作代码:

这在List.cshtml中有效

@using Orchard.DisplayManagement.Shapes;
@{
    var list = Model.ContentItems;
    var items = list.Items;
    var count = items.Count;
    var listTag = Tag(list, "ul");
    listTag.AddCssClass("content-items");
    listTag.AddCssClass("blog-posts");
    var index = 0;
}
@listTag.StartElement
    @foreach (var item in items) {
        var itemTag = Tag(item, "li");
        if (index == 0) {
            itemTag.AddCssClass("first");
        }
        else if (index == count - 1) {
            itemTag.AddCssClass("last");
        }
        @itemTag.StartElement
        @Display(item)
        @itemTag.EndElement
        ++index;
    }
@listTag.EndElement
@using Orchard.DisplayManagement.Shapes;
@{    
    //var list = Model.ContentItems; 
    //var items = list.Items;   

    var items = Model.Items; 
    var count = items.Count;

    //var listTag = Tag(list, "ul"); 

    var listTag = Tag(Model, "ul");    
    listTag.AddCssClass("content-items");
    listTag.AddCssClass("blog-posts");
    var index = 0;
}
@listTag.StartElement
    @foreach (var item in items) {
        var itemTag = Tag(item, "li");
        if (index == 0) {
            itemTag.AddCssClass("first");
        }
        else if (index == count - 1) {
            itemTag.AddCssClass("last");
        }
        @itemTag.StartElement
        @Display(item)
        @itemTag.EndElement
        ++index;
    }
@listTag.EndElement
继续阅读这篇文章

到目前为止,我们已经有效地接管了 列表,但实际的HTML[将]是。。。和以前一样 [除了]实施

好的。我跟在后面。我们希望修改渲染,而不仅仅是重新实现它

替代项是描述附加形状的字符串集合 当前形状的名称。。。在元数据中。替换任何形状的属性

明白了。现在,为什么“标记/标记名”页面不显示列表形状呈现所需的列表.cshtml以外的其他选项

我们所需要做的就是把这个[替补名单]加进去。。。[并确保]尊重生命周期

太好了。也许我们可以在“标记/标记名”页面上为列表形状添加另一个替代项。但是,这样做与Betrand所解释的不同虽然Betrand的博文非常出色,但它解释了如何为一个项目添加备选方案,而我想为列表添加备选方案

在List.cshtml模板中,我将为列表项添加一个替代项,如下所示:

ShapeMetadata metadata = item.Metadata;
string alternate = metadata.Type + "_" +
        metadata.DisplayType + "__" +
        item.ContentItem.ContentType +
        "_First";
metadata.OnDisplaying(ctx => {
    metadata.Alternates.Add(alternate);
});
所以

[t] 形状跟踪的替代项列表现在包含一个新项

但是,我应该在哪里以及如何为列表形状添加一个替代项?Bertrand建议查看这篇博文。下面的引文来自那篇文章

但是,如果要为特定对象更改另一个形状模板,该怎么办 页面,例如主页上的主要内容形状

这看起来很合适,因为我的示例是标记页面上的主列表形状。要做到这一点,我们

。。。处理每次命名为“内容”的形状时触发的事件 [在本例中为“列表”]即将显示。[它]是在形状表提供程序中实现的,您可以在该提供程序中执行所有与形状相关的站点范围操作

太好了!下面是我为主列表形状添加另一个模板的实现

TheThemeMachine>ListShapeProvi
orchard.exe
feature enable Orchard.CodeGeneration
codegen theme My.FirstTheme /CreateProject:true
theme enable My.FirstTheme
feature enable Orchard.DesignerTools
orchard.exe
setup /SiteName:SITE /AdminUsername:ME /AdminPassword:PWD /DatabaseProvider:SqlCe
feature enable Orchard.CodeGeneration
codegen theme My.FirstTheme /CreateProject:true
theme enable My.FirstTheme
namespace My.FirstTheme
{
    using Orchard.DisplayManagement.Descriptors;
    public class ListShapeProvider : IShapeTableProvider
    {
        public void Discover(ShapeTableBuilder builder)
        {
            System.Diagnostics.Debugger.Break();
            // implementation here
        }
    }
}