渲染以转盘控制自己的布局儿童项目(Render child items with their own

2019-10-18 10:31发布

这里就是我想要做:

我有一个内容项“旋转木马演示”。 本质上,这将在传送带内提交其子项。 我想要的灵活性,有任意数量的子项。 我也希望能够灵活地可以指定每个子项的呈现 - 它们可以相同或不同。 我使用Sitecore的6.5。

转盘是的jCarousel。 我需要生成的标记一般是这样的(由项目“旋转木马主讲”):

<div class="jcarousel">
    <ul>
        <li> ... MARKUP FROM ITEM 1 ... </li>
        <li> ... MARKUP FROM ITEM 2 ... </li>
        ... and so on
    </ul>
</div>

这是我曾尝试:

  • 创建sublayout “旋转木马presenter.ascx”,标记:

    代码隐藏:

      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);
            }
        }
    

    请注意,我偷了大部分从这里这段代码: 临时更改Sitecore的项目的布局

    • 在内容树中创建子项,内容项目“转盘演示”下方即“旋转木马文件”,与(在配置/布局通过标准值)分配给每个一个sublayout控制。

    一切都公开。

    当我打的每个子项(“旋转木马项目”),以及转盘作品的产生我的测试页面的标记,但它看起来像数据源没有被正确地分配 - 所有子项的数据源/上下文是父项目,尽管明确地设置数据源,当我创建的子控件。 我该如何解决?

    是否有什么我想在Sitecore的6.5,实现了更好的方法?

    谢谢

    Answer 1:

    用户控制/为您的孩子的项目sublayouts需要以编程方式读取数据源。 对于这份工作,我总是有我自己的“基地” 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);
                    }
                }
            }
        }
    }
    


    Answer 2:

    我倾向于创造一个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>
    

    然后,在代码隐藏所有你需要做的是一样的东西:

    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是否可以使用这样的事情



    文章来源: Render child items with their own layout in a carousel control