Parameterized Snippets

Snippet elements are elements dynamically discovered based on Razor views whose name follow a certain convention: Razor views that end with Snippet.cshtml are harvested as a Snippet element. For example, ButtonSnippet.cshtml would yield an element called Button Snippet.

As of Orchard 1.10, this feature has been enhanced to provide parameterizable snippets. A parameterized snippet enables users to add snippet elements to the layout editor and configure these snippets with custom settings.

To add settings to a snippet, all the theme developer needs to do is invoke an Html helper called SnippetField. This nifty helper serves two purposes:

  1. To provide meta information to the element editor about the configurable field.
  2. To read the configured value for the field when the element is being rendered.

The signature of the helper looks like this:

SnippetFieldDescriptorBuilder SnippetField(this HtmlHelper htmlHelper, string name, string type = null) {}

And you use it from a view like this:

@Html.SnippetField("MyPropertyName").DisplayedAs(T("My Property Name")).WithDescription(T("This is a sample property of the snippet."))

As you can see, it accepts a name and a type. The name represents the technical name of the field, while the type represents the data type of the field. At the time of this writing, only one type is supported: text.
The method returns a thing called SnippetFieldDescriptorBuilder which enables the theme developer to provide more information to the snippet field using a fluent API, currently just a DisplayName and Description, both of which are used when presenting the user with the element editor dialog in the back-end.

Parameterized snippets are a great tool for theme developers to create custom elements without the need to write element classes. All they need to do is create a Razor view and provide the necessary markup.

To get a good understanding of what you can do with parameterized snippets, let's see how create one.

Demo: Parameterized Snippets

In this demo, we'll build a reusable, parameterized snippet called JumbotronSnippet with two fields: Caption and Text. The idea is that users can add any number of jumbotrons to their pages and provide a caption and a body text.

The first thing to do is create a view called JumbotronSnippet.cshtml in our theme and provide the following markup:

@using Orchard.Layouts.Helpers
@*Using inline CSS for demo purposes.*@
@using (Script.Head()) {
   <style type="text/css">
      .jumbotron {
      padding: 2em;
   background: #ededed;
   }
   </style>
 }
 <div class="jumbotron">
 <h2>@Html.SnippetField("Caption").DisplayedAs(T("Caption")).WithDescription(T("The caption of this jumbotron."))</h2>
 @Html.Raw(Html.SnippetField("Text").DisplayedAs(T("Text")).WithDescription(T("The body text of this jumbotron")))
 </div>
 

First of all, notice the inclusion of the Orchard.Layouts.Helpers namespace. This is important to make available the SnippetField extension method.

In the above code, I am rendering two snippet fields: Caption and Text. This means that the user will be able to provide a value for a Caption and a piece of text. When this snippet is rendered, the SnippetField method will return the user-provided values.

Notice that I'm chaining the DisplayedAs and WithDescription methods. The fluent API enables us to do everything in a single line rather than having to first instantiate a snippet field, initializing it with desired values, and then render it.

With this snippet in place, all we need to do next is make sure that the Layout Snippets feature is enabled and add the Jumbotron element to our canvas.

Notice that as soon as you drag & drop a Jumbotron element to the page, the element editor dialog appears, showing the two fields as defined in the JumbotronSnippet.cshtml file:

As you can see, the editor took the information from the snippet field descriptors as created in the view and used it to render appropriate input controls.

Let's see how this looks on the front end:

Summary

In this post, we learned how snippets work and how we can parameterize them so that users can configure them from the layout editor. Snippets enable theme developers to create custom elements without having to write C# classes. All that's required is a Razor view and some markup.

4 comments

  • ... Posted by jtkech Posted 02/21/2016 02:49 AM

    Wow, just tried it and i was able to create a configurable element in 1 minute!

  • ... Posted by Ondra Kopp Posted 05/25/2016 01:58 PM

    very nice example. But i can use snippet for read some value from external database? What i can do it ?

  • ... Posted by Sipke Schoorstra Posted 05/25/2016 04:14 PM (Author)

    Yes, there are various ways to go about that, but it would require coding.

    The first way is to implement a shape table provider that handles the Displaying event of the snippet shape. From that handler, you could inspect the fields and their values for example as inputs to your DB query, and set the results of your query onto the shape.

    The second way is to extend the available field types (currently there is just text). For example, if you have a DB with reference data from which you want the user to be able to select a value, e.g. Country, you could implement a Country dropdown field type. Since field type editors are also shapes, you could implement a shape table provider for that shape and inject the available countries.

    Finally, you could perform all of this querying from within the Razor views, but I would not recommend that.

  • ... Posted by NomadIan Posted 12/06/2016 11:26 PM

    Great stuff! I bought & have been reading through your Layouts book, it's very helpful. How would you go about implementing a dropdown field type rather than just the text field?

Leave a comment