肯蒂科是魔鬼!使用 HierarchicalViewer WebParts(这是我尝试它们的第一天)。我有以下层次结构:
-
Main Page
-
SubPage 1
[文档包括字段:标题、简介、底部内容]-
SubSubpage 1.1
-
SubSubpage 1.2
-
SubSubpage 1.3
-
-
SubPage 2
[相同的字段...]-
...
-
-
在Main Page
,我想自动显示每个Subpage
:包括Subpage
标题和介绍,所有SubSubpage
的列表,然后Subpage
底部内容。换句话说:
期望输出:
<section>
<h1>[Subpage 1 Title]</h1>
<p>[Subpage 1 Intro]</p>
<ul>
<li>[SubSubpage 1.1 Title]</li>
<li>[SubSubpage 1.2 Title]</li>
<li>[SubSubpage 1.3 Title]</li>
</ul>
<p>[Subpage 1 Bottom Content]</p>
</section>
<section>
<h1>[Subpage 2 Title]</h1>
<p>[Subpage 2 Intro]</p>
<ul>
<li>[SubSubpage 2.1 Title]</li>
<li>[SubSubpage 2.2 Title]</li>
<li>[SubSubpage 2.3 Title]</li>
</ul>
<p>[Subpage 2 Bottom Content]</p>
</section>
...
很简单,对吧?不适合肯蒂科...不,他们不做人的逻辑。我无法显示底部内容。
我有以下分层转换:
级别 0 的项目转换:
<section>
<h1><%# Eval("Subpage Title") %></h1>
级别 1 的页眉、页脚和项目转换(分别):
<ul>
| </ul>
| <li><%# Eval("SubSubpage Title") %></li>
必须为级别 1 指定空白分隔符转换,以便它不会继承级别 0。(为什么只在所有其他未指定的级别上插入时才为级别 0 指定分隔符?
最后
级别 0 的分隔符和页脚转换:
<!-- Only works on the Footer, not the Separator:
<%# Eval("Subpage Bottom Content") %>-->
</section>
(为什么我必须为分隔符和页脚创建转换?为什么我不能只做页脚 - 最合乎逻辑 - 并且它适用于级别 0 的每个项目?我离题了。
我的底部内容不起作用的原因是,您似乎无法在分隔符转换上Eval()
文档字段。
弄清楚起来相当复杂,在这个问题中描述几乎同样复杂。我需要知道如何使用分层转换(或者其他东西,如果你知道的话)来完成上面的所需输出!我正在使用Kentico 7(不幸的是)。
更新
我只能访问CMSDesk和SiteManager的前端访问权限,我既无法访问后端文件系统,也不知道 ASP.NET。
花了很多时间才弄清楚这一点,虽然我同意 Kentico 的 API 一团糟,但看起来这实际上是 ASP 的限制。NET的<asp:repeater>
控制肯蒂科的中继器和观众所基于的。
看看SO上的这个问题,有人遇到了与您在<asp:repeater>
的分隔符模板上遇到的相同问题。
然后,查看此答案,其中显示了可能的解决方法。
我无法确切地弄清楚为什么项目分隔符不能绑定到 asp:repeater 的 eval() 数据,但我找到的每个示例都显示项目分隔符仅包含纯文本 - 没有数据正在解析。
作为分层转换的替代方法,您可以随时尝试嵌套转发器并绑定其数据 OnInit(如果必须,有时不需要)。 如果你太复杂,它可能会变得混乱,但这是一种可靠的技术。
例如,在页面模板中设置转发器后,将其添加到该转发器的转换中:
<cms:CMSRepeater
ID="ControlID"
DelayedLoading="true"
runat="server"
Path="./%"
ClassNames="custom.DocTypeName;"
CategoryName=""
MaxRelativeLevel="-1"
SelectTopN="0"
SelectOnlyPublished="true"
OrderBy=""
Columns=""
TransformationName="custom.DocTypeName.TransformationName"
RelationshipName=""
RelatedNodeIsOnTheLeftSide=""
HideControlForZeroRows="false"
enableViewState="false"
/>
<script runat="server">
protected override void OnInit(EventArgs e)
{
// an example of how to bind data OnInit
// to get the data you need
ControlID.WhereCondition = "NodeParentID = '"+ GetSearchValue("NodeID")+"'";
}
</script>
在这种情况下(但不是一般情况下),最干净和正确的解决方案是使用嵌套中继器(如 Jerreck 建议的那样)。
您只需要以下两个转换;主要转换:
<section>
<h1><%# Eval("Title") %></h1>
<p><%# Eval("Intro") %></p>
<ul>
<cms:CMSRepeater ID="repListItems" runat="server" DelayedLoading="true"
ClassNames="your.ClassName" TransformationName="your.NestedRepeater.TransformationID" />
</ul>
<p><%# Eval("BottomContent") %></p>
</section>
一个用于子子页面:
<li><%# Eval("DocumentName") %></li>
当然,将 Web 部件的嵌套控件 ID 属性设置为适当的值。无需进一步编码。您可以在此处找到有关使用嵌套控件的详细信息。希望它能帮助你。
注意:使用 Kentico v8+,您可以在转换(使用 SubLevelPlaceHolder)中指定应渲染子关卡的位置。