Try our conversational search powered by Generative AI!

Iterating through unique ContentArea items

Vote:
 

Hi,

I have been trying to find a way to iterate through a number of block's with various types. As a guide I followed the similar thread here that helped with iterating through blocks of the same type.

Ideally I would like to write a helper function that would return the rendered content of a ContentAreaItem. For now though here's the code I have at the moment but it crashes IIS when it run's. 

for (var blockCount = 0; blockCount < blockCountMax; blockCount++)
{
	var contentAreaItem = Model.Content.Items[blockCounter];
	var blockContent = contentAreaItem.GetContent();
	var namespaces = blockContent.GetOriginalType().ToString();
	var namespaceArray = namespaces.Split('.');
	var blockName = namespaceArray[namespaceArray.Length - 1];

	if (blockName == typeof(ArticlePromoBlock).Name)
	{
		var repository = EPiServer.ServiceLocation.ServiceLocator.Current.GetInstance();
		var blockPass = repository.Get(contentAreaItem.ContentLink);
		Html.RenderAction("Index", blockName, blockPass);
	} 
	else if (blockName == typeof(NewsPromoBlock).Name)
	{
		...
	}
}

A number of us at my work have tried to solve this problem at different times, so any help would be greatly appriciated!

Cheers Ben

#119659
Apr 01, 2015 8:32
Vote:
 

Hard to say where it might fail but I would do your code a bit differently and you eliminate all "index out of bounds" possibilites :)

var contentAreaItems = Model.Content.FilteredItems.Take(blockMaxCount);

foreach (var item in contentAreaItems)
{
	var block = item.GetContent();

	if (block is ArticlePromoBlock)
	{
		var articlePromoBlock = block as ArticlePromoBlock;
		// do stuff
	}
	else if (block is NewsPromoBlock)
	{
		// similar as above
	}
}

Make sure Models.Content isn't null.

#119672
Edited, Apr 01, 2015 13:39
Vote:
 

Thanks Mikael. I've altered it to your better structure but unfortunately it's still crashing IIS when it hits the Html.RenderAction. The IIS issue might be too hard to diagnose in a forum like this so I guess the crux of my question is how do people do this? Has someone got something like the following code to work before?

	var contentAreaItems = Model.Content.FilteredItems.Take(5);

	foreach (var item in contentAreaItems)
	{
		var block = item.GetContent();
		if (block is ArticlePromoBlock)
		{
			var articlePromoBlock = block as ArticlePromoBlock;
			Html.RenderAction("Index", "ArticlePromoBlock", articlePromoBlock);
		}
	}



#119710
Edited, Apr 02, 2015 1:35
Vote:
 

Can you fill out the context a little bit more, what are you trying to achieve and why handle the contentarea items "manually" instead of using PropertyFor?

#119711
Apr 02, 2015 7:38
Vote:
 

So we are creating layout blocks that from a dropdown can choose various configurations.

e.g. 2/3/4 column & 2 column split layout (shows 1 large block on 1 side and 4 small blocks on the other)

So with the 2 column split layout block, our issue is we want to render the first block differently than the other 4 that will make up the second column.

Our aim is to just have the one layout block for all these layouts to make it easier for the user. I'm also trying to avoid having more than one ContentArea due to it only applying to a few of the layouts.

#119715
Apr 02, 2015 8:08
Vote:
 

Could you please post what error message you get? I've done something similiar...I don't have access to the code right now though but will post when Im back at the office

#119839
Apr 04, 2015 12:26
Vote:
 

As content area items are not handled by ordinary controllers (like it's done for pages), but they are child action controllers - you should not call RenderAction directly. This will try to call controller that is handling blocks as Mvc controller.

Haven't tried myself, just a wild guess (so it may could fail) - try to go through content data extensions to render that content:

EPiServer.Web.Mvc.Html.IContentDataExtensions.RenderContentData(htmlHelper, articlePromoBlock, true);
#119864
Apr 04, 2015 20:58
Vote:
 

Thanks everyone! The missing peice of the puzzle was the line Valdis posted. Here's the final working version incase someone else is interested.

@{
	var contentAreaItems = Model.Content.FilteredItems.Take(5);

	foreach (var item in contentAreaItems)
	{
		var block = item.GetContent();
		Html.RenderContentData(block, true);
	}
}

Using this way I could just pass the content as is without the unwieldy 'if' chain, used to set the specific model.

EDIT: Sanitised RenderContentData line

#119889
Edited, Apr 07, 2015 1:17
This topic was created over six months ago and has been resolved. If you have a similar question, please create a new topic and refer to this one.
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.