February 2013 - Posts
The multi-tenancy feature in Orchard enables you to host multiple sites within the same Orchard instance. It’s not a a security feature, just a way to improve site density, and to enable you to save on hosting costs. Nevertheless, a request to a specific existing tenant should never be answered with a page from another tenant. Ever.
There is however a fallback mechanism that enables one tenant to handle all requests that weren’t identified by another tenant. While this could be considered useful in some scenarios, I’m hereby declaring it bad practice.
If for any reason a tenant fails to start, for example, requests to that tenant are going to fall back. Even if you were in a scenario where you considered fallback to be useful, this is an unexpected and positively undesirable result. It’s much better to fail with an error message or a 404 than to fail with a fallback to a different site than the one the client asked for.
So here is my recommendation:
Always have a host or URL prefix configured on all tenants, in particular the default tenant.
This way, no fallback will ever happen, and requests will only be handled by a tenant that recognizes its own host name.
Here is, for example, the new configuration of the default tenant on my hosted web sites:
Note that I have multiple hosts configured here, including the host that I use on my dev machine for local development, but the point here is to specify something on all tenants.
This is important.
Placement.info is an XML file that orchestrates the different parts of a content item and sends each of the shapes they create into specific local content zones. If the previous sentence sounded confusing to you, fear not, this post is for you.
When writing an Orchard theme, more often than not, you know exactly what parts exist in your content type, and you know where you want them to render. Placement can be extremely powerful, but it’s rather abstract and it reverses the usual logic of placing contents on a page. What most people really want to do is write a template with simple markup and placeholders inside that markup for the rendering of specific parts such as title, summary, tags, etc. Placement forces you to dispatch those part shapes from a completely separate file.
In the Summer of 2011, I wrote a little article to explain how to write custom templates for specific content types in Orchard, without using placement.info:
So you don’t want to use placement.info?
The solution worked, but relied on a hack that will break with the next version of Orchard (1.7).
Sébastien Ros gave me a little trick the other day that enables the same thing, in a simpler, less hacky form. It still uses placement somewhat, but in a very simple way.
The idea is to create one local zone per part instead of the usual header, content and footer zones. Here we are going to send the relevant shapes to those zones through placement:
This sends shapes into Summary, Tags, MetadataSummary and CommentsCount zones. Those do not yet exist.
Caveat: when naming your custom zones, be careful not to collide with existing properties or zones on the Model, lest you end up with unexpected and confusing results. Using longish and very explicit names usually works well for that.
The template can now simply create and render those zones. Here is my Content-BlogPost.Summary.cshtml template:
var blogPost = Model.ContentItem;
<article class="content-item blog-post">
Notice how in the case of the title, I’m not even using the shape given by the part, but I’m accessing the properties directly on the TitlePart. The other parts are rendered through the special zone that we created using the Display function. And that is all. You can now focus on building your template, and it will be pretty obvious what will render where…
If you want to create a simple widget in Orchard, such as a box of social links, you have three possibilities:
- Find a module on the gallery or write one yourself, but there is overhead associated with modules, which may make this overkill.
- Create a simple widget, following the instructions in this post.
First, let’s create a content type (in the admin, go to Content / Content Types and click “Create new type”) and call it “Social Links”.
Add the widget and identity parts. Those are the only ones you really need:
Uncheck creatable and draftable, add the “Widget” stereotype (with an upper-case ‘W’: I made the mistake, as you can see, of using a lower-case ‘w’ on my first try, and it did prevent the widget from being seen as such):
Now when you add a widget, the social links widget appears in the list:
It’s a simple, apparently featureless widget, which minimizes the chances of accidentally messing it up.
All that’s left to do now is to add a template to the theme that will render what we want. We’ll take advantage of shape alternates. Using shape tracing, we quickly discover that we can name our template Widget-SocialLinks.cshtml to target it narrowly enough:
Once the file has been added to the Views folder of my theme, I can paste in the code from Facebook, Twitter, or whatever else I want in there.
Done. Fastest and simplest way to create a new widget.