How to pass boolean from Startpage to another view?

Vote:
 

In our header we have a language switcher that allows visitors to choose to view a page in one of the available languages, for example EN or DE.

I have created a property in our Startpage.cs model under SiteSettings which I have called HideLanguageSwitcher:

[Display(GroupName = Global.GroupNames.SiteSettings, Order = 120)]
public virtual bool HideLanguageSwitcher { get; set; }

Our Header.cshtml view is using the following as the model:

@model IPageViewModel<SitePageData>

I am having a hard time understanding how to pass the state of the HideLanguageSwitcher boolean from the Startpage model to Header.cshtml.

In PHP with which I am a little more familiar I would have used a global variable.

Any help greatly appreciated.

#264439
Oct 04, 2021 19:55
Vote:
 

You can get the ContentReference to the current site's StartPage with the static ContentReference member StartPage:
https://www.jondjones.com/learn-episerver-cms/episerver-developers-tutorials/episerver-api-explained/how-to-get-a-reference-to-the-start-page-or-root-page/

Then, use a IContentRepository instance to get the start page content and retrieve the property's value. Since IContentRepository caches content instances it shouldn't be an expensive operation to get the start page, but you can do your own caching if you're worried about it.

var startPageRef = ContentReference.StartPage;
var repo = ServiceLocator.Current.GetInstance<IContentRepository>(); // of course you should always prefer Constructor Injecting dependencies instead of using the ServiceLocatory anti-pattern
var startPage = repo.Get<StartPage>(startPageRef);
var isFoo = startPage.HideLanguageSwitcher;

As for where to do this lookup, you have several options.

You could do it in the view for the header, but some people would say that's too much code in a view.

You could create a base ViewModel that implements your IPageViewModel and add a property to that that holds the language switcher switch. I've seen people implement an action filter for OnResultExecuting that adds properties to the current view model or even the base page type wrapped in an IViewModel right before the view is executed.

You could also implement a partial controller that creates a custom ViewModel just for the header.

I'm sure there are other ways, too.

#264441
Edited, Oct 04, 2021 20:40
Vote:
 

Thank you very much for your feedback Drew. I am trying to place this in the Header.cshtml right now.

But for 

var startPage = repo.Get<StartPage>(startPageRef);

I am getting the following error:

'StartPage' is an ambiguous reference between 'Project.Site.Models.Pages.StartPage' and 'System.Web.WebPages.StartPage'

I have tried rather simply to just write out the full path:

var startPage = repo.Get<Project.Site.Models.Pages.StartPage>(startPageRef);

Not sure if it's the correct way to deal with an exception like this, but it works.

#264501
Edited, Oct 05, 2021 7:46
Vote:
 

When you are loading data, and not making updates, you could use IContentLoader istead of  IContentRepository.

#264503
Oct 05, 2021 12:19
Vote:
 

@EpiNewbie

That's correct. In a view file you can also add a using declaration at the top like:

@using Project.Site.Models.Pages

This lets the compiler know that any type names in the Project.Site.Models.Pages should be made available without their fully qualified name. You can also add an import statement to the web.config in your project's Views folder.

https://stackoverflow.com/questions/3239006/how-do-i-import-a-namespace-in-razor-view-page

Of course, @Thomas is correct and since you are not saving, an injected IContentLoader will provide the same functionality as IContent Repository.

#264508
Edited, Oct 05, 2021 13:20
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.