Question

I have a repeater in one of the sublayouts in Sitecore 6.6. rev 120918. Inside this repeater, I have a placeholder. On ItemDataBound, I assign a key with a GUID to it, and using Nick Wesselman's GetAllowedRendering pipeline, I am able to render the insert options for this.

The repeater code is very simple:

<asp:Repeater runat="server" ID="rptrTimelineItemsEdit"  OnItemDataBound="rptrTimelineItemsEdit_OnItemDataBound">
  <ItemTemplate>
    <sc:Placeholder ID="scTimelineItemPlaceholder" Key="timelineitemcontent" runat="server" />
  </ItemTemplate>
</asp:Repeater>

The Item Data bound is also pretty simple:

protected void rptrTimelineItemsEdit_OnItemDataBound(object sender, RepeaterItemEventArgs e)
{
  if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
  {
    Item item = (Item)e.Item.DataItem;

    Placeholder scTimelineItemPlaceholder = (Placeholder)e.Item.FindControl("scTimelineItemPlaceholder");
                scTimelineItemPlaceholder.Key = "timelineitemcontent" + item.ID.ToString().ToLower(); 
  }
}

Everything works up to this point. After I choose the sublayout I want to insert in the placeholder, it throws me an in the JS error popup. After inspecting in the chrome inspector, I see the error is:

Could not find the rendering in the HTML loaded from server PlaceholderChromeType.js:601
Sitecore.PageModes.ChromeTypes.Placeholder.Sitecore.PageModes.ChromeTypes.ChromeType.extend._frameLoaded

So - it would seem like that in the page reload, the sublayout renderings are happening before the repeater bindings, so it can't find the placeholder key.

I did some google, and found that there is a way to change the layout engine sequence using the layoutpageevent setting:

However, this didn't solve my problem. I'm out of ideas. Help!

Was it helpful?

Solution

Hi there Ive found a solution to this issue, it had me stumped as well. It only occurs to placeholders that sit under a repeater. Overwrite PlaceholderChromeType.js in Website\sitecore\shell\Applications\Page Modes\ChromeTypes\ With the one ive dropboxed (also available on the credit link below) https://www.dropbox.com/s/7m99b8jgdz3cgl2/PlaceholderChromeType. Your keys then have to have dynamic in them for it to work. Example code:

protected void R1_ItemDataBound(Object Sender, RepeaterItemEventArgs e)
    {
        var p = e.Item.FindControl("andysplaceholder") as Placeholder;
        p.ID = "Andy" + (e.Item.ItemIndex + 1);
        p.Key = "dynamic" + p.ID;
    }

<asp:repeater id="MyRepeater" runat="server" OnItemDataBound="R1_ItemDataBound">
        <ItemTemplate>        
               <sc:placeholder runat="server" id="andysplaceholder" key="dynamicandysplaceholder" ></sc:placeholder>
        </ItemTemplate>
    </asp:repeater>

On top of this i do my repeater binding in the oninit method

 protected override void OnInit(EventArgs e)
    {
        base.OnInit(e);

and i set the web.config setting from preInit to load

<setting name="LayoutPageEvent" value="load" />

Although that might be overkill, I will revert today to page_load and preinit today and see if it still works.

Credit to Sitecore support and Mickey Rahman for this http://mickeyrahman.wordpress.com/2014/05/05/an-ode-to-sitecore-support/#respond

This should also work with the dynamic key apprach from Nick, you'll just have to make sure the keys generated by his code have dynamic in them

OTHER TIPS

You have not implemented it in the way it's explained by Nick.
What you need to do is create a WebControl class for your Dynamic Placeholder.
That will ensure that things are processed in the same order as it would have with a 'real' Placeholder.

So the first thing I would do is make sure you do it in the same way as it's been described by Nick.
Then verify that it works with just 1 dynamic placeholder on the page.

Secondly, you should take a look at this blog post: Dynamic Placeholders and IExpandable
It explains how to deal with adding multiple dynamic placeholders in repeaters (and other controls).
He also thought that it had something to do with the change in the LayoutPageEvent, but it did not turn out to be that.

EDIT:
I've reproduced the issue and I highly doubt that you're going to solve it with this approach.
The placeholders are not loaded yet when the Page Editor is requesting their renderings after trying to add controls to them.
Even when you create the Placeholders in the OnInit (which is the earliest), it doesn't work.

If I get more time I'll try to look into it further.

Ruud referenced my blog post Dynamic Placeholders and IExpandable in his answer, and I think that he's definitely on the right track. I know that you haven't used dynamic placeholders in the way that I describe, however you are still creating placeholders dynamically.

I personally have never had any success with the LayoutPageEvent; which is why I decided to post about the use of IExpandable as it isn't something that's been highlighted that much.

You ought to create your placeholders in the Expand method and also expand them after you add them to the page. I would personally advise against using a Repeater to do so - add them to the controls collection or maybe to a normal ASP.Net PlaceHolder control.

public class YourSublayout : UserControl, IExpandable
{
    public void Expand()
    {
        var myListOfItems = GetItems()
        foreach (var item in myListOfItems)
        {
            var placeholder = new Placeholder { Key = "key" + item.ID.ToString() };
            container.Controls.Add(placeholder); // add to a control container
            placeholder.Expand();
        }
    }
}

Hopefully that should get you a bit further (if you haven't solved it already). Just keep in mind the other things I mention on my post, namely that the Expand method can be called before the control gets added to the page, and so getting your DataSource may break if you rely on getting it from the parent control.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top