首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在旋转木马控件中使用自己的布局呈现子项。

在旋转木马控件中使用自己的布局呈现子项。
EN

Stack Overflow用户
提问于 2013-07-24 13:16:34
回答 2查看 1.6K关注 0票数 1

以下是我要做的事:

我有一个内容项目“旋转木马主持人”。本质上,这将在旋转木马中呈现它的子项。我希望有足够的灵活性来拥有任意数量的子项目。我还希望灵活性能够指定每个子项目的表示方式--它们可能是相同的,也可能是不同的。我用的是Sitecore 6.5。

旋转木马是旋转木马。我需要生成这样的标记(从项目"Carousel演示者“):

代码语言:javascript
复制
<div class="jcarousel">
    <ul>
        <li> ... MARKUP FROM ITEM 1 ... </li>
        <li> ... MARKUP FROM ITEM 2 ... </li>
        ... and so on
    </ul>
</div>

以下是我尝试过的:

  • 创建子布局"carousel presenter.ascx",标记:

代码背后:

代码语言:javascript
复制
  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演示器“下面,即"Carousel item”,并为每个项分配一个子布局控件(通过配置/布局中的标准值)。

所有的东西都出版了。

当我按下测试页标记时,会为每个子项("Carousel item“)生成页面标记,并且旋转木马工作,但看起来Datasource没有被正确分配--所有子项的数据源/上下文都是父项,尽管在创建子控件时显式地设置了Datasource。我该怎么解决这个问题?

是否有更好的方法来实现我正在努力实现的在塞特罗雷6.5?

谢谢

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-07-24 14:26:41

子项的用户控件/子布局需要以编程方式读取数据源。对于这个工作,我总是有我自己的'base‘Sublayout类,它处理用户控件的数据源问题。在我的基类中,如果没有设置数据源,则默认使用Sitecore.Context.Item。守则如下:

代码语言:javascript
复制
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);
                }
            }
        }
    }
}
票数 2
EN

Stack Overflow用户

发布于 2013-07-24 13:48:55

我倾向于为这样的事情创建一个Repeater

你可以这样做:

代码语言:javascript
复制
<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中,您所需要做的就是:

代码语言:javascript
复制
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是否可以使用这样的东西

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17835166

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档