Don't miss out Virtual Happy Hour this Friday (April 26).

Try our conversational search powered by Generative AI!

Managed header /footer

A
A
Vote:
 

Hi, Im trying to createa managed header and footer but am unsure of the best approach.

Right now, I have a simple Header Block that utilizes LinkItemCollection

[ContentType(DisplayName = "Header Block")]
    public class HeaderBlock : BlockData
    {
        public virtual LinkItemCollection Pages { get; set; }
    }

What I would like to do is keep this block, add it to the home page and have it inherit to all the other pages.

Can i do this? Is there another way to achieve this same outcome?

Thanks,

A

#191143
Apr 20, 2018 19:09
Vote:
 

Hi CC,

You could have a look at the Alloy demo site and how the footer links are implemented. Basically the start page has a properties for the footer items and then the PageViewContextFactory.cs has code to map those properties to page view model Layouyt property which all pages use. So have a look at the Alloy implementation code.

You can do the same for your header links so you don't actually need a block just for that (if you have just one property there). If you will have multiple properties in the block and you are using the block to create a "property group" then I think you should have the block as local block and have it as a property on the start page. Then you would have some code that handles reading those values (and maybe cache the values) and supply them to your header.

There are plenty other options like you could have your header links in a block and you create one instance of it, then you would have a property (content reference, allowed types the header block) on the start page and then just select the reference to your header block.

Or you could have a settings page type where you collect all your site settings, have a content reference to this instance on the front page OR no reference at all but code to for example find the first site settings page instance under start page and there you would have your all site settings.

I would say there is no right way of doing this ;)

For example if you have all your site settings defined on the site start page on different tabs and then you have caching for the values and you have hooked to the content publishing event and check there that the page type being published is your sites start page type, then everytime the actual content of the start page is changed you also discard your cache for settings because start page changed. If you have just reference on the start page to your settings page then you could check has the reference to your site settings page changed or not. If you just have logic that your site settings page instance is under site start page then you in the event handler just check that is the page being published type of your site setting page and act according to. BUt many options here ;)

#191146
Apr 20, 2018 19:59
Vote:
 

Add this block to the StartPage (Home page) as a local block

[Display(
       Name = "Site Header Block:",
       GroupName = Global.GroupNames.SiteSettings,
       Order = 100)]
        public virtual HeaderBlock Header { get; set; }

Then use the following code in the SitePageData (base page) so all pages inherit it.

public SiteHeaderBlock Header => ContentHelper.GetStartPage()?.Header;



#191150
Apr 20, 2018 22:14
Vote:
 

I would say this is bad design. Site header or footer doesn't have anything to do with the page data. You need the header and footer in your layout files. So if you create a helper method to fetch the header and/or footer use it on the layout to pass the data as a model for the header/footer view, or fetch it using the helper method in the view (if not using layout model as in Alloy sample for the site). Yes the above works but is it good design - no.

#191152
Apr 20, 2018 22:56
A
Vote:
 

Thanks guys, the new 'issue' is that the layout file is referencing the home page for content.

While I'd like to keep the header and footer managed on the home page - I was wondering if there is a better way to get this content.

public class LayoutViewModel
{
    private IContentLoader _repo = ServiceLocator.Current.GetInstance<IContentLoader>();
    public HeaderBlock Header { get; set; }
    public FooterBlock Footer { get;set; }
    public LayoutViewModel()
    {
        HomePage homePage = _repo.Get<HomePage>(ContentReference.StartPage);
        this.Header = homePage.Header;
        this.Footer = homePage.Footer;
    }
}


Thanks,

- A

#191199
Edited, Apr 23, 2018 19:36
Vote:
 

Hi CC,

Your layout view model should be a dumb class just containing properties and no functionality like getting IContentLoader and then loading in constructor the HomePage.

Look at Alloy for reference, how the PageViewContextFactory is responsible for creating the LayoutModel and how PageContextActionFilter is used to make sure there is a view model (by calling the PageViewContextFactory CreateLayoutModel method). The PageContextActionFilter also have some other responsibilities and you can also add your solution dependant responsibilities there that don't belong to page controllers.

Talking about these classes:

#191207
Apr 24, 2018 5:50
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.