How to check for block types inside a content area

Vote:
 

I need to check if the block types in a content area are Block A or Block B. Below is my current code:

            var contentLoader = ServiceLocator.Current.GetInstance();
            if (_view.CurrentHomePage != null && _view.CurrentHomePage.TopContentArea != null && _view.CurrentHomePage.TopContentArea.Items.Any())            
            {
                foreach (var contentItem in _view.CurrentHomePage.TopContentArea.Items)
                {
                    var itemType = contentItem.GetType();                   
                    if (itemType == typeof(IFrameBlock))
                    {
                        var b = contentLoader.Get(contentItem.ContentLink);
                        // do with the block                        
                    }                       
                }
            }

#118895
Mar 17, 2015 8:16
Vote:
 

the Item in a ContentArea is simply a ContentAreaItem, a piece of information that represents ContentReference, DisplayOption, Personalization (access rights) etc.

It knows nothing of the actual content. This was rebuilt in 7.5 compared to 7 where the ContentArea also had Contents and FilteredContents, but these are now obsolete.

To get the actual content you need to do the following

var iframeBlock = contentLoader.Get<IContentData>(contentItem.ContentLink) as IFrameBlock;

if(iframeBlock != null)
{
   // do with the block
}

The reason we say .Get<IContentData> is that EPiServer will throw an Exception if your block does not inherit IFrameBlock.

But if we load as IContentData and later casts to your specific Content Type, we can simpler ensure that the block is your IFrameBlock.

#118896
Mar 17, 2015 8:44
Vote:
 

Thanks. Is there a way for a content item to set its RenderSettings?

My real problem is that the Content Area wraps the blocks with divs:

<div>

     <div>block</div>

     <div>block</div>

</div>

Since I can't remove them, I have found a way to style the outer div. I need to apply different style rules to each divs wrapped in each block depending on the type of block. So I thought I need to iterate blocks inside the Content Area and apply RenderSettings to each of the blocks.

#118898
Mar 17, 2015 9:12
Vote:
 

I think it's better that you look on various ways to render your ContentAreas

How to do this depends on if you using WebForms or MVC

#118899
Mar 17, 2015 9:14
Vote:
 

I would like to know why you need to eliminate elements around block in the first place? If you take a look at content area renderer there is a method that takes care of pushing content area content out to response and that method expects htmlTag as one of method arguments. Using this value TagBuilder is created.

You can inherit from default ContentAreaRenderer, swap in initializable module and get more control over rendering pipeline.

You can even override "string GetContentAreaItemHtmlTag(HtmlHelper, ContentAreaItem)" and return empty string as tag element. But this will not work as TagBuilder will throw exception if you try to build builder for empty tag name.

One of workaround is to inherit from content area render and take care of content area item rendering yourself.

[ModuleDependency(typeof(ServiceContainerInitialization))]
[InitializableModule]
public class SwapRendererInitModule : IConfigurableModule
{
    public void ConfigureContainer(ServiceConfigurationContext context)
    {
        context.Container.Configure(container => container.For<ContentAreaRenderer>().Use<MyOwnContentAreaRenderer>());
    }

    public void Initialize(InitializationEngine context)
    {
    }

    public void Uninitialize(InitializationEngine context)
    {
    }

    public void Preload(string[] parameters)
    {
    }
}

And

public class MyOwnContentAreaRenderer : ContentAreaRenderer
{
    public MyOwnContentAreaRenderer(
        IContentRenderer contentRenderer,
        TemplateResolver templateResolver,
        ContentFragmentAttributeAssembler attributeAssembler) : base(contentRenderer, templateResolver, attributeAssembler)
    {
    }

    public MyOwnContentAreaRenderer(
        IContentRenderer contentRenderer,
        TemplateResolver templateResolver,
        ContentFragmentAttributeAssembler attributeAssembler,
        IContentRepository contentRepository) : base(contentRenderer, templateResolver, attributeAssembler, contentRepository)
    {
    }

    protected override void RenderContentAreaItem(
        HtmlHelper htmlHelper,
        ContentAreaItem contentAreaItem,
        string templateTag,
        string htmlTag,
        string cssClass)
    {
        // do stuff here !
    }
}
#118901
Mar 17, 2015 9:49
Vote:
 

I do not intend to remove the wrapping divs. I'm using Web Forms not MVC.

#118909
Mar 17, 2015 10:35
Vote:
 

Oh, I see then I misunderstood you.

To set Css class conditionally I would go different way. Instead of checking this in content area render I would set it inside my block type.

If you take a look at Alloytech sample site (7.5 Mvc, but you will get idea) - there is a type called AlloyContentAreaRenderer. What it does is it overrides GetContentAreaItemCssClass method and checks for ICustomCssInContentArea interface. If block implements one - custom Css class is added to wrapping element in content area.

#118920
Mar 17, 2015 13:21
Vote:
 

ContentAreaRenderer won't work in webforms. See the below thread where Linus Ekström suggested a solution and it seems to be working fine for me. I have only used this to add additional attributes to outer div but he has suggested some other methods to modify the inner divs as well.

http://world.episerver.com/Modules/Forum/Pages/Thread.aspx?id=120174&epslanguage=en

#120801
Apr 24, 2015 13:38
This thread is locked and should be used for reference only. Please use the Episerver CMS 7 and earlier versions forum to open new discussions.
* 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.