As Sitefinity gets bigger as a software project, many small features that get implemented may stay unnoticed. While trying to solve problems, developers often provide solutions that may be used elsewhere, and not just the specific feature they are implementing. This is how design patterns are born. We do have a lot in the Sitefintiy codebase that may not be very well known and used.
One such not-so-famous feature is called Conditional Templates and this blog post is an attempt to explain when and how you can use it in your custom development.
When implementing functionality as a separate widget, we often have a requirement of providing different user interface, depending on how the widget is used. This is very similar to having multiple widget templates. The different requirement is that you should be able to switch between them dynamically. Let me give a few examples.
- A weather widget, which may display its user interface in several modes: current temperature, the current weather as an image, the current weather as text
- A widget that displays a different chart: bar chart or pie chart
- A widget that can display a value or be used to edit that value
All these cases can be generalized to something, which we will call modes. A mode is just one way of displaying the user interface of a widget.
I assure you we’ve had many cases like the above in Sitefinity. The solution that was implemented is called conditional templates. They give you the ability to work with multiple widget templates, but let you change them at runtime, depending on a property in the widget. They are not “real” widget templates, but rather different markup from the same template.
The reason this is not very well known is that out of the box it is only supported in the so called field controls, and those work only in the backend. Sitefinity custom development usually leans towards the frontend of a site, not extending Sitefinity’s backend itself. That’s quite normal, but it’s also very easy to use conditional templates for any kind of custom widget. Here’s how.
Create a custom widget and inherit from SimpleView
Let’s take the weather widget example mentioned above.
We recommend that you inherit from SimpleView when implementing custom widgets to be used in Sitefinity. There are a couple of methods and properties you need to override. Those include LayoutTemplateName and LayoutTemplatePath, and also InitializeControls. Instead of doing this manually, alternatively you can use Sitefinity Thunder and it will generate a widget with those overridden by default. For more info on Thunder, head over to the documentation. The final code for the newly created widget is the following:
Implement the property used as a condition
Instead of using strings, I’ll also implement an enumeration with all the modes our widget supports.
Once we have the enumeration, we add a property, whose value will represent the condition in our conditional templates. It will use the enum created above as a type.
Include a ConditionalTemplateContainer in the widget template
Now that we have a property showing the mode, we need to include the markup for each mode in the widget template. This is done by placing a conditional template container inside the template. You also need to register the required namespace Telerik.Sitefinity.Web.UI. Once we have the container on the page, adding a template for each mode is very similar to adding item templates in data-bound controls like the repeater. Here is the final markup
The three important attributes to remember for each conditional template are Left, Operator and Right. Those represent the condition to which the template corresponds. The case above could be translated in plain English as “If Mode is equal to Temperature” (then load the first template) or "If Mode is equal to Text” (load the second template). By setting the value of the Mode property, we can control which markup gets rendered by our widget. This approach is more readable, easier to debug and more structured than manually showing and hiding controls through code or CSS.
Override the CreateContainer method
Up until this point we have implemented our conditional templates. The only thing left to do is hook up the logic to make use of them. As I said above, this has already been done for field controls in Sitefinity. In order to do it in your widgets, you need to override the CreateContainer method. Inside its implementation, you should only call Evaluate() on the conditional template container. That call takes care of everything to initialize the template depending on the condition.
Once you are able to show conditional templates, you can put any markup inside them. The example displays static data, but you can easily use the Sitefinity API to bind to data inside the CMS or implement your own business logic. Then you can switch between the different markup by just setting the value of the Mode property.
You can download the source code of the example shown above from here.
I hope this feature makes you life easier when you encounter a similar need in your future Sitefinity development projects.