Templates for EPiServer 7 CMS

Views: 19889
Number of votes: 9
Average rating:

This article provides an overview of the new templates package available for EPiServer 7 CMS. It is part of the Web Solution Toolkit and is intended for developers interested in a high-level description of some of the concepts used.

Tech summary

  • Built on EPiServer 7 CMS
  • Templates built on ASP.NET 4.0 using Web Forms
  • Based on the responsive Bootstrap by Twitter HTML framework
  • Uses YUI for JavaScript and CSS bundling and minification
  • Uses config transforms for configuration management

An introduction to Bootstrap

The Alloy site markup is based on the responsive HTML framework Bootstrap.

The basic idea is to make it easier to go from this...

Alloy website with full functionality

...to this, depending on the size of the browser:

Alloy website with responsive design

Basic building blocks in Bootstrap

Bootstrap is based on rows, each consisting of one or more content elements that span a certain relative width.

The HTML looks something like this:

HTML for blocks

The first row would normally render something like this...

First row

...while rendering something like this when the browser window becomes small enough (think handheld devices):

Rendering for mobile devices

Block rendering

Because of Bootstrap we want our content areas to be rendered as one or more rows which in turn contain blocks as content elements. To make things even more interesting, we want to "fill" each row with blocks to ensure a nice adaptive layout.

Basic layout concept

When a single block is added to a content area we want it to be rendered as a single row with a single full-width content element:

Full-width content element

When we add a second block, we want it to fill the row together with the first block:

Second block

We want the same principle if we add a third block:

Third block

However, if we add a fourth block it will no longer fit in the same row. Therefore we want a new row containing the fourth block as a full width element (as there are no more blocks to share the row with):

Fourth block

Layout concept involving minimum and maximum block widths

The basic layout concept described earlier works because most of Alloy's block controls support dynamic widths ranging from 1/3 to full width.

However, it's not always practical to have a block control which can vary so freely in size.

To manage this, we introduced properties to define minimum and maximum widths for Alloy block controls.

This means we could potentially add seven different blocks which would be rendered like this:

Seven different blocks

Note that the last block is full width even though it's minimum size is 4 (one third). That's because it won't fit in the previous row, and since there are no more blocks to render the last block can stretch out across the entire row.

The simplified Tetris theory

Whenever a content area is rendered, a block control is resolved for each block. We take all these block controls and play a game of simplified Tetris to arrange the blocks in neatly filled rows, according to the minimum and maximum widths of each block control.

The simplified Tetris theory

Custom content area rendering

To support these design requirements for the Alloy website we use a custom control called SitePropertyContentAreaControl to render content areas.

This control inherits the native PropertyContentAreaControl, with some added Tetris-like aspects to support the type of layouts described earlier.

To make EPiServer use our own control to render all content area (i.e. all PropertyContentArea properties) we have added an initializable module like this:

Custom content area rendering

This means we can render our content areas using the standard Property control while still getting our customized rendering of content areas:

Standard property control

Bundling and minifying JavaScript and CSS files

JavaScript and CSS files are concatenated and minified every time the site is built.

This is done by a post-build event which triggers the YUI compressor. For details, check out the Scripts.xml and Stylesheets.xml files in the [MSBuild] folder.

Stylesheets are minified and/or concatenated into a non-minified file called combined.css and a minified equivalent called combined.min.css:

Combined.css

The same principle applies to JavaScript files:

JavaScript files

These files are linked in the Root.Master master page using simple web controls:

Root.Master

When the site is built in debug mode...

Debug mode

...the non-minified versions will be linked:

minified versions

Otherwise the minified versions will be linked:

minified versions linked

Note: the combined JavaScript and CSS files should be included in the project, but not under source control as they are overwritten on each build. However, we want them included in the project file so that they're automatically included when publishing the website.

Configuration management

To deal with different configuration setups we use chained config transforms:

Chained config transforms

This means we have a set of default configuration files...

Default configuration files

...which contain generic configuration settings valid for any EPiServer 7 website:

generic configuration settings

We then apply a set of common config transforms for our particular website...

common config transforms

...which contain modifications to the generic configuration settings...

modifications to the generic configuration settings

...which results in a configuration file where some of the generic configuration elements have been updated:

configuration file

Lastly, we apply a set of build-specific config transforms. The build-specific transforms are determined by the name of the build configuration. For example, if we select "Debug" as our build configuration...

build-specific config transforms

...the build-specific transforms will be retrieved from a folder called /[Configuration]/Debug:

Debug

These transforms are applied after the common transforms...

transforms

...which results in a build-specific configuration, such as local development or production release...

built-specific configuration

...which is then copied to the site root:

Site root

Note: do not edit the configuration files in the site root as they will be overwritten on every build. Instead make your configuration changes in the common or build-specific config transforms. This also means that the root configuration files should not be included in source control.

The config transforms are triggered on each build through a post-build event:

post-build event

Soon-to-be FAQ

1. My web.config changes keep disappearing. What gives?

Only edit configuration files under the [Configuration] folder, the root configuration files are overwritten on every build because of the config transforms.

2. Why is it built on Web Forms instead of MVC?

Although EPiServer 7 fully supports both Web Forms and MVC, Web Forms is still the more widely used. For that reason we decided to start with a Web Forms-based version.

3. Why isn't ASP.NET bundling of JavaScript and CSS files used instead of YUI?

Alloy is built on ASP.NET 4.0, bundling came with ASP.NET 4.5.

4. Why aren't the minified JavaScript and CSS files deployed when publishing the site?

That's because they're not included in the project file (that's a bug, sorry). They should be included in the project but not included in source control as they are overwritten with each build.

5. Why isn't a CSS framework like LESS or SASS used?

To minimize package dependencies and avoid confusing developers not familiar with them. Both work just fine, though!

Known bugs, limitations and annoyances in Alloy

The editmode.css file in /Static/css is obsolete, it can safely be removed if it's also removed from the Stylesheets.xml MSBuild file (otherwise CSS concatenation will fail). You have to rebuild the website after making changes to JavaScript and CSS files since only the concatenated files are linked. The ClonedContentProvider's cache does not depend on the original cloned pages.

Feedback, suggestions or questions?

Tweet me at @tednyberg, e-mail me at ted@tedgustaf.com, or just shout really, really loud.

Comments

Excellent!!!

Nice! I like a lot of it but Bootstrap by Twitter is a really crappy framework.

Glad you like it! :) Johan, any other favorites in terms of responsive HTML frameworks?

I've been using Foundation with SASS for a while, but it's pretty similar to Bootstrap (except for the CSS framework used).

Thanks Ted. I do like both bootstrap and Zurb Foundation.The only limitation with zurb is it stop supporting IE. Which IE9 seems to fair well with foundation, IE7/IE8 doesn't work so pretty. I actually like foundation over bootstrap but when building apps for the client that they only use IE7/8, makes it hard and thats why i went to Bootstrap.

I appreciate your time explaining the "tetris" effect and hope to see more of these post from you.

Not to open a can here, but Johan, whats not to like about Bootstrap?

It's bloated and contains or encourages bad practises.
Here's a blog post that illustrates some of the biggest problems:
http://theled.co.uk/blog/archive/2012/06/22/twitter-bootstrap---its-not-all-roses/

For a demo template package I would've wanted something that kept it's classes out of the markup as much as possible, was 100% accessible and semantic and secondary kept the CSS code to a minimum to make it easier to borrow code from it.
Anyway I guess most partners have their own framework that matches those requirements much better. Fo' shizzle we do :)

Valid points, I appreciate the feedback! Although, it should be noted that I didn't do the HTML/CSS of the Alloy templates, the markup was done internally at EPiServer.

In any case, I think it's more important to look at the implementation of the HTML framework in terms of blocks, rendering etc, than it is to look at the specific framework chosen for the demo templates.

Whether a site uses Bootstrap, Foundation or a vendor-specific framework (I think those will diminish more and more though) the basic principles remain the same.

I think the biggest take-away from developing responsive websites regardless of CMS is to select an HTML framework fitting for the requirements at hand. And, to some extent, fitting for the developers involved.

In the case of Alloy, the rendering implementation could quite easily be modified to support Foundation or any other HTML framework adhering to the same basic principles of rows and columns for layout.

Nice work

Awesome

Great, now I'm waiting for the MVC version!

By the way, is it something wrong with the package that comes with EPiServer Deployment Center where I manually need to add <location> elements for the VPPs in web.config?

I am just starting a new project how long will the MVC version be?

Great work! But i am having some problem with the project ;) Would it be possible to make the templates less dependet on the assambly name and namespace? For instance i do not like when you use the EPiServer.Your.Namespace. This is because vs will think of all you code as every other episerver code....having some trouble explaining this at courses :) Therefore I would like to change the assembly name and namespace in the project. But when i did that the site cannot be started.. changing the references in web.config to the new will not help so my conclusion is that you have some custom properties ie blocks, that have their assambly name in the DB? could this be change to a property that you reference in web.config instead?

/Eric

Good article!

Hi Ted! Great article.

I am using this class to render our own content area. I have one problem calling the GetContentRenderers(bool) function. When adding true to the function I get my list of controls, but when adding false for default view I get nothing. I am having trouble debugging why. Tried to compare to Alloy project with no success.

Question is if you know what to look for?

Thanks!


EDITED: You can delete this post. Problem was in my own code structure.

Hi everybody ,
did any one of u face the below issue with alloy mvc site ?
if u restrict a block on a page then the page it self is not visible. for example i restricted "news list" block on alloy-track page by deleting everyone group from it. but note that "Alloy-track page is having access to everybody. so expected functionality is user should see "Alloy-track" page but news list block should not visible. (this is default behaviour in Alloy - webforms ).
But actual behaviour is it is redirecting to login page !!!
note : I am facing same problem in my custom Episerver mvc site. can any body help me how to resolve this issue. thanks in advance.