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

Per Magne Skuseth
Aug 27, 2013
  11308
(0 votes)

Letting your blocks know where they are

I’ve been fiddling around with how I could get information from the current content area when in the context of a block controller.
First of all, I wanted to know which tag was currently set in the content area. That was reachable through this:

   1: var tag = ControllerContext.ParentActionViewContext.ViewData["Tag"] as string;

 

Then, I tried getting the actual content area, which I could retrieve by doing this:

   1: var currentContentArea = ControllerContext.ParentActionViewContext.ViewData.Model as ContentArea;


By getting the current content area, I could get information on how many items it contained, and what those items were. I could also get the current index of the item. Knowing this, I could control which view to render, based on the current index. In the example below I’ve done just that, with the case being that the blocks rendered first, second and third in the list should have special views.


The block type that is being used:

   1: [ContentType(GUID = "81D97CE8-AF88-41FB-B4FF-BFF5D53DDDDF",
   2:     DisplayName = "Football player block")]
   3: public class PlayerBlock : BlockData
   4: {
   5:       public virtual string Heading { get; set; }
   6:       [UIHint(UIHint.Image)]
   7:       public virtual Url Image { get; set; }
   8:       public virtual XhtmlString MainBody { get; set; }
   9:  
  10:       // This property will indicate the block’s position and will be set in the controller,
  11:       // which is why I've used the [Ignore] attribute. By doing this, EPiServer won't register it
  12:       // as an editable property.
  13:       [Ignore]
  14:       public int Index { get; set; }  
  15: }



In the PlayerBlock controller, I return a view based on the current block’s index in the content area:

   1: public override ActionResult Index(PlayerBlock currentBlock)
   2: {
   3:     string blockView;
   4:     // get the current content area
   5:     var currentContentArea = 
   6:         ControllerContext.ParentActionViewContext.ViewData.Model as ContentArea;
   7:  
   8:     int index = 1;
   9:     // we'll need to check if it is actually rendered in a ContentArea.
  10:     if (currentContentArea != null)
  11:     {
  12:         // the index of the current selected block
  13:         index = currentContentArea.Contents.IndexOf(currentBlock as IContent) + 1;        
  14:     }
  15:     switch (index)
  16:     {
  17:         case 1:
  18:             blockView = "first";
  19:             break;
  20:         case 2:
  21:         case 3:
  22:             blockView = "twoandthree";
  23:             break;
  24:         default:
  25:             blockView = "index";
  26:             break;
  27:     }
  28:     currentBlock.Index = index;
  29:  
  30:     // Example:if index is 2, return view "/Views/Blocks/PlayerBlock/TwoAndThree.cshtml".
  31:     // If in preview mode, 
  32:     // the 'first' view will be return as we set the index initial value to '1'.
  33:     return PartialView(string.Format("~/Views/Blocks/{0}/{1}.cshtml",
  34:         currentBlock.GetOriginalType().Name,
  35:         blockView),
  36:         currentBlock);
  37: }


The code along with the inline comments should be quite self explanatory, but to sum up: The first item in the content area will now be rendered using the First.cshtml view, while item two and three will be rendered using the TwoAndThree.cshtml view (I guess I could have found a better name for that one), while the rest of the views will be rendered with the Index.cshtml view.

top 7 footballers

 

And finally: Keep in mind that while I’ve used the currentBlock object in all three views, I could just as well create view models, and populated them only with the data needed in the view. Performance wise, that would probably be a good idea.

Aug 27, 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