我想深刻修改 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之外没有替代。
博客页面与替补嘉豪
使用一个备用List.cshtml博客标签页
因此,我创建了一个 List.cshtml而不是Parts.Blog.BlogPost.List.cshtml 模板,并将其保存在我主题的Views目录中。 (这里的一个问题是,一旦我们开始工作,我们将覆盖默认的List渲染。)
然后我添加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之间存在某些不相容之处。
为了找出究竟是什么不相容的东西,我一次尝试Betrand的代码,看看它在哪里打破(是的,VS会比WM更好)。每次更改时,我都会重新启动WebMatrix并查看结果。这是打破它的最小代码。
罪魁祸首
@using Orchard.DisplayManagement.Shapes;
@{
var list = Model.ContentItems;
var items = list.Items;
}
list.Items
在这里不合适。所以我再次对其进行评论并再次运行<p>Hello World</p>
版本。此外,形状跟踪显示,在我的标签/标记名页面上,内容区域现在渲染列表两次。这是正常的吗?
作为另一个步骤,我只使用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条目,其中包含编译中的代码。万岁!
答案 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 文件添加到主题中的根(或任何文件夹)。
将以下代码添加到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)