Tuesday 30 June 2009

EPiServer Composer - How to load content functions defined on a different page

This in another example of interesting EPiServer Composer (version 3.2.5) use case - on homepage there is a content area called "Bottom Area" which contains number of content functions. I want to display this whole content area on other arbitrary pages.

Here is a piece of code which can do this for us:

   1:  var structure = PageDataManager.LoadPageStruct(homepage.PageLink);
   2:  var contentArea = structure.GetContentAreaById(AreaName.BOTTOM_AREA_ID);
   3:  for (var i = 0; i < contentArea.ContentFunctions.Count; i++)
   4:  {
   5:      var data = contentArea.ContentFunctions[i];
   6:      var contentFunction = PageDataManager.InitContentFunctionControl(ExtensionGeneric.ViewMode.ExtensionNormalMode,
   7:                                                                       Page, data);
   8:      plhContainer.Controls.Add(contentFunction);
   9:      
  10:      var element = contentFunction as IListItemPosition;
  11:      if (element == null) continue;
  12:  
  13:      element.IsLastElement = IsLastElement(i, contentArea);
  14:      element.IsFirstElement = IsFirstElement(i);
  15:      
  16:  }

Explanation:
  1. In first two lines I'm using PageDataManager to get instance of ExtensionPageData class for homepage and then I can easily access required content area. Please note that to load data from a different page you just need to provide reference to a different page.
  2. Heaving an instance of ContentAreaData class (contentArea variable) I have access to the list of all content functions (contentArea.ContentFunctions)
  3. In lines 5-8 I'm instantiating each content function and then it can be added to the PlaceHolder which is a container for all content functions.
  4. In lines 10-14 I'm detecting first and last element as those elements may require some special CSS classes. You can read more about IListItemPosition interface and how to figure out which content function is first/last in my previous post.
To get everything working you still need those two simple methods:

   1:  private static bool IsFirstElement(int i)
   2:  {
   3:      return i == 0;
   4:  }
   5:  
   6:  private static bool IsLastElement(int i, ContentAreaData contentArea)
   7:  {
   8:      return i == contentArea.ContentFunctions.Count - 1;
   9:  }

I think it's fairly simple but if you have any questions don't hesitate to leave a comment.