The Media Theme feature will allow developers to host their themes in the Orchard Core Media Library, including templates and assets. This is useful in SaaS scenarios where you can't allow everyone to develop full Orchard themes, but still want to make the usual Orchard theming experience available to all users. Media Theme allows full theming of sites running on DotNest, the Orchard SaaS, too. Watch a demo video of it from the Orchard Community Meeting here.
We at Lombiq also used this SDK for the new Show Orchard website when migrating it from Orchard 1 DotNest to DotNest Core (see case study and the theme's source code).
Do you want to quickly try out this project and see it in action? Check it out in our Open-Source Orchard Core Extensions full Orchard Core solution and also see our other useful Orchard Core-related open-source projects!
There are two Orchard Core extensions and a targets extension in this project:
Lombiq.Hosting.MediaTheme.Bridge
: An Orchard Core module that enables the core logic required for hosting your theme the Media Library.Lombiq.Hosting.MediaTheme
: An Orchard Core theme that bootstraps the Media Theme logic using theLombiq.Hosting.MediaTheme.Bridge
module. With this theme active you can dynamically change the base theme from the Admin UI or using recipes.Lombiq.Hosting.MediaTheme.Targets
: Provides automatic Media Theme package creation in the project. Checkout its readme file.
To get started, you'll need to add Lombiq.Hosting.MediaTheme
and Lombiq.Hosting.MediaTheme.Bridge
NuGet packages to your web project. Set the Lombiq.Hosting.MediaTheme
as the active site theme from the Admin UI or recipe.
Once the theme is enabled, it'll look for templates and assets in the Media Library. Go to Media Library and create the _MediaTheme folder, where you can put shape templates inside the Templates folder (see limitations below), and assets inside the Assets folder.
Note that the .liquid
extension is not allowed in Media Library by default, which might be an issue with a few of your assets as well. Please update the Media settings as described here.
Media Theme supports base themes. First, enable the theme you want to use as a base theme. Then go to the Admin UI → Configuration → Media Theme page and select the one you want to use. You won't be able to update the base theme dynamically if the Media Theme is not active even if you are using the Media Theme logic provided by the Lombiq.Hosting.MediaTheme.Bridge
.
- Shape templates must be .liquid files. You can't use Razor templates.
- Shape template file names must be valid template, not template file names, i.e., may not contain
.
and-
characters (but use the_
and__
notation instead). Note that these don't just differ in the interchangeable characters but may also differ in the order of sections. E.g.[Stereotype]_[DisplayType]__[PartType]__[PartName]__[DisplayMode]_Display
is "Widget_Summary__ServicePart__Services__CustomMode_Display" as template name but "Widget-ServicePart-Services-CustomMode.Display.Summary.liquid" as a file name (note e.g. "Summary" being in a different location). See the docs for details. - The theme may include static resources in its wwwroot folder as any theme. You can also build those from source files like SCSS files as usual.
- The theme mustn't include any C# code apart from its
Manifest
. - Folders within the Views folder are not supported. It also means that MVC views can't be overridden or custom shape harvesters can't be used.
If you want to build a theme that'll eventually end up in the Media Library, you can develop it as usual but make sure the Lombiq.Hosting.MediaTheme.Bridge
module is its dependency. You can set a base theme for your theme from the Manifest
as usual too. Note that you won't be able to change the base theme dynamically from the Admin UI during local development.
You can proceed with developing your theme as you'd typically do: put the templates inside the Views folder and static resources inside the wwwroot folder; however, keep the limitations mentioned above in mind.
If you want to reference assets in your templates, you can use the /mediatheme/
prefix in URLs, like below:
{% assign 32pxIconUrl = "~/mediatheme/images/favicon-32x32.png" | href %}
{% link type:"image/png", rel:"icon", sizes:"32x32", href:32pxIconUrl, append_version:"true" %}
{% assign stylesPath = "~/mediatheme/styles/site.css" | href %}
{% style src:stylesPath %}
These use Orchard's resource manager and thus will also include a browser/proxy cache busting v
parameter that updates when you deploy a new version of your theme. This will ensure that everybody sees the current version of your site's styling. Note that while the Liquid style
and script
tags do this by default, for link
you have to add append_version
like above too.
Media Theme will translate this special ~/mediatheme path to either your local theme asset path or Media Library if the file exists. This way, you don't need to update your asset URLs in your templates one-by-one when deploying them. The ~
notation of virtual paths also comes in handy if you want to work with multiple tenants using URL prefixes locally, i.e. develop multiple Media Themes for multiple sites from the same solution.
If you are developing a theme for your DotNest site you can use the DotNest Core SDK that has everything prepared for you right away.
Instead of manually uploading files to the Media Library, install the Lombiq.Hosting.MediaTheme.Deployer
dotnet tool:
dotnet tool install --global Lombiq.Hosting.MediaTheme.Deployer
Then you can use it to build a deployment package of your theme:
media-theme-deploy --path [path of your theme] --base-id [base theme id] --clear [clear media hosting folder] --deployment-path [deployment path]
A specific example when run in the folder of your theme project:
media-theme-deploy --path . --base-id TheTheme --clear true --deployment-path .\Deployment
--base-id
is optional. If not provided, the tool will try to get it from the Manifest file, and if it's not defined there either, no base theme will be used.--deployment-path
is optional. Without it, the package will be exported to your directory root, for example C:\MediaThemeDeployment_04Aug2022230500.zip. The parameters also have shorthand versions:-p
,-i
,-c
,-d
, respectively.
You can then take the resulting ZIP file and import it on your site from the Admin UI → Configuration → Import/Export → Package Import. Everything necessary will be configured by the package. If you don't see this menu item then first enable the "Deployment" feature under Configuration → Features.
You can use Remote Deployment to accept packages created with the above-explained Deployer too via the internet, without manually uploading the ZIP file. You can use this to deploy your theme remotely from your local development environment or CI workflow too, for which we provide a ready-to-use GitHub Actions workflow.
Do the following to set up automated GitHub Actions deployments:
- Create a Remote Client on the Orchard admin UI → Configuration → Import/Export → Remote Clients. Use a suitable name and a strong, unique API key. If you don't see this menu item then first enable the "Remote Deployment" feature under Configuration → Features.
- Configure the Client API Key as a repository secret. While not strictly necessary, we recommend also storing the Client Name and Remote Deployment URL as secrets too.
- Add a workflow to the .github/workflows folder of your repository that executes the
deploy-media-theme
reusable workflow with some suitable configuration:
name: Deploy Media Theme to DotNest
on:
push:
branches:
- my-dev
paths:
- 'src/Themes/My.Theme/**'
jobs:
deploy-media-theme:
name: Deploy Media Theme to DotNest
uses: Lombiq/Hosting-Media-Theme/.github/workflows/deploy-media-theme.yml@dev
secrets:
URL: ${{ secrets.MY_THEME_DEPLOYMENT_URL }}
CLIENT_NAME: ${{ secrets.MY_THEME_DEPLOYMENT_CLIENT_NAME }}
CLIENT_API_KEY: ${{ secrets.MY_THEME_DEPLOYMENT_CLIENT_API_KEY }}
with:
theme-path: "src/Themes/My.Theme"
# You can leave out base-theme-id to get it from the Manifest, or to not use a base theme at all.
#base-theme-id: "TheBlogTheme"
If you want to use a different CI system or would like to run remote deployment from the command line otherwise, use the --remote-deployment-url
, --remote-deployment-client-name
, and --remote-deployment-client-api-key
parameters. See this PowerShell script for an example:
$switches = @(
'--path', '.'
'--remote-deployment-url', 'https://localhost:44335/OrchardCore.Deployment.Remote/ImportRemoteInstance/Import'
'--remote-deployment-client-name', 'demo'
'--remote-deployment-client-api-key', 'Password1!'
)
media-theme-deploy @switches
Bug reports, feature requests, comments, questions, code contributions and love letters are warmly welcome. You can send them to us via GitHub issues and pull requests. Please adhere to our open-source guidelines while doing so.
This project is developed by Lombiq Technologies. Commercial-grade support is available through Lombiq.
If you want to publish Lombiq.Hosting.MediaTheme.Deployer
to test it during local development, then do the following:
- Pack it into a NuGet package by running
dotnet pack
in the project's folder. - Uninstall the tool if you have it installed already:
dotnet tool uninstall --global Lombiq.Hosting.MediaTheme.Deployer
. - Install the local version (note that without a version specified, it'll be published as v1.0.0):
dotnet tool install --global Lombiq.Hosting.MediaTheme.Deployer --add-source .\nupkg --version 1.0.0
. - Now
media-theme-deploy
will use the development version.