Secrets module, Cookie based dark mode theme - This week in Orchard (10/01/2021)

Gábor Domonkos's avatar
Admin UI, Documentation, This week in Orchard

We start this year by showing you the latest updates of the Dark mode of the admin UI. After that, you can read about how can expose your Lucene or SQL queries through GraphQL! Finally, we will check out the latest improvements to the Secrets module!

Orchard Core updates

Dark mode V2 (cookie based)

A few weeks ago we mentioned that now you can use the dark mode for your admin theme. The only thing you have to do is to go to Configuration -> Settings -> Admin and check Enable dark mode admin theme. The new version of dark mode contains several improvements:

  • Cookie based settings storage.
  • Use only one CSS to prevent flickers and animations when switching from light to dark mode and vice versa.
  • Use data-theme on HTML element.
  • Fixing several modals.
  • Fix GraphiQL styles (Codemirror global styles conflict).

But what does cookie based mean? Find the DarkModeService.cs file in the OrchardCore.Themes project and check out the IsDarkModeAsync async method in it. As you can see, there is an adminPreferences cookie collection, that contains a darkMode boolean property. If it's true, that means the dark mode has been applied to the admin theme.

The new DarkModeService

And here comes the trick! If you check out the first few lines of the Layout.cshtml file of the admin theme, you will see that the code checks if the dark mode is currently enabled or not and puts the CurrentTheme value into the data-theme data attribute.

The Layout.cshtml of the admin theme

Tutorials page in the documentation

Many external resources are available in order to teach you how to develop with Orchard Core and keep you informed with the latest news and the goal of the Resources page is to give you a nice overview of these resources. Now you can find a new Tutorials page that lists some content that you can use to learn Orchard Core. Here you can find our Dojo Course 3 video series or the Orchard Core Training Demo module!

Tutorials page in the Orchard Core documentation

Custom query schema fix and documentation

Method BuildSchemaBasedFieldType inside LuceneQueryFieldTypeProvider.cs and SqlQueryFieldTypeProvider.cs was wrong because official JSON schema should look something like this:

"type": "object",
"properties": {
"firstName" : {
"type" : "string"
"age": {
"type": "integer"

The line where code tries to get type specifically child["type"] will throw an error of System.InvalidOperationException: 'Cannot access child value on Newtonsoft.Json.Linq.JProperty.'.

foreach (var child in properties.Children())
var name = ((JProperty)child).Name;
var nameLower = name.Replace('.', '_');
var type = child["type"].ToString();

The fix was something along the lines of and the properties key should be lowercase.

foreach (JProperty child in properties.Children())
var name = child.Name;
var nameLower = name.Replace('.', '_');
var type = child.Value["type"].ToString();

You can find nice documentation here that tells you how you can expose queries through GraphQL.

Documentation about how to expose queries through GraphQL


Secrets Module

We mentioned the latest updates regarding secret management back in September and now here comes the continuation of this upcoming feature. If you haven't known about it yet, you should definitely check out that post and the two recordings on YouTube. So, let's see what we are talking about exactly!

The idea here is to extend some of the places that we can use to store secrets. For example, let's navigate to the Email settings (Configuration -> Settings -> Email) and say we require credentials for authentication. And of course, we need to define a user name and a password. The password is get stored with data protection. But if we export this to a production server where the data protection keys are different, the setting will no longer work and you can get an exception when you would like to use it. As you can see on the screen, the concept here is to have a secret where you select which secret you would like to use. We have already defined one called email, let's select this one.

Email settings with password secret

We managed that secret and the value of it under Configuration -> Secrets. Here we can select where we would like to store this secret, which can be the Database Secret Store or the Configuration Secret Store. But if you enable the Azure KeyVault Secrets Store feature, you can use the KeyVault store too.

Create a new text secret for storing the email password

Normally when we have a form, we use an HTTP Request event to drive the form to a workflow. Let's create one Workflow, call it Form Submit and add an HTTP Request event to it. Normally what we have in the query string is a token here which is protected with data protection but we could have a little problem with it. When you use this in a Form widget and you have moved the form to a production server, it doesn't work because the token was no longer valid because it is was stored using a local data protection key. But we have a solution for that too! Here you can notice one new option called HTTP Request Event Secret. You can just simply type a preferred name to the secret and hit enter, which will create the new secret for you.

HTTP Request event with event secret

Now let's create a form. If you set up your site with the Blog recipe, you can just simply enable the Forms module and create a new Page. Add the Form widget to the FlowPart where you can see the same picker that we can use to select the given secret that we would like to use. If you pick a secret, you don't need to specify the action (the URL to submit the form to) because it is stored in your HTTP request event secret and that will override the specified action value of the form.

Form widget with the HTTP request event secret

If you navigate to Configuration -> Secrets, you can check out the details of the formsubmitted secret that we have just created. The difference here is that now you have a picker here that lists all the workflows that have an HTTP Request Event as a starting activity. By using that picker you can assign this secret to another workflow if you would like to.

Edit a secret that contained in a workflow type

But we are just scratching the surface of this feature and haven't talked about anything about how you can import/export your secrets using deployments plans. If you are interested in more, don't forget to check out this recording on YouTube!

News from the community

Our full Orchard Core tutorial series, the Dojo Course 3 is here!

After a long wait, the new Orchard Core version of our legendary Dojo Course tutorial series is here, the Dojo Course 3!

Are you a newcomer and want to learn Orchard Core from the ground up, both from a user's and a developer's perspective? Are you somewhat familiar with Orchard Core but would like to get up to speed and become an Orchard pro? Look no further, check out Dojo Course 3! Dojo Course 3 guides you from the very basics of Orchard Core all up to be able to write your own themes and modules, utilizing various APIs of Orchard.

If you're looking for our previous Orchard 1.x tutorial series check out Dojo Course 2.

Orchard Dojo Newsletter

Lombiq's Orchard Dojo Newsletter has 183 subscribers! We have started this newsletter to inform the community around Orchard with the latest news about the platform. By subscribing to this newsletter, you will get an e-mail whenever a new post published to Orchard Dojo, including This week in Orchard of course.

Do you know of other Orchard enthusiasts who you think would like to read our weekly articles? Tell them to subscribe here!

If you are interested in more news around Orchard and the details of the topics above, don't forget to check out the recording of this week's Orchard meeting!

No Comments

Add a Comment