+1-888-365-2779
Try Now
More in this section
Categories
Bloggers
Blogs RSS feed

Mapping to different templates based on provider name

by Ivan Osmak

[This post is part of the developer's manual preview published on this blog. You can find temporary TOC here.]

 
[This article requires Sitefinity 3.6 hotfix to be installed

 

In versions prior to Sitefinity 3.6 there was a convention that for each new provider (see this article on provider model if you need a refresher) one would create a new folder in ~/Sitefinity/ControlTemplates and ~/Sitefinity/Admin/ControlTemplates folders and name it after the provider name. Sitefinity would then automatically go to these folders and find the appropriate templates based on the provider name.

 

In Sitefinity 3.6, since the templates have been embedded, this concept is not applicable anymore.

 

Before we delve into the specifics, let us first examine why would one want to have different templates for different providers. While you will find many scenarios that require such customization, a good and common example to explain this principle is TagsList control.

 

TagsList control is part of the Generic Content module and its fully qualified name is:

 

Telerik.Cms.Engine.WebControls.Tags.TagsList

 

However, since all Generic Content based modules support tagging, such as Blogs or News, we will probably be reusing this control for different purposes (on one page we will display list of blog tags, on another list of news tags). Following this thought comes the requirement that the template for TagsList control when used for Blogs is different than when used with News.

 

Luckily, new Controls Config file can handle this with utmost simplicity.

 

Provider based mapping


Let us examine how could we map TagsList control to different templates based on the provider name property of the TagsList control.
  • First we will open our ControlsConfig file (see this article for more info on ControlsConfig file) and paste following declaration between the viewMap nodes.
    <!--Provides user interface for displaying the list of tags for the content items.--> 
     <viewSettings hostType="Telerik.Cms.Engine.WebControls.Tags.TagsList"  
    layoutTemplatePath="~/Sitefinity/ControlTemplates/Generic_Content/TagsList.ascx" /> 
     
  • In the first step we have simply mapped the TagsList control to an external template, very much in the same fashion as we did in this article.
  • Now, we will once again resort to the additionalTemplates collection. We will define the additionalTemplates in a way that the key of each additional template will be the provider name. So if we are to define a different template for the Blogs provider, we would modify our declaration in following way:
    <!--Provides user interface for displaying the list of tags for the content items.--> 
        <viewSettings hostType="Telerik.Cms.Engine.WebControls.Tags.TagsList" layoutTemplatePath="~/Sitefinity/ControlTemplates/Generic_Content/TagsList.ascx"
          <additionalTemplates> 
            <add key="Blogs"  
                    layoutTemplatePath="~/Sitefinity/ControlTemplates/Blogs/TagsList.ascx" />       
          </additionalTemplates>     
    </viewSettings> 
     
We, of course, need to provide templates for both paths that we have specified.

 

*** IMPORTANT ***

 

Every time you modify ControlsConfig file it is necessary to restart the application in order for the changes to be applied. While there are numerous ways to restart an application, here are few handy ones - you can restart the IIS server, resave web.config file (e.g. open web.config file, press space, press backspace, save config.file), resave global.asax file (e.g. open global.asax file, press space, press backspace, save global.asax file)…

 

*** END IMPORTANT ***

 

*** NOTE ***

 

If you map to an external template that ends with the .ascx extension, you will be using standard ASP.NET template parser which means you will also need to provide localization file in the App_LocalResources file. Resources files are also part of the package that comes with ExternalTemplates.zip file.
If, on the other hand, you decide to use Sitefinity parser, embedded localization resources will be used. Sitefinity parser will be used if template ends in any other extension except .ascx (though the convention is .sft).

 

*** END NOTE

 

A question may come to one’s mind, what happens if we specify a provider name for which we haven’t defined additional template. Namely, if template for provider has not be mapped, Sitefinity will gracefully fall back to the default mapping defined in the viewSettings elements as  "~/Sitefinity/ControlTemplates/Generic_Content/TagsList.ascx".

 

Mapping controls with multiple templates to different providers


We have seen so far how to map an embedded template to external one, how to map embedded templates of controls that have multiple templates to external templates and finally we’ve seen how to map to different templates based on the provider name.

 

What is left to demonstrate is how to map embedded templates of controls that have multiple templates differently based on the provider name. While, you may feel slight dizziness from the previous sentence, in fact the approach is rather simple and straightforward.

 

Let us take ListDisplay control for an example. ListDisplay control has seven different templates, based on the mode in which you wish to display the list. Our first step is to map the embedded templates to external ones. In order to do so, we will paste following declaration between the viewMap nodes of our Controls Config file:

<viewSettings hostType="Telerik.Lists.WebControls.ListDisplay"
      <additionalTemplates> 
        <!--Simple list--> 
        <add key="SimpleListTemplatePath" layoutTemplatePath="~/Sitefinity/ControlTemplates/Lists/SimpleListView.ascx" /> 
        <!--Expanded list--> 
        <add key="ExpandedListTemplatePath" layoutTemplatePath="~/Sitefinity/ControlTemplates/Lists/ExpandedListView.ascx" /> 
        <!--Expandable list--> 
        <add key="ExpandableListTemplatePath" layoutTemplatePath="~/Sitefinity/ControlTemplates/Lists/ExpandableListView.ascx" /> 
        <!--Anchor list--> 
        <add key="AnchorListTemplatePath" layoutTemplatePath="~/Sitefinity/ControlTemplates/Lists/AnchorListView.ascx" /> 
        <!--Page list--> 
        <add key="PageListTemplatePath" layoutTemplatePath="~/Sitefinity/ControlTemplates/Lists/PageListView.ascx" /> 
        <!--Simple Rotating list--> 
        <add key="RotatingListsSimpleTemplatePath" layoutTemplatePath="~/Sitefinity/ControlTemplates/Lists/RotatingListsSimpleView.ascx" /> 
        <!--Expanded Rotating list--> 
        <add key="RotatingListsExpandedTemplatePath" layoutTemplatePath="~/Sitefinity/ControlTemplates/Lists/RotatingListsExpandedView.ascx" /> 
      </additionalTemplates> 
    </viewSettings> 
 
  We are already familiar with this syntax, since we have seen it in the article about Mapping multiple templates of a control. However, this time our goal is to provide different set of mappings based on the provider name. Let us imagine that we have created a new provider for Lists module and named it “Lists1”. In order to map different templates for Lists1 provider, we will modify the mapping declaration in following manner:

<viewSettings hostType="Telerik.Lists.WebControls.ListDisplay"
      <additionalTemplates> 
        <!--Simple list--> 
        <add key="SimpleListTemplatePath" layoutTemplatePath="~/Sitefinity/ControlTemplates/Lists/SimpleListView.ascx" /> 
        <!--Expanded list--> 
        <add key="ExpandedListTemplatePath" layoutTemplatePath="~/Sitefinity/ControlTemplates/Lists/ExpandedListView.ascx" /> 
        <!--Expandable list--> 
        <add key="ExpandableListTemplatePath" layoutTemplatePath="~/Sitefinity/ControlTemplates/Lists/ExpandableListView.ascx" /> 
        <!--Anchor list--> 
        <add key="AnchorListTemplatePath" layoutTemplatePath="~/Sitefinity/ControlTemplates/Lists/AnchorListView.ascx" /> 
        <!--Page list--> 
        <add key="PageListTemplatePath" layoutTemplatePath="~/Sitefinity/ControlTemplates/Lists/PageListView.ascx" /> 
        <!--Simple Rotating list--> 
        <add key="RotatingListsSimpleTemplatePath" layoutTemplatePath="~/Sitefinity/ControlTemplates/Lists/RotatingListsSimpleView.ascx" /> 
        <!--Expanded Rotating list--> 
        <add key="RotatingListsExpandedTemplatePath" layoutTemplatePath="~/Sitefinity/ControlTemplates/Lists/RotatingListsExpandedView.ascx" /> 
         
        <!--Simple list--> 
        <add key="SimpleListTemplatePath|Lists1" layoutTemplatePath="~/Sitefinity/ControlTemplates/Lists1/SimpleListView.ascx" /> 
        <!--Expanded list--> 
        <add key="ExpandedListTemplatePath|Lists1" layoutTemplatePath="~/Sitefinity/ControlTemplates/Lists1/ExpandedListView.ascx" /> 
        <!--Expandable list--> 
        <add key="ExpandableListTemplatePath|Lists1" layoutTemplatePath="~/Sitefinity/ControlTemplates/Lists1/ExpandableListView.ascx" /> 
        <!--Anchor list--> 
        <add key="AnchorListTemplatePath|Lists1" layoutTemplatePath="~/Sitefinity/ControlTemplates/Lists1/AnchorListView.ascx" /> 
        <!--Page list--> 
        <add key="PageListTemplatePath|Lists1" layoutTemplatePath="~/Sitefinity/ControlTemplates/Lists1/PageListView.ascx" /> 
        <!--Simple Rotating list--> 
        <add key="RotatingListsSimpleTemplatePath|Lists1" layoutTemplatePath="~/Sitefinity/ControlTemplates/Lists1/RotatingListsSimpleView.ascx" /> 
        <!--Expanded Rotating list--> 
        <add key="RotatingListsExpandedTemplatePath|Lists1" layoutTemplatePath="~/Sitefinity/ControlTemplates/Lists1/RotatingListsExpandedView.ascx" /> 
      </additionalTemplates> 
    </viewSettings> 
 
  A concentrated reader will notice immediately the difference. All that we have done was added provider name to the key and separated it with a pipe sign from the template path name.  As always, the question appears what happens when you have a provider for which you have not mapped the templates (e.g. let’s assume we have provider “Lists3”). In this case, Sitefinity will fall back to the first declaration which we have declared without provider name and hence specified that this is a default mapping.

Leave a comment