A critical vulnerability was discovered in React Server Components (Next.js). Our systems remain protected but we advise to update packages to newest version. Learn More

Anders Hattestad
May 8, 2013
  2481
(0 votes)

Render ContentArea with temporarily content

One nice feature in EPiServer 7 is the ability to render content based on tags and type.  But sometimes you want to add temporary items to a collection and then render them. This can be a RSS feed, or if you want to add one link list with and existing ContentArea.

The problem is that temporary items will not be rendered thru the PropertyContentAreaControl. So if you add some temporarily items like some RSS articles it will not render.

You can add IContent to a ContentArea, but internally it is stored as content reference, and the object is not preserved. It basically add the content Reference ID, and then when you render it it gets the content again. That means you cant manipulate the IContent items before you render them. Personally I think this behaviour is a bit odd, and makes it a bit harder to do cool stuff Smilefjes

Create temporarily content

Before it was possible to create pages and add them to a page list. You had to add the ACL to the page so it was not filtered out.

Code Snippet
  1. var page = new TempPageType();
  2. page.Property.Add("PageTypeID", new PropertyNumber(pageID));
  3. page.Property.Add("PageLink", new PropertyPageReference(PageReference.EmptyReference));
  4.  
  5. page.Property.Add("PagePendingPublish", new PropertyBoolean(false));
  6. page.Property.Add("PageWorkStatus",
  7.                     new PropertyNumber(Convert.ToInt32(VersionStatus.Published)));
  8. page.ACL.Add(new AccessControlEntry("Everyone", AccessLevel.Read));

 

In EPiServer 7 you have to register this page type and also add the PageTypeID to the temporarily page

Code Snippet
  1. var repository = ServiceLocator.Current.GetInstance<IContentTypeRepository<PageType>>();
  2. var pageType = repository.Load(typeof(TempPageType));
  3. var pageID=-1;
  4. if (pageType!=null)
  5.     pageID=pageType.ID;
  6. page.Property.Add("PageTypeID", new PropertyNumber(pageID));

And then register the page type.

 

Code Snippet
  1. [ContentType(GUID = "454E47D6-BC76-4596-BC03-8BA519BB4650", GroupName = "Default",AvailableInEditMode=false)]
  2. public class TempPageType : SitePageData
  3. {
  4.     [Ignore]
  5.     public virtual object InnerObject { get; set; }
  6.  
  7.     public override EPiServer.Security.ISecurityDescriptor GetSecurityDescriptor()
  8.     {
  9.         if (PageReference.IsNullOrEmpty(PageLink))
  10.             return new OwnSecurityDescriptor();
  11.         return base.GetSecurityDescriptor();
  12.     }
  13.        
  14. }
  15.   public classOwnSecurityDescriptor:ISecurityDescriptor
  16. {
  17.     public AccessLevel GetAccessLevel(IPrincipal principal)
  18.     {
  19.         return AccessLevel.FullAccess;
  20.     }
  21.     public bool HasAccess(IPrincipal principal, AccessLevel access)
  22.     {
  23.         return true;
  24.     }
  25. }

 

 

To render

The solution is to make your own render of a List of IContent

Lucky for us it’s still easy to look at the current code using Reflector or some other app.

This code will take a list of IContent and render them accordingly to the tags. So you can use it like this, where Result is a List<IContent>

Code Snippet
  1.   publicbool AddResult2Container(Control container,  string tag, bool add_Ul_Li)
  2. {
  3.     var haveContent = false;
  4.     var result = new RenderContentArea() { Data = Result };
  5.     result.Tag = tag;
  6.     if (add_Ul_Li)
  7.     {
  8.         result.TagName = "ul";
  9.         result.TagChildName = "li";
  10.     }
  11.     container.Controls.Add(result);
  12.     haveContent = result.CreateContent();
  13.     return haveContent;
  14. }

The code that runs is this

Code Snippet
  1. public class RenderContentArea : PlaceHolder
  2. {
  3.     public List<IContent> Data { get; set; }
  4.     public string TagName { get; set; }
  5.     public string TagChildName { get; set; }
  6.  
  7.     public string ItemCssClass { get; set; }
  8.     public string ItemChildCssClass { get; set; }
  9.  
  10.     public string Tag { get; set; }
  11.  
  12.     private ContentControlResolver _contentControlResolver;
  13.     public ContentControlResolver ContentControlResolver
  14.     {
  15.         get
  16.         {
  17.             ContentControlResolver arg_1D_0;
  18.             if ((arg_1D_0 = this._contentControlResolver) == null)
  19.             {
  20.                 arg_1D_0 = (this._contentControlResolver = ServiceLocator.Current.GetInstance<ContentControlResolver>());
  21.             }
  22.             return arg_1D_0;
  23.         }
  24.         set
  25.         {
  26.             this._contentControlResolver = value;
  27.         }
  28.     }
  29.  
  30.     protected IList<Control> GetContentRenderers2()
  31.     {
  32.         if (Data == null || Data.Count<IContent>() == 0)
  33.         {
  34.             return new List<Control>();
  35.         }
  36.         string itemTagName = TagChildName;
  37.         string itemCssClass = ItemChildCssClass;
  38.  
  39.         return ResolveContentControls(this, this.Tag, itemCssClass, itemTagName);
  40.     }
  41.     public virtual Injected<TemplateControlLoader> TemplateControlLoader
  42.     {
  43.         get;
  44.         set;
  45.     }
  46.     private WebFormsContentValidator _contentValidator;
  47.     public virtual WebFormsContentValidator ContentValidator
  48.     {
  49.         get
  50.         {
  51.             WebFormsContentValidator arg_1D_0;
  52.             if ((arg_1D_0 = this._contentValidator) == null)
  53.             {
  54.                 arg_1D_0 = (this._contentValidator = ServiceLocator.Current.GetInstance<WebFormsContentValidator>());
  55.             }
  56.             return arg_1D_0;
  57.         }
  58.         set
  59.         {
  60.             this._contentValidator = value;
  61.         }
  62.     }
  63.     public virtual IList<Control> ResolveContentControls( Control parentControl, string tag, string itemCssClass, string itemTagName)
  64.     {
  65.  
  66.         IContentFilter filter = new FilterContentForVisitor(TemplateTypeCategories.WebFormsPartial, tag);
  67.         List<Control> list = new List<Control>();
  68.         IEnumerable<IContent> source = Data;
  69.         IEnumerable<IContent> enumerable =
  70.             from c in source
  71.             where  !filter.ShouldFilter(c)
  72.             select c;
  73.         foreach (IContent current in enumerable)
  74.         {
  75.             Control control = this.TemplateControlLoader.Service.LoadControl(HttpContext.Current.ContextBaseOrNull(), current, parentControl.TemplateControl, tag);
  76.             if (this.ContentValidator.ExistInControlHierarchy(parentControl, current, control))
  77.             {
  78.                 //if (enableEditFeatures)
  79.                 //{
  80.                 //    HtmlGenericControl item = this.BuildCircularReferenceControl(current, itemTagName, itemCssClass);
  81.                 //    list.Add(item);
  82.                 //}
  83.             }
  84.             else
  85.             {
  86.                 IVersionable versionable = current as IVersionable;
  87.                 if (versionable == null || versionable.Status == VersionStatus.Published)
  88.                 {
  89.                     ContentRenderer item2 = new ContentRenderer
  90.                     {
  91.                         CurrentControl = control,
  92.                         CurrentData = current,
  93.                         CurrentContent = current,
  94.                         Tag = tag,
  95.                         CustomTagName = itemTagName,
  96.                         CssClass = itemCssClass,
  97.                         TemplateControlLoader = this.TemplateControlLoader,
  98.                         RenderType =RenderType.Default
  99.                     };
  100.                     list.Add(item2);
  101.                 }
  102.             }
  103.         }
  104.         return list;
  105.     }
  106.       
  107.         
  108.     public  bool CreateContent()
  109.     {
  110.           
  111.         string containerTagName = (!string.IsNullOrEmpty(TagName)) ? TagName : "div";
  112.         System.Collections.Generic.IList<Control> contentRenderers = this.GetContentRenderers2();
  113.         Control control = CreateMainContainer(containerTagName);
  114.         foreach (Control current in contentRenderers)
  115.         {
  116.             control.Controls.Add(current);
  117.             ContentRenderer contentRenderer = current as ContentRenderer;
  118.             if (contentRenderer != null)
  119.             {
  120.                 contentRenderer.EnsureChildControlsCreated();
  121.             }
  122.         }
  123.         if (contentRenderers.Count > 0)
  124.             return true;
  125.         return false;
  126.          
  127.     }
  128.     protected HtmlGenericControl CreateMainContainer( string containerTagName)
  129.     {
  130.         HtmlGenericControl htmlGenericControl = new HtmlGenericControl(containerTagName);
  131.         this.Controls.Add(htmlGenericControl);
  132.            
  133.         //if (enableEditFeatures)
  134.         //{
  135.         //    base.ApplyEditAttributes();
  136.         //}
  137.         return htmlGenericControl;
  138.     }
  139.         
  140. }
May 08, 2013

Comments

Please login to comment.
Latest blogs
A day in the life of an Optimizely OMVP: Learning Optimizely Just Got Easier: Introducing the Optimizely Learning Centre

On the back of my last post about the Opti Graph Learning Centre, I am now happy to announce a revamped interactive learning platform that makes...

Graham Carr | Jan 31, 2026

Scheduled job for deleting content types and all related content

In my previous blog post which was about getting an overview of your sites content https://world.optimizely.com/blogs/Per-Nergard/Dates/2026/1/sche...

Per Nergård (MVP) | Jan 30, 2026

Working With Applications in Optimizely CMS 13

💡 Note:  The following content has been written based on Optimizely CMS 13 Preview 2 and may not accurately reflect the final release version. As...

Mark Stott | Jan 30, 2026

Experimentation at Speed Using Optimizely Opal and Web Experimentation

If you are working in experimentation, you will know that speed matters. The quicker you can go from idea to implementation, the faster you can...

Minesh Shah (Netcel) | Jan 30, 2026

How to run Optimizely CMS on VS Code Dev Containers

VS Code Dev Containers is an extension that allows you to use a Docker container as a full-featured development environment. Instead of installing...

Daniel Halse | Jan 30, 2026

A day in the life of an Optimizely OMVP: Introducing Optimizely Graph Learning Centre Beta: Master GraphQL for Content Delivery

GraphQL is transforming how developers query and deliver content from Optimizely CMS. But let's be honest—there's a learning curve. Between...

Graham Carr | Jan 30, 2026