Orchard Core Introduction - Part 2 : Building A Custom Theme

Welcome to the next part in our series on Orchard Core development. In our first part we spoke about how to get Orchard Core up and running to develop a brand new website. Next, we explore how we can theme our Orchard site to match a custom design. In legacy Orchard, you simply added a new folder in the Themes directory with a few key files and Orchard did the rest. In Orchard Core it's a little different because themes can be delivered as a Nuget package or are just included as a project dependency into your Orchard Core project. This concept had me confused to start because I am so used to my Themes foler being under the webroot and then having Orchard auto-discover my project. I thought this was the way to go until a helpful friend on Orchard Gitter, Jean-Thierry Kéchichian, pointed me in the right direction.

Thanks for all your help Orchard Gitter on proof-reading this article!

The Simplest Path Is To Copy An Existing Theme

We decided the easiest way to build a new theme was to copy an existing theme and then modify everything we needed to. This would give us good insight into how a theme should be architected.

We ended up copying the Agency Theme. This code is located here in GitHub : https://github.com/OrchardCMS/OrchardCore/tree/dev/src/OrchardCore.Themes

Choose the Agency Theme, and download the code. I first renamed all the files with the naming convention of "TheAgencyTheme" to my new theme name of "MendedLittleHeartsTheme". You can put the code anywhere you like in relation to the webroot because you simply reference it now as a project dependency. I just decided to do it the old way with a Themes folder under the webroot. You then create a new folder with your theme name as the folder name. So your Orchard root directory will look like this :

Then under Themes/MendedLittleHeartsTheme you will have :

You will notice that there are two files here in the root that are not in the code on Github. That is the package.json and the gulpfile.js. These files exist inside the wwwroot directory for the theme and I moved them to the Theme root so in Visual Studio the project was more organized and the gulpfile runs at the right directory level (IMO). You should then load the theme project into your Visual Studio solution. Be sure to create a Themes Solution folder prior so you can keep things legible and organized. Open the Orchard Core solution and add the Theme project in as well so we can work with the theme.

You can now manage the Theme and Orchard Core project together in the same solution. So you might be wondering why I chose to move the package.json file and gulpfile.js as well as how this theme will get pulled in by Orchard. First off change the Theme.txt file to a custom theme name, I chose Mended Little Hearts. Our 2018 charity site we're building. Next you need to add your theme as a project dependency into the Orchard Core project so it gets pulled in. Just right click on the Dependencies node and add a new Project dependency and choose your Theme.

Lastly, you need to update your gulpfile.js to now reference your wwwroot folder from a few directories up. Here is an example of updating the SASS compilation task so it can still compile the code and put it in the proper location. You can also use Visual Studio Task Explorer to properly execute your gulpfile.js on build as well. 

The key part about Orchard Core theming is to make sure you get your static files into your theme's /wwwroot directory. You can use whatever pipeline you want, but in order to have them served properly they need to be in that directory. I had to look-up what the "wwwroot" directory actually does in .NET Core and it appears that it is a special directory that is referenced from the root of your project. We placed all assets in the "src" subdirectory in wwwroot, and then our gulpfile copies the minified versions into the css and js directories under the same wwroot parent directory. Theme assets are then served from the wwroot directory and are included as "Embedded Resources" in your Theme's dll.  This was all new to me and took a little time for me to wrap my head around. You will notice when your theme is activated and running all assets will be referenced as "/MendedLittleHeartsTheme/css/mlh.min.css". This is due to the files being included as embedded resources in your theme and being in the wwwroot folder.

Developers Note : After talking with the Orchard team, it makes sense to have your source assets in a "Assets" directory under yoru theme. Then use your gulpfile to copy them into the appropriate directories under wwwroot. This keeps things organized.

It's pretty cool that we can create our theme using whatever tooling we want for the css and js assets. It makes it much easier because then a front-end develoepr doesn't need to know anything about the Orchard pipeline, etc. They can just manage the gulpfile and handle it on their own. There are three key things I want to talk about here so everyone can get it straight. 

  1. You can use your own gulpfile.js to manage your client side assets and just get them to wwwroot as you want.
  2. You can take advantage of the Orchard pipeline and create an "Assets.json" file which will replace gulp/grunt for you and you can get minification and uglification out of the box. This is a great option. You can read about it here. Also /Assets is automatically excluded so you don't need to worry about that.
  3. You then can take advantage of the ResourceManifest.cs file in order to "reference" these assets properly so their not duplicated across modules and themes. 

Developers Note: A key thing I just learned as well is that you definitely need to make sure your theme Nuget dlls need to be matching the Orchard Core project's version. I had my theme on a build behind of OrchardCore.Theme.Targets and it did not render in the Theme's view of Orchard.

So the final piece is to run your Orchard project again. This will then allow you to select your theme in the Orchard Admin Dashboard : 

Once you enable your theme you can then browse to the front-end and see your theme in action!

Developers Note: This theme obviously will not look like yours when it is first run. We had already started building our new theme. You should see the Agency Theme as you normally would until you of course begin modifying templates and css.

I hope this explains on how to get a theme up and off the ground. The next part will detail how to add logging to your Orchard site so you can make sure you can easily debug any situation.

A Much Needed Performance Boost!

While developing themes it is important to understand what is going on in the background with the packaging of your files and keeping track of your own Gulp pipeline. One issue we were running into was that our builds were super slow. We couldn't figure out what was taking so long. After reviewing the detailed build output and consulting the Gitter feed, we realized the "node_modules" folder of our theme was getting packaged up into our theme assembly. This was causing things to slow down drastically. We solved the problem by adding the following lines to our theme .csproj file.

<None Remove="node_modules\**" />
<PackageAssetFiles Remove="node_modules\**" />

This instructs Visual Studio to not package up all the node_modules required by our theme. This is already happening via Gulp and is not needed. If you see any building performance, check for this.

Questions for the Cloud team? Please browse to our Contact Us page and let us know how we can help you get started with Orchard!

Learn about error logging in our third part to this series. Browse to Part 3 - Adding Logging to Orchard Core