以下是我要做的事:
我有一个内容项目“旋转木马主持人”。本质上,这将在旋转木马中呈现它的子项。我希望有足够的灵活性来拥有任意数量的子项目。我还希望灵活性能够指定每个子项目的表示方式--它们可能是相同的,也可能是不同的。我用的是Sitecore 6.5。
旋转木马是旋转木马。我需要生成这样的标记(从项目"Carousel演示者“):
<div class="jcarousel">
<ul>
<li> ... MARKUP FROM ITEM 1 ... </li>
<li> ... MARKUP FROM ITEM 2 ... </li>
... and so on
</ul>
</div>以下是我尝试过的:
代码背后:
protected void Page_Load(object sender, EventArgs e)
{
// Get all children and render them inside the <ul>
var kids = Sitecore.Context.Item.GetChildren();
foreach (Item snippet in kids)
{
// RENDER THE ITEMS HERE INTO THE PLACEHOLDER...
// Get the first rendering from item's presentation definition
RenderingReference rendering = snippet.Visualization.GetRenderings(Sitecore.Context.Device, false).FirstOrDefault();
// We assume that its a Sublayout, but you can also check for xslt and create an XslFile() object
Sublayout sublayout = new Sublayout();
sublayout.DataSource = snippet.Paths.FullPath; // creates a reference to the snippet item, so you can pull data from that later on
sublayout.Path = rendering.RenderingItem.InnerItem["Path"];
sublayout.Cacheable = rendering.RenderingItem.Caching.Cacheable;
// Copy cache settings
if (rendering.RenderingItem.Caching.Cacheable)
{
sublayout.VaryByData = rendering.RenderingItem.Caching.VaryByData;
sublayout.VaryByDevice = rendering.RenderingItem.Caching.VaryByDevice;
sublayout.VaryByLogin = rendering.RenderingItem.Caching.VaryByLogin;
sublayout.VaryByParm = rendering.RenderingItem.Caching.VaryByParm;
sublayout.VaryByQueryString = rendering.RenderingItem.Caching.VaryByQueryString;
sublayout.VaryByUser = rendering.RenderingItem.Caching.VaryByUser;
}
// Now render the sublayout to the placeholder
carouselItemsPh.Controls.Add(sublayout);
}
}请注意,我从这里窃取了大部分代码:Temporarily change a Sitecore item's layout
所有的东西都出版了。
当我按下测试页标记时,会为每个子项("Carousel item“)生成页面标记,并且旋转木马工作,但看起来Datasource没有被正确分配--所有子项的数据源/上下文都是父项,尽管在创建子控件时显式地设置了Datasource。我该怎么解决这个问题?
是否有更好的方法来实现我正在努力实现的在塞特罗雷6.5?
谢谢
发布于 2013-07-24 14:26:41
子项的用户控件/子布局需要以编程方式读取数据源。对于这个工作,我总是有我自己的'base‘Sublayout类,它处理用户控件的数据源问题。在我的基类中,如果没有设置数据源,则默认使用Sitecore.Context.Item。守则如下:
public class SublayoutBase : UserControl
{
private Item _dataSource;
public Item DataSource
{
get
{
if (_dataSource == null)
{
if (Parent is Sublayout)
{
_dataSource =
Sitecore.Context.Database.GetItem(((Sublayout)Parent).DataSource);
}
if (_dataSource == null)
{
_dataSource = Sitecore.Context.Item;
}
}
return _dataSource;
}
}
protected override void OnLoad(EventArgs e)
{
foreach (Control c in Controls)
{
SetFieldRenderers(DataSource, c);
}
base.OnLoad(e);
}
private void SetFieldRenderers(Item item, Control control)
{
if (item != null)
{
var ctrl = control as Sitecore.Web.UI.WebControl;
if (ctrl != null && !string.IsNullOrEmpty(ctrl.DataSource))
{
//don't set the source item if the DataSource has already been set.
return;
}
if (control is FieldRenderer)
{
var fr = (FieldRenderer)control;
fr.Item = item;
}
else if (control is Image)
{
var img = (Image)control;
img.Item = item;
}
else if (control is Link)
{
var link = (Link)control;
link.Item = item;
}
else if (control is Text)
{
var text = (Text)control;
text.Item = item;
}
else
{
foreach (Control childControl in control.Controls)
{
SetFieldRenderers(item, childControl);
}
}
}
}
}发布于 2013-07-24 13:48:55
我倾向于为这样的事情创建一个Repeater。
你可以这样做:
<div class="jcarousel">
<asp:Repeater id="repeater" runat="server">
<HeaderTemplate>
<ul>
</HeaderTemplate>
<ItemTemplate>
<li>
..markup from item such as:
<sc:FieldRenderer FieldName="Title" runat="server" id="titlefield" Item="<%# Container.DataItem %>" />
</li>
</ItemTemplate>
<FooterTemplate>
</ul>
</FooterTemplate>
</asp:Repeater>
</div>然后,在CodeBehind中,您所需要做的就是:
protected void Page_Load(object sender, EventArgs e)
{
repeater.DataSource = Sitecore.Context.Item.GetChildren(); // Could also make a LINQ statement where you make sure Children are of specific template if required
repeater.DataBind();
}当然,这取决于您的子项目SubLayouts是否可以使用这样的东西
https://stackoverflow.com/questions/17835166
复制相似问题