Orchard - 为主List形状添加其他形状名称(即备用)

时间:2014-04-30 03:04:36

标签: razor orchardcms

介绍问题

我想深刻修改 Orchard CMS标签列表的布局。

这是启用了形状跟踪的example page

它为List形状建议的唯一替代是~/Themes/TheThemeMachine/Views/List.cshtml,因为页面呈现默认的List形状。我想有其他特定于页面的替换。

阅读Orchard list customization后,我已经能够在razor中实现默认的List.cshtml。但是,我想要做的是添加另一个备用,例如~/Themes/TheThemeMachine/Views/Parts.Tags.List.cshtml,而不是实现默认的List.cshtml模板。

问题似乎是页面呈现通用List形状。

相比之下,blog post list页面呈现Parts_Blogs_BlogPost_List形状,这意味着~/Themes/TheThemeMachine/Views/Parts.Blogs.BlogPost.List.cshtml可用。

搜索和研究

以下所有引文均来自Orchard list customization博客文章,其中介绍了如何添加列表备用(但我想添加列表备用)。

  

我们真正想要的是一个替代模板......恰当地称为Shape   Alternates ... [so]启用Shape Tracing ...并在列表中选择一个帖子...   [你会看到]我们已经有了一些可能的替补。

我的example page也有一些可能的列表内容替代。凉。

  

我们需要以某种方式进入列表渲染... [t]默认是定义的   在代码中... [可以]覆盖我们的新[cshtml]模板   主题。

好。那讲得通。我们可以覆盖列表渲染。

  

正如Shape Tracing可以显示的那样,我们可以覆盖a的列表渲染   博客通过创建Parts.Blog.BlogPost.List.cshtml模板。

这适用于alog但不适用于博客标记页面(example page)。您看,博客显示** Parts_Blogs_BlogPost_List形状并建议适当的替代形式,但博客标签页面显示默认的List形状,除了List.cshtml之外没有替代。

博客页面与替补嘉豪 enter image description here

使用一个备用List.cshtml

博客标签页 enter image description here

因此,我创建了一个 List.cshtml而不是Parts.Blog.BlogPost.List.cshtml 模板,并将其保存在我主题的Views目录中。 (这里的一个问题是,一旦我们开始工作,我们将覆盖默认的List渲染。)

enter image description here

然后我添加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

作为故障排除步骤,我将List.cshtml替换为<p>Hello world.</p>。 Orchard按预期呈现标记。因此,Bertrand博客的Razor代码和Tags List之间存在某些不相容之处。

enter image description here

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

罪魁祸首

@using Orchard.DisplayManagement.Shapes;
@{
    var list = Model.ContentItems;
    var items = list.Items;
}

list.Items在这里不合适。所以我再次对其进行评论并再次运行<p>Hello World</p>版本。此外,形状跟踪显示,在我的标签/标记名页面上,内容区域现在渲染列表两次。这是正常的吗?

enter image description here

作为另一个步骤,我只使用Model.ContentItems替换Model有效。看来,要覆盖List.cshtml模板,我们不能使用Model的ContentItems属性。这是新的,有效的代码:

这在List.cshtml中有效

@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 [将]与我们以前的相同   [除了]实施。

好。我跟着。我们想要修改渲染而不仅仅是重新实现它。

  

Alternates是描述其他形状的字符串集合   任何形状的Metadata.Alternates属性中当前形状的名称。

疑难杂症。现在,为什么“标签/标记名称”页面没有显示除List.cshtml之外的其他替代项来呈现List形状?

  

我们需要做的就是添加到这个[替代品]列表中...... [并确保]尊重生命周期......

大。也许我们可以在Tags / tagname页面上为List形状添加另一个替代。但是,这样做与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]来自Shape Tracing的替代品列表现在包含一个新项目。

在哪里以及如何为List形状添加备用文字? Bertrand建议您查看Shape Table Providers博文。以下引用来自该帖子。

  

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

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

  

...处理每次名为&#34; Content&#34;的形状时触发的事件。   [在我们的案例中&#34;列表&#34;]即将显示。 [它]在形状表提供程序中实现,您可以在其中执行与所有形状相关的站点范围操作。

大!这是我为主List形状添加另一个模板的实现。

TheThemeMachine&gt; ListShapeProvider.cs

namespace Themes.TheThemeMachine
{
    using Orchard.DisplayManagement.Descriptors;
    public class ListShapeProvider : IShapeTableProvider
    {
        public void Discover(ShapeTableBuilder builder)
        {
            System.Diagnostics.Debugger.Break(); // break not hit
            builder.Describe("List").OnDisplaying(displaying => {
                // do stuff to the shape
                displaying.ShapeMetadata.Alternates.Add("Tags__List");
            });
        }
    }
}

上面的构建和运行但没有点击断点,也没有为/ tags页面上的List形状添加替代。所以我查看了Orchard.Azure.MediaServices模块及其实现IShapeTableProvider的CloudVideoPlayerShape。它的断点确实受到了打击。我的ListShapeProvider代码与CloudVideoPlayerShape的代码有什么根本的不同?

另外,我按照Bertrand博客文章的建议安装了 Orchard.Themes.CustomLayoutMachine.1.0.nupkg 。遗憾的是,它不再包含IShapeTableProvider的实现。

我还查看了this szmyd post,它没有解释IShapeTableProvider代码的放置位置。

此外,我安装了Orchard Gallery的Contoso主题。它在添加对Microsoft.CSharp.的引用后工作和构建它还包括IShapeTableProvider的实现。万岁!将其ContentShapeProvider与我的ListShapeProvider进行比较会发现一个微妙但重要的区别:

Contoso.csproj

<ItemGroup>
    <Compile Include="Code\ContentShapeProvider.cs" />
</ItemGroup>

我的实现并没有在编译中包含.cs文件,因为我的主题既没有.csproj也没有App_Code文件夹。因此,我使用以下代码生成重新创建了我的主题:

orchard.exe
feature enable Orchard.CodeGeneration
codegen theme My.FirstTheme /CreateProject:true
theme enable My.FirstTheme
feature enable Orchard.DesignerTools

添加ListShapeProvider.cs文件时,Visual Studio会自动为该文件添加一个ItemGroup / Compile条目,其中包含编译中的代码。万岁!

2 个答案:

答案 0 :(得分:3)

这两篇文章会有所帮助。

以下是我自己最低限度解决方案的步骤。

下载并解压缩Orchard.Source.1.8.zip

打开&#34; \ Downloads \ Orchard.Source.1.8 \ src \ Orchard.sln&#34;在Visual Studio中。

构建解决方案以创建orchard.exe

使用orchard.exe生成新主题。使用 CreateProject:true ,因为您需要csproj来包含.cs文件。

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

在VS中,将 ListShapeProvier.cs 文件添加到主题中的根(或任何文件夹)。

ListShapeProvier

将以下代码添加到ListShapeProvider.cs。

namespace My.FirstTheme
{
    using Orchard.DisplayManagement.Descriptors;
    public class ListShapeProvider : IShapeTableProvider
    {
        public void Discover(ShapeTableBuilder builder)
        {
            System.Diagnostics.Debugger.Break();
            // implementation here
        }
    }
}

构建解决方案。

运行Orchard.Web。

Visual Studio将在System.Diagnostics.Debugger.Break().中断,如果没有,请转到Orchard仪表板并将My.FirstTheme设为当前主题。

现在阅读Shape Shifting以实施public void Discover(ShapeTableBuilder builder)

答案 1 :(得分:1)