Thursday, February 9, 2017

Surrounding EpiServer lines with a div in content area


Surrounding EpiServer lines with a div in content area

Some days ago I had a discussion with our frontenders  regarding the rows in ContentArea. They liked to have a div surrounding each line of the items so they can make the styles in a correct way. In this small post I will describe what have I done:
I will use Alloy Demo site to describe the issue and my solution

The problem:

In a ContentArea, if you add some items it will be a big div with multiple lines inside. 
As you can see in the picture item 1 is taking a line, 2 and 3 are in the second line and 4,5,6  are in the third line. And size of each block depends on their display options.





The request

Surrounding each line with a div with CssClass="row" and removing the one for content area.

The solution

Removing the css class from the ContentArea is too easy since it has been added to html.Propertyfor in the index page:


However to remove add the container around each row, you need to override ContentAreaRenderer. In alloy demo website, it has already been overridden to add suitable classes based on the tags and it is called   AlloyContentAreaRenderer. Just override RenderContentAreaItems method and add this code. Then you are good to go :)


       protected override void RenderContentAreaItems(HtmlHelper htmlHelper, IEnumerable contentAreaItems)
        {
            float totalSize = 0;
            if (contentAreaItems.Any())
                htmlHelper.ViewContext.Writer.Write(@"
"); foreach (ContentAreaItem contentAreaItem in contentAreaItems) { var tag = this.GetContentAreaItemTemplateTag(htmlHelper, contentAreaItem); totalSize += GetSize(tag); if (totalSize>1) { htmlHelper.ViewContext.Writer.Write(@"
"); totalSize = GetSize(tag); } this.RenderContentAreaItem(htmlHelper, contentAreaItem, this.GetContentAreaItemTemplateTag(htmlHelper, contentAreaItem), this.GetContentAreaItemHtmlTag(htmlHelper, contentAreaItem), this.GetContentAreaItemCssClass(htmlHelper, contentAreaItem)); } if (contentAreaItems.Any()) htmlHelper.ViewContext.Writer.Write(@"
"); } float GetSize(string tagName) { if (string.IsNullOrEmpty(tagName)) { return 1f; } switch (tagName.ToLower()) { case "span12": return 1f; case "span8": return 0.666666f; case "span6": return 0.5f; case "span4": return 0.333333f; default: return 1f; } }

The result







19 comments:

  1. You could also just create a display template. It's a lot less code and it allows you the flexibility to add markup around each item on a per-content-area basis. So, if you have several content areas on several page types, you could essentially have each one have it's own item wrapping markup instead of forcing every content area to have the same markup.

    ReplyDelete
    Replies
    1. Hi John,
      Thanks for the comment. I've looked into that, but it doesn't seems to be as easy and general as overriding the render method. Of course, it makes sense if you want to have different template for each content area but that was not my case :). I will also appreciate if you can provide a real life example or a link to somewhere that I can see a real scenario.

      Delete
  2. That's all very good for a simple square design but it wouldn't work with more complex designs that have to combine going full page width followed by constrained rows with margins. We just had RowBlock that has to be added for each row then the blocks added inside. This allows us to have non constrained blocks added directly to a page and constrained rows inserted, it also gives us the ability to set row properties such as gradients, tints and any iconography that flows between row areas

    ReplyDelete
    Replies
    1. To be honest, that is the way that I wanted to avoid. If you create a container block (like row block) you have to go inside that and then change your items which is not for the editor since he will loose the page overview, plus he cannot reorder real blocks and take one from one line and put it into the other.
      Other than this, I didn't get why you have problem with margins. so you have some margin around your objects, and on each of them you have spanX. What is wrong with checking the size?
      Let's say you have a span12 (fullWidth) then with what ever margin it will be a row itself. If you have a span8 and span4 then what? Do you expect them to be shown in 2 lines if you have margin?

      I appreciate if you can give me a scenario that you think that it won't work.

      Delete
  3. What about just relying on something that has been already built? :)

    http://blog.tech-fellow.net/2015/09/20/row-support-added-to-bootstrap-contentarea/

    ReplyDelete
  4. I wanted to thank you for this great read!! I definitely enjoying every little bit of it I have you bookmarked to check out new stuff you post.
    java代写

    ReplyDelete
  5. This is my first time i visit here and I found so many interesting stuff in your blog especially it's discussion, thank you.
    java代写

    ReplyDelete