SaaS CMS has officially launched! Learn more now.

best way to create a multi-page header?


I have played with alloy, and gone through the "geting started" docs, but there are a lot of gaps.

The first thing one might want to do with an empty site is to create a block (via the conent editing tools) which will be the header for every page. I would expect this to be a simple HTML block with some links and a logo, all editable.  Looking at alloy, the header is hard coded into the template.  It is not a block or editable.

So I get that episerver doesnt want the content editors to be able to modify the "templates", only very limited areas on pages. this is fine if the company has a lot of c# developers.

What is the best way to create an editable header and footer block, which appears on many different page templates, but is still editable (i.e. to add new page links)?

I think that episerver, unlike say dreamweaver, doesnt allow nested templates. Ie. you cant create a template with an editable header and footer, then base inner templates off this, where inner templates can put conent in areas where the parent temlates designate.  I understand this kind of thing is done with blocks.  but I dont see any shared blocks. Why is header not just a block, which is hard coded to be included on all page templates?

I see there is something called Header.cshtml in shared. It gets the page links from "item". Where does item come from?  It is not in the pages model, nor in the "SitePageData" which it inherits from?

where does this header shared view get inculded in the templates which use it? Its not in the pages view. I cant see a controler per template, or a link between the page and its controller. There seems to be no controller for "StandardPage", althoug it does have a view and a model. I understood that view, model and conroller were linked by naming convention, but this does not seem to be the case here.

                                <ul class="nav">
                                    <li class="@(Model.CurrentPage.ContentLink.CompareToIgnoreWorkID(SiteDefinition.Current.StartPage) ? "active" : null)">@Html.ContentLink(SiteDefinition.Current.StartPage)</li>
                                                    @<li class="@(item.Selected ? "active" : null)">
                                                        @Html.PageLink(item.Page, null, new { @class = string.Join(" ", item.Page.GetThemeCssClassNames())})

Does anyone have an example of a better (more logical, easy to edit etc) way to do headers and footers? Alloy seems overly complex with little flexibility.  Anyone have a good skeleton site?

Edited, Nov 20, 2019 17:48

Standard page elements like headers and footers are not usually handled as blocks they are handled as part of the core MVC templates.

E.g a page would be made up of elements


header (Part of the core page template)


body (Containing blocks)


footer (Part of the core page template)

So for example in the Alloy demo scenario the header and footer are just rendered in the core page template. The data/viewmodel would be built up by core data in the CMS depending on what you want to achieve. For example a header with a top navigation would usually be driven by sub pages of the home page that are set as show in navigation and rendered in the view. Usually a common approach for header configuration is adding properties to the home page for the header and footer or separating this configuration out.

You can put block in the header and footer as well but these are more commonly used more for CTAs, Logos and small content pieces rather than core configuration. This is because core site configuration should be stored globally and then rendered on page templates. This also allows this data to be cached until change using episerver syncronizing caching system so you can build a view model for core site data that will drive core page information such as the header and footer used across all pages.

Nov 20, 2019 18:11
johnv - Nov 20, 2019 23:33
Thanks Scott. What I dont get is that content editors frequently need to add pages to the site, along with updating the navigation in the header. This is pretty standard requirement. What I am looking for is a way to do this. There should be somewhere on the site where the content editor can update the navigation. E.g. add an affiliate section. The only way I can see to do this is to create a block which is shared by all pages. As each page needs to share the nav, and pages dont inherit from each other, I guess you cant do this in the page itself.
Scott Reed - Nov 21, 2019 8:03
Yes, I'll expand on what I said above so it's more clear.

This is usually down to either 2 decisions in most CMS platforms. Convention or Configuration.

Option 1: Convention

If you have a structure of a home page with sub pages such as

-- about
-- events

In a convention way the way for example a header would be built would be to load the home page which you can get on the ContentReference.StartPage and then load the child pages. There's a built in property called show in navigation so of all of these child pages you'd check which have this property checked and then render the navigation elements for those pages. This relies on the convention of using child pages of the home for the header. You can build whatever convention you like, for example with a mega menu going down deeper levels you can repeat that to the Nth level.

This is what you see in the Alloy Demo

Option 2: Configuration

As mentioned above a common action in most CMS sites is to need a central place to store site wide configuration options. These can often include things like

- Header Configuration
- Footer Configuration
- Google Analytics Configuration
- SEO Configuration

And much more.

A common practice is to add this to the start page model of your website, this means they are grouped at the root of a site and also means if you have multiple sites configured in Episerver this will work for all.

So what I would usually expect is a new Group on the Home page called "Header" and a new property in this group which would be called something like Main Navigation. This property would be a ContentArea and restricted to your Base Base type so that you can only include page in to this content area. You would then write whatever site settings loader code to load this property on the home pages and build it's navigation elements. As mentioned above it's also common to cache this so that all the information on your site settings are cached until change.

This means that from a CMS editors perspective they need only open the home page node in the CMS, and drag whatever pages in the website in to that content area. Again you can customise the configuration of this as much as you like (restrictions, multiple tiers) depending on your UX and Design.

I Hope this is more clear now
johnv - Nov 21, 2019 11:44
Thanks Scott, much appreciated. As its done this way, I assume there is no such thing as a "shared" block where the editable contents are shared across pages. For an editor, to have a header block which was editable, but whose changes were instantly reflected on all pages would be pretty nice. But if its done with settings or dynamically, ill try to figure out how do to this (could not figure out how the allow gets the list of pages for the nav).
You mention dragging pages into a block. I haven't come across this concept in the docs yet (only seen editing text and dragging images). Does this have a name, or do you know of any example code which I can try?
Scott Reed - Nov 22, 2019 23:54
1. Things like header and footer are core to all pages. That's why we usually store them on the home page or a configuration node and simply render them in the root view as it's inherited by all pages. Anything that's a standard page is usually designed to be configured and rendered by convention

2. You're describing the exact way blocks work. Blocks are usually created in the Blocks folder in the "For all sites" area. These are shared and when added to a page any changes on the block are reflected on all pages referencing them. This is evident in the Alloy demo. You can create blocks for a specific page when you created them from clicking the link in the ContentArea, this a coupled to the page and when the page goes the block goes. Ergo there's 2 choices, create a block at a site wide level for reusable blocks or per page for blocks tied to the page content.

3. I mentioned dragging a page in to a ContentArea not a block. A ContentArea when defined on a model is just a placeholder for any piece of content that inherits IContent. Often ContentAreas are used for blocks but they can be used for any IContent content such as pages, blocks, media. You can restrict the types that can go in an ContentArea with an attribute.

And Alloy is pretty much the simplest example of a content driven Episerver website you'll find as a reference.

Nov 20, 2019 18:13
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.