Theming Orchard

I’ve just finished redesigning my site and implementing that design as an Orchard Theme. While it’s still fresh in my head I wanted to write down what I’d learnt. The documentation on the Orchard site is pretty good, but I wanted to write down the things that I found most important. I hope you find it useful.

An Orchard page is made of lots of bits; layout, zones, shapes, items, parts and fields. This can be a bit confusing and I’m still getting my head round it. You can find a more complete description of all of these in the anatomy of a theme in the Orchard documentation.

The HTML that displays all these bits is controlled by various CSHTML files and an XML file. If you’ve not used CSHTML before I’d recommend reading Scott Guthrie’s blog post Introducing Razor.

Even if you create a blank theme there are defaults for all the different parts of an Orchard Theme. The defaults are still controlled by CSHTML files, but they’re a bit scattered and hard to find at first if you don’t understand the rules. The defaults are quite sensible and you may find that you don’t need to override many of them and a lot of your styling can be done with your style sheet. I’m going to go through the files that I needed to override to create my theme.

First you need to generate your theme. You could copy an existing one, or use Orchard’s code generation feature. Now you’ve got a blank theme and can start having fun.

/Theme.txt

Here you can give your theme a nice name and a description. These are only really important if it’s a theme you’re going to share. The most important bit is where you define what zones you’re going to use. Zones are the parts of your page where you can place content and widgets. I thought I’d be able to choose my zone names but it seems you need to pick from the possible zone names defined by Orchard. These are: Header, Navigation, Featured, BeforeMain, AsideFirst, Messages, BeforeContent, Content, AfterContent, AsideSecond, AfterMain, TripelFirst, TripelSecond, TripelThird, FooterQuadFirst, FooterQuadSecond, FooterQuadThird, FooterQuadFourth and Footer.

/Views/Layout.cshtml

This is the main layout of your site and is used for all pages in your site. It covers everything between the opening and closing body tags. It’s where you get to control where on the page the various zones will be shown. You can even include conditional logic that will only show things if a zone has content in it.

/Styles/Site.css

You don’t need to call your style sheet Site.css, but it must go in the styles folder. You can register a style sheet at any point, but for a site wide style sheet you will probably want to do this in Layout.cshtml. You register a style sheet like this:

@{ Style.Include("Site.css"); }

/Views/Content.cshtml
/Views/Content.Summary.cshtml

These control the overall layout of a piece of content like a blog post or a page. The summary one controls how it looks when displayed as part of a list. I thought I would need to change these, but they actually delegate most of what they display to content part templates. The actual layout specified in the default was good enough for me so I stuck with it.

/Views/Content-11.cshtml

I wanted to display the content on my homepage slightly differently than other pages. My homepage has an ID of 11 so I was able to reference it with a file called Content-11.cshtml. I could also have created a template for all blog post content using a file called Content-BlogPost.cshtml had I needed to do so.

/Views/Parts.Common.Body.Summary.cshtml

I wanted to change how long the body text of a summary was and this is the file that controls that.

/Views/Parts.Common.Metadata.cshtml
/Views/Parts.Common.Metadata.Summary.cshtml

This shows the date a post or page was published. I wanted to change it to use the HTML5 time tag.

/Placement.info - The order of things

I wanted to display the tags and comment count under a post and this is where I got stuck. The templates defined several shapes that made up a piece of content like header and footer, but didn’t say what went in these. The templates for the tags and comment count just controlled how those looked and not where they were placed. This is where Placement.info steps in. Each module has its own placement file that defines where the parts like to live, but you can override this in your theme’s placement file.

My Placement.info file looks like this:

<Placement>
    <Match DisplayType="Detail">
        <Place Parts_Tags_ShowTags="Footer:1"/>
    </Match>
    <Match DisplayType="Summary">
        <Place Parts_Tags_ShowTags="Footer:4"/>
        <Place Parts_Comments_Count="Footer:5" />
    </Match>
</Placement>

What file is what and where can I find the base file

Figuring out theming for me was all about seeing a part of the page and figuring out which file I needed to copy into my theme to change it. Sometimes I needed to copy a file and then change its name so it was more specific to a particular type of content. I found the Experimental Developer plugin very useful. With this installed you can hover over a part of the page and it will tell you the file you need. It changes the page’s HTML though so I needed to turn it off when I was using Firebug to look at my pages makeup.

I couldn’t always find the file I needed using Experimental. I found the table of Template naming rules in the Orchard documentation very useful in these cases and more.

As the files are a bit scattered I found the search feature in Solution Navigator very useful. The Solution Navigator is part of the Productivity Power Tools extension for Visual Studio 2010 and is definitely worth installing if you haven’t already.

My blank theme

I've taken what I've learnt from this and created a simple blank 2 column theme. It includes some labels to help you work out which file controls what. You can download my Blank Theme from the Orchard Gallery. It's not as sophisticated as the Theme Machine, but it brings the common template files you'll need together. If there's anything else you'd like this theme to illustrate then please let me know.

16 Comments

  • Sebastien Ros said

    Very nice job, thanks ! I can't say I have learnt anything ;) but I am sure a lot of readers will, and I will definitely recommend it.

  • Shahnawaz Khan said

    Nice post, I'm also learning orchard and finding the best way for theming. One suggestion for naming your homepage content template, you can use Content-Homepage.cshtml instead of Content-11.cshtml

    Thanks!

  • Piotr Szmyd said

    Good job!:) The docs were definitely lacking a quick theme building description like this! I was thinking about writing one lately (on my soon-to-be-launched Orchard blog) but now it seems I'd better stick to module development;)

    Your theme is much better starting point than Theme Machine - that one is rather complicated (I know it has to show all the features) and lacks examples of overriding content shapes...

    Keep up the good work!

  • John Tarbox said

    Great post, thank you!

    Will you be using multi-level menus and are you planning om updating your previous blog post about them?

  • Richard said

    @John, I've got no plans to use multi-level menus on this site. It's not really complicated enough to need them. I will be checking them out though and although I've not blogged about them before I might in the future.

  • Richard said

    @Shahnawaz, it would be great to be able to use Content-Homepage.cshtml, but you need to do some jiggery pokery to make that work.

    http://weblogs.asp.net/bleroy/archive/2011/01/10/orchard-shapeshifting.aspx

  • Joel said

    Thanks for the post. I just picked up Orchard and trying to figure out how it works (after spending some time thinking Umbraco was the way to go). This is helpful.

  • Terrence said

    I've ported three production website from static HTML -> Orchard, and I just wanted to add on some lessons learned:

    1: If you have two CSS files named the same (site.css), one in the root of the styles folder, and one in a sub-folder under styles, Orchard will pick the one in the root folder over the sub-folder, even if you explicitly tell it the sub-folder. Assume nothing, trust your HTML debugger and make sure the CSS/Script/Images it is loading is really what you want it to be loading.

    2: When migrating, leave your original CSS un-modified as long as possible. Consider creating an Orchard.css and putting Orchard only stuff there (such as the styles for edit mode), or overrides. It will help you when you have the Orchard version of a page up side-by-side with the static html version.

    3: Orchard puts wrapper HTML around a lot of things. Sometimes the wrapper uses non HTML tags (such as <article>), and other times it uses <div> or <span>. This can be bad if you have high-level CSS applied to these elements. Again, assume nothing and use your HTML debugger to find these evil wrappers and use CSS to fix them. Optionally, use the Experimental Module to find the .cshtml file that is injecting these wrappers. If that fails, use a tool that can "Find in Files" and try matching on the troublesome HTML.

    4: Try to avoid using the Media feature for the stock-art or simple images of your website. The static-file HTML handler seems to push these images out a little faster. Also, if you ever go from single-tenant to multi-tenant, your images paths will change from /Media/Default to /Media/Tenant.

    5: If you are in a situation where there are multiple Layouts for a single site, you have some options. Before Orchard 1.0, I would create a Zone called "NewsLayout" and add an empty widget to that zone in a Layer for all news pages. Then, in my Layout.cshtml I would check to see if anything is in that zone, and if so I could radically change the layout. Now that we have fields, lists, and other things there may be some more elegant options, but this is at least a working solution.

  • Richard said

    @Terrence, thanks for the points.

    The only point I'd make is that <article> is valid HTML, it's just that it's HTML 5. Orchard's standard theming uses HTML 5. If you'd rather not use HTML 5 then you're free to overright it. It just means you need to override more of the standard template files.

  • Tim French said

    Thanx for the theme help. It really helped me sort out placement and what files do what.

    Q: do you know how I can hide a custom field for a custom Content Type in the summary List?

  • setiri said

    We're working to move setiri.com to orchard, curious if you have an recommendations for how to do a page that is pretty much different from the rest- the hope page is a simpler single-column design "welcome" kind of deal, while the rest of the site is mostly a 2 column layout etc. Thanks!

  • MegaNanodots said

    This is a great inspiring article. I am pretty much pleased with your good work. You put really very helpful information. Keep it up. Keep blogging. Looking to reading your next post.

Comments have been disabled for this content.