Categories
Bloggers
Blogs RSS feed

Mapping External Templates for Sitefinity Widgets

by Josh Morales

As we saw in the last post , it is possible to run server-side code by placing it directly in the Widget Template. However, although this works for quick examples, it lacks many of the conveniences of developing your template inside Visual Studio such as Intellisense and debugging.

Fortunately, it is possible to map the widget templates to external files, and in fact there are two ways to do this. Today we'll take a closer look at how this is done.

Option 1: Mapping an External Template

The first option is to edit the Widget Properties directly on the page, pointing it to your template file. For this example we'll look at the Events View widget in the Sitefinity Non-Profit Starter Kit.

Create the Template

The best way to create an external template is to copy it from an existing one. Open up the list of widget templates under the Design menu of the Sitefinity Administration backend. For this example we'll be using the DateList template for the Events - List view.

Sitefinity-4-Widget-Templates

Open that template, the select everything after the first line of the template. When we create our user control, it will include it's own copy of this line, so we need to skip it when we copy the template.

Sitefinity-4-Widget-Templates-Copy-Template

Now open up your Sitefinity project in Visual Studio. Add a new User Control to your project. For organization, I recommend using a format like ~/Templates/Events/EventListTemplate.ascx. Paste the markup from the widget template into the control.

CodeFile

If you are using a Web Application Project, there is one important change you need to make. You see, templates are loaded dynamically by Sitefinity instead of being compiled into your project. As a result the user control must be modified to behave as a Web Site Project User Control so that it can behave as such when it is loaded.

Fortunately this is easy to do. Simply change the CodeBehind property on the first line of the .ascx control to instead be CodeFile. Now when the template is loaded, it will also load the associated code-behind file, meaning you no longer have to use the <script> tag as we did last time!

Map the Template

Now that we've created the external template, we need to tell the widget to use it. In this starter kit, the events view widget is on the ~/Events page, so open it up in the Sitefinity administration and edit the widget and click the "Advanced" button.

Sitefinity-4-Widget-Templates-Widget-Editor 

Now click the ControlDefinition button, then on the next page click the Views to see the two views for the widget.

Sitefinity-4-Widget-Templates-Widget-Editor-Advanced Sitefinity-4-Widget-Templates-Widget-Editor-ControlDefinition

We want to edit the EventsFrontendList view, so click that button and scroll down to see the TemplateName and TemplatePath properties.

Simply set the path to your .ascx file in the TemplatePath property to point the view for the widget to the template.

Sitefinity-4-Widget-Templates-Template-Path

Important Note: The Guid in the TemplateKey corresponds to the ID of the internal Sitefinity Widget Template. This property does take priority over the TemplatePath value, so be sure to delete the Guid so that the property is blank or it will continue to use the internal template instead.

Save your changes and publish the page and you'll now see that the template is loading from your external file.

Sitefinity-4-Widget-Templates-External

Option 2: Using the Virtual Path Provider

As mentioned by Slavo in the previous post Taking advantage of the Virtual Path Provider in Sitefinity 4.1, the new Virtual Path Provider simplifies loading of internal and external resources. We can use this to our advantage when mapping external templates.

The way that the VPP works for Widget Templates is through the virtual path ~/SfCtrlPresentation/[PageProviderName],[TemplateGuidWithoutDashes].ascx. This means it's looking for the template in the virtual "folder" named SfCtrlPresentation that follows the naming convention that matches the template.

If we want to override the internal templates, we simply need to create this actual folder and place inside it a template that matches that naming convention.

More than likely you are using the Default Page Provider for Sitefinity, so the PageProviderName should be OpenAccessDataProvider. The Template Guid corresponds to the TemplateKey property we saw above, except with the dashes stripped out.

So to use the Virtual Path Provider, instead of deleting the TemplateKey property and setting the TemplatePath, we leave the TemplateKey property in place and use that Guid for the external template name, removing the dashes.

That means for this widget template, we'll create the SfCtrlPresentation folder, then inside it create a new User Control and name it OpenAccessDataProvider,c2b52ad7acaa4838a3c695a275a8f014.ascx.

Note that the comma is required as part of the name of the template file.

As before, change the CodeBehind property of the User Control to CodeFile. Now when you visit the Events page, it should load the physical template file, overriding the Virtual Path it would otherwise use if it didn't exist.

Sitefinity-4-Widget-Templates-VPP

Considerations

Clearly working with the internal naming convention is slightly cumbersome, and improvements to this process are already in the works so that using the VPP to map templates is simpler and more intuitive. However this does allow you to create a direct mapping from an internal template to an external file.

In addition, remember that the Guid used corresponds to the ID of the internal Widget Template, and this template needs to be assigned to the Widget in order for it to be loaded correctly. If you change the view to use a different internal template, the Guid will change and your template will not be loaded. This too is already being addressed by the development team.

Feedback and What's Next

To close of this discussion on templates, I'll be posting a quick 5 things post later this week on some of the additional benefits you gain from using external templates.

I also strongly encourage you to try playing with external templates yourself in your Sitefinity projects and especially to report your feedback via our Sitefinity 4 discussion forum. This is a new way to hook into additional opportunities for customization, so we want to know how you're using it and how it can be improved.

7 comments

Leave a comment
  1. Jason May 23, 2011
    Which version of Sitefinity 4 does this apply to? Following these instructions with a default installation of 4.0 does not produce the same results.

    Also - at the bottom of this page, where it says "see latest post in devloper tools blog", I'd suggest using the correct spelling for "developer".
  2. Sean Molam Jul 09, 2011
    Hi Josh,

    While the instructions for the Virtual Path Provider sound good they are incomplete.  Firstly the TemplateKey isn't filled in until after the template as been selected under simple.

    The second important piece of information missing about this is that the TemplateKey value isn't filled for the EventsFrontendDetails view so how do you get the GUID for this?

    This feature on the surface looks very useful but still isn't "easy" to use yet.  Using Control mapping from the settings kind of like what used to happen in 3.7 still seems to be the most reliable form of mapping external templates, but not for all template unfortunately...

    Cheers
    Sean
  3. Josh Jul 20, 2011
    @Jason, the Virtual Path Provider was introduced in Sitefinity 4.1, it looks like that's going to be the required version to follow this post, apologies for not pointing that out.

    Also thank you for reporting the typo, I have alerted our web team to fix!

    @Sean you are correct, and we are continuing to develop and improve this process, I will take a look at the EventsFrontendDetails and report your feedback to the team.

    I am also preparing a post on mapping controls through the settings, which is indeed a simple way to map templates globally.

    Thank you both for your feedback!
  4. Rahul Patel Oct 12, 2011
    FYI... in the samples Product Catalog Module the MasterListView.LayoutTemplatePath property getter needs to be changed from:

                get
                {
                    return "~/SFRes/" + titlesDatesLayoutTemplateName;
                }

    to:

                get
                {
                    string layoutTemplatePath = base.LayoutTemplatePath;
                    if (string.IsNullOrEmpty(layoutTemplatePath)) {
                        return "~/SFRes/" + titlesDatesLayoutTemplateName;
                    }
                    return layoutTemplatePath;
                }
  5. Alex Apr 27, 2012
    Has this been fixed in SF5? Can we just set the template in control definitions view template path? I tried this with a module built with module builder but nothing changes
  6. Josh May 03, 2012
    Alex, template paths for dynamic module widgets have not yet been implemented. This is a known issue and is logged for fixing in a future release, however you can use Sitefinity Thunder to easily modify these templates! be sure to check that out as it's a MUCH easier way to manage your templates.

  7. wholesale soccer uniforms Aug 10, 2013
    I bet everyone here is gonna wine about ‘same design’ and ‘usual template by puma’, but nonetheless this one does good for an original away jersey.

    Leave a comment