Our blog contains the activity stream of Orchard Dojo: general news, new resources or tutorials are announced here.

Mastering Lucene Query Syntax in Orchard Core, How to quickly spin off your Orchard Core site? - This week in Orchard (12/06/2026)

Have you heard that we rebuilt DotNest.com using reusable landing page sections, Tailwind 4 without Node.js, and AI-assisted workflows?

Nick Jackson demos an Electron desktop app that lets you spin up Orchard sites fast! Choose your modules and themes, manage recipes, all without touching an IDE.

Sébastien Ros introduced support for async JS evaluation using Jint's new async method, enabling workflows and other JS-dependent features to run without blocking.

We're excited to open registration for Orchard Harvest 2026! Secure your spot today for the early bird pricing and get ready to level up your skills!

Latest tutorials

Featured tags

AI
IIS
SMS
MCP
API
SEO
All tags >

Orchard Core Workshops

Start Date: 6/20/2020 4:00:00 PM End Date: 6/27/2020 10:00:00 PM We always do some presentations at the Orchard Harvest conferences, but 2020 was different. Because of the pandemic, the community cannot organize Harvest, but we don't want to skip the presentations. Thus let us introduce the Orchard Core Workshops! The goal here is for the contributors of Orchard Core to hold some unique online workshops between May and September 2020. So even with Orchard Harvest postponed we'll get some new learning events. Lombiq's developers also gave two workshops, on using the admin Ul of Orchard Core and module development. On June 20, we did a workshop about how to use the admin UI of Orchard Core. On that day, we created custom content types, a custom widget, and placed that widget in a layer that has a custom layer role. We saw how we can enable/disable modules and themes, and created workflow types to send the content of a contact form to site owners. For that, we used the Forms module of Orchard Core. Finally, we saw how to use the OpenID server of the CMS and how to authenticate users using JWT tokens to use the content APIs of Orchard Core. We started with an overview of the Orchard Core source code on June 27. After that, we used data migrations to create custom content types and fields. We used Razor to display the different templates of the custom content to the users. We saw the JSON schema of the content types and the way Orchard Core is storing the data in the document DB. We also created a new index table and by using that table we wrote queries to return the data from the DB. What do the attendees say about the results of the training? Thank you for the great information, clear explanations, and openness to answer any questions asked. The workshop was very useful and I'm sure I'll save a lot of time thanks to it. Thank you very much. Excellent workshop content, teaching delivery and demo examples! This workshop will truly help people jumpstart their Orchard Core skills. Do you want to quickstart with Orchard Core? Book a training with us!

Tabs, Cards, and Columns for the Admin, RenderTitle option - This week in Orchard (03/07/2020)

Heads up, several improvements coming this week! Editor shapes now support grouping placement, which allows you to group editor shapes, to create a variety of content editor layouts. The Title Part now has a Render Title option to show or hide the value of the Title. And last week we did an Orchard Core workshop about module development. Check out our current post for more! Orchard Core updates TitlePart with RenderTitle option and Placement for Form, Label Let's say you set up your site using the Blog recipe and want to edit the content definition of the Blog Post. If you edit the definition of the attached Title Part, you will find a new option that you can use called Render Title. With this option, you can enable or disable rendering the value of the Title Part in Detail and Summary display types. The Blog recipe using the TheBlogTheme by default where we override the content of the Blog Post (Content-BlogPost.liquid) and displaying the DisplayText of the content item whether the Render Title option is on or off. So, to see this in action we should use a theme where there is no override for the Blog Post content items. Let's navigate to Design -> Themes and make the Default Theme as the current for now. After that, you will be able to see the differences. The upper window here is about to render the title, but under that, you can see the default blog post without displaying the value of the title. We have some content types where is no need to display the title by default. These types are the Form and the Label. If you check the migration of the Label for example you will see how you can use the TitlePartSettings to hide the title by default. Fix jsonparse Liquid filter to supports arrays The jsonparse Liquid filter converts a JSON string to a JObject. This can be useful to build collections and iterate over the values in Liquid. Now, this filter is about to support arrays. To do that the community had to use the JToken.Parse method instead of the JObject.Parse one as you can see in the JsonParseFilter class. Add menu display text (differentiator) classes to menu shapes When using multiple menus on a site it is possible to do a lot of the styling with CSS, which can avoid having many, many templates. Now Orchard Core will add the menu differentiator (which is calculated from the display text) as an additional class on the menu. So out of the box, you will get: class="menu menu-main-menu". Demos Tabs, Cards, and Columns for the Admin We are able to use placement to move some of the fields/parts into a tab in the admin area. The new thing is now you can use Bootsrap Collape to organize your content into cards. And now you can also move fields into columns, in that case, you can have a Media Field near to the HTML Body Part for example. But after this intro let's go deeper and see some examples of placement. Modifier for tabs remains #, but now supports ; before as a position modifier for the tab grouping. Modifier for cards is %, also supports ; as a position modifier. Modifier for columns is |, supports ;, and _ as a column modifier, _9 will be applied as col-md-9 automatically, or _lg-9 which will be applied as col-lg-9. _9 should be sufficient for most, as it will by default break at md. ; must be immediately after , whereas : is the shape placement, and applies anywhere in the placement string. So, in nutshell the normal tab modifier is a #, the card modifier is a %, and the column modifier is a |. The column has a name and another modifier that allows you to say how big you want the column to be. Now try out these in your Orchard Core site! We will use the Orchard Core source to set up a site and we will modify the content of the placement.json file in the OrchardCore.Contents module. In the following example we place the MediaField_Edit shape in a tab called Media, and position the Media tab first, and the Content tab second. The Html Field goes first in the Content tab and the rest goes under the Html Field. Let's play with this a little bit more! Now we place the MediaField_Edit shape in a card called Media, and position the Media card first, and the Content card second. And lastly, we are playing a little bit with the columns. In the following example we place the MediaField_Edit shape in a column called Media, and position the Media column first, and the Content column second. We also specify that the Content column will take 9 columns, of the default 12 column grid. By default, the columns will break responsively at the md breakpoint, and a modifier will be parsed to col-md-9. If you want to change the breakpoint, you could also specify Content_lg-9, which is parsed to col-lg-9. If you want to know more check out the official documentation and don't forget to watch the video about the new features of the placement! News from the community Orchard Core RC 2 on ASP.NET Blog You can find a new blog post in the ASP.NET Blog that telling you the Orchard Core Release Candidate 2 now available! In this post you will learn how to create an Orchard CMS website using the templates, you will see the notable improvements and you can check out the development plan of Orchard Core! Module Development - Orchard Core Workshop 4 We had some great crowd at the Orchard Core module development workshop on Saturday, thanks all for coming! Would you like to attend a workshop too? Other community members will hold ones soon: https://orchardcore.net/workshops. Are you interested in something else? Leave a comment below! Orchard Dojo Newsletter Now we have 151 subscribers of the Lombiq's Orchard Dojo Newsletter! 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! There will be no This week in Orchard post next week because of vacation, so see you in two weeks!

CodeMirror improvements, 100th This week in Orchard - This week in Orchard (26/06/2020)

The 100th This week in Orchard is here! In this post you could see a great demo about the CodeMirror improvements, we mention the updated Send Email activity, the new sample in our Orchard Core Training demo module about how to do unit testing, and many more! Thanks for joining us for the 100th time! Orchard Core updates Add Reply-To Header to Workflow EmailTask activity When you send an email to a subscriber and they click Reply, the reply message is typically sent to the email address listed in the From: header. A Reply-To address is identified by inserting the Reply-To header in your email. It is the email address that the reply message is sent when you want the reply to go to an email address that is different than the From: address. If you want to configure the Reply-To header in your EmailTask activity now you can do it! Just add the Send Email task to your workflow and use the updated editor of the activity! Allows ZoneShapes to be overridden If you were trying to override the ContentZone implementation in ZoneShapes.cs to get some different behavior for some tabbed shapes, it won't work, because it was not attributed with [Feature(Application.DefaultFeatureId)]. Just a note here: the [Application.DefaultFeatureId] attribute is used to allow core shapes to be overridden. Demos CodeMirror improvements CodeMirror in Orchard Core was a little bit outdated because it was not updated from quite a long time ago. All the views in Orchard Core have been changed that is using CodeMirror and now there is a new style called codemirror that is registered in the ResourceManifest.cs of the OrchardCore.Resources module. And that's not all, here you can see several other add-ons that are included by default. Here you can see the content of the TextField-CodeMirror.Edit.cshtml file. But let's see in action what can you do with these add-ons! When you are using HTML, you will have auto-close for the tags. If your text is too long, it will wrap the lines and the currently active line is being highlighted. And these features are provided by the newly added CodeMirror plugins. In this GIF you can see a Text Field and an HTML Field. We set the editor option to Code Mirror for the Text Field and Standard for the HTML Field. And as you could saw in the code above, you can turn on or off these features just by setting the values of the editor. If you don't want to have an auto-close tags feature, just simply say autoCloseTags: false. If you want to know more about the CodeMirror improvements, don't forget to check this recording on YouTube! News from the community Unit Testing in the Lombiq Training Demo for Orchard Core We added a new service and tests to it to learn a bit of unit testing! First, we'll create a service that we'll then later test in a test project. This service won't be used anywhere else, it's just an example to be tested. Why a service? Services are where usually most of the complex logic of an Orchard-based web app goes. You can test anything as long as you've written it in a testable way (by, for example, not utilizing hidden dependencies but injecting them all), you can write tests for controllers, drivers, background tasks, you name it. However, we think that unless you're aiming for 100% test coverage it's best to focus your unit and integration testing efforts on services. Then, the rest of the app can further automatically be tested via e.g. UI tests. Check out the service that will be tested here and here come the tests for it! This week in Orchard for the 100th time! We started our This week in Orchard series to inform our readers with the latest news and improvements around Orchard 1.x and Orchard Core. In this series we try to cover the most important features of the CMS and of course from time to time we are looking under the hood and show you the different code changes. But this series is not just for developers. We also want to target the super users of Orchard Core to know and be able to use every feature of it by learning the usage of the admin UI. Last year we started to upload Orchard Core demos in separate videos from the weekly podcasts to be able to find the given feature that you are really interested in as quickly as possible. We have also created a playlist for it on YouTube that contains more than 30 videos for now! And don't forget our Orchard Nuggets series that we have started in December last year! In that series, we answer common Orchard questions, be it about user-facing features or developer-level issues. Check out these posts for bite-sized Orchard tips and let us know if you'd have any questions! We hope that you like our series and find it useful! Thanks for reading us! 4000 stars on GitHub In GitHub, you can star repositories and topics to keep track of projects you find interesting and discover related content in your news feed. Starring a repository also shows appreciation to the repository maintainer for their work. Many of GitHub's repository rankings depend on the number of stars a repository has. And we are proud to present that on June 22, the Orchard Core repository reached 4000 stars and it's still growing! Congratulations on the community! Using the admin UI of Orchard Core - Orchard Core Workshop 3 Last Saturday we did a workshop with 11 attendees about how to use the admin UI of Orchard Core! This Saturday we are gonna show you how to develop a module. Are you looking to get up to speed with Orchard? Check out the workshops' details on the Orchard Core homepage! Orchard Dojo Newsletter Now we have 151 subscribers of the Lombiq's Orchard Dojo Newsletter! 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!

Orchard Core RC 2 release, Visual Studio code snippets - This week in Orchard (20/06/2020)

We are thrilled to announce that Orchard Core RC 2 is now available! Check out this post to know everything about the latest release of Orchard Core. This week we will also show you a great demo about the brand new code snippets for Visual Studio, which will make your Orchard Core development more efficient! Orchard Core updates User menu as a shape There is a user menu at the top-right corner of the admin theme. In this menu, you could see the name of the logged-in user, and here is a button that you can use to log off. In the past, if you would like to change the look and feel of this menu, you had to override the whole Layout.cshtml file of the theme, because this was the file where we rendered the menu. From now there is a new shape called UserMenu, which is just about containing that piece of content that is responsible to display the user menu. So, if you would like to override that menu, just create a new Razor file in your admin theme called Usermenu.cshtml. Reviewing encoders usages There was a bug when you are sending an email, where your chars might be JSON-encoded. Let's say that you were using workflows to send a bunch of emails and in this case, Liquid is used to construct the body of the emails. You can have input data like "Country": "België" that you are rendering with {{order.UserProfile.Country}}<br />. However, workflow Liquid evaluator is using JavaScriptEncoder rather than HtmlEncoder. This results in an email with Belgi\u00EB in the body. By default when ASP.Net Core injects it's HTML helpers, it will encode all the Unicode chars. If you have any Unicode char, it will be encoded, which means you will not see the actual characters even if the browser supports Unicode characters. To prevent that you can configure the WebEncoderOptions in your web application to say that the TextEncoderSettings will accept all Unicode ranges. That means it will don't encode anything that is based on Unicode ranges. It will still encode HTML, but any char that is a Unicode char will still be returned as a Unicode char and not as an HTML entity or a URL entity or a JSON entity and so on. It's better to just opt-in for the ranges you want, but in this case, it's just a sample code to show you how you can do that. If you look at your source code when you use such chars, you will see you will have lots of HTML entities instead of the chars you wrote. Once you do that, it could be the actual chars. And also, when you are using an encoder, just resolve it in the constructor, because the encoders are registered in the DI using the mentioned arguments. If you don't want to use the arguments (TextEncoderSettings) for a custom piece of code, then don't resolve the encoder, use HtmlEncoder.Default. For more information, check out the documentation! Demos Orchard Core code snippets for Visual Studio Orchard Dojo Library is a portable package of coding and training guidelines, development utilities. These are also part of the best practices and guidelines we use at Lombiq. This library contains Visual Studio code snippets to quickly generate code in some common scenarios during the Orchard Core module and theme development. To effectively use this collection of VS snippets just point the Snippets Manager to where you cloned or downloaded this folder. To do this go under Tools → Code Snippets Manager → select the C# language → Add and Add the whole folder. For Razor snippets to also work select the HTML Language and do the same. Do note that Razor snippets will only be suggested when you hit Ctrl + space first. You can download the snippets from this GitHub repository. For example, if you type oc, the IntelliSense in Visual Studio will show you the suggestions. In the screen below you could see the code that is generated if you are using the ocmigrations snippet. That is about generating a class that implements the DataMigration abstract class and you will also get a Create method, that is the minimum requirement if you would like to add a migration. But that's not all! Check out this recording to see more snippets in action! News from the community Orchard Core RC 2 released We are thrilled to announce that Orchard Core RC 2 is now available! There is a new blog post in Orchard Core Blog that shows you the new features of the latest release. Here you could find the content localization support, and pre-configured localized Setup experience, the improved block content management experience, sitemaps management, and Azure support improvements. The NuGet packages are also updated on nuget.org. It's still prerelease of Orchard Core (the last one), so if you would like to update the packages in your solution, don't forget to put a tick in the Include prerelease checkbox if you are using Visual Studio. And don't forget the Roadmap! Here you could see a list of the fully or partially implemented features and the plans for the future releases! Upgrade your solution to RC 2 now! Feel free to drop on the dedicated Gitter chat and ask questions! Lombiq Utility Scripts Our Utility Scripts project is now open source! Many scripts for Orchard Core, Orchard CMS, Azure, SqlServer development. E.g. quick Orchard Core solution init, reset/reinstall. Head to the GitHub repository to see all the included scripts! Lombiq's Open-Source Orchard Core Extensions is now updated to RC 2 Looking for some useful Orchard Core extensions? Here's a bundle solution of all of Lombiq's open-source Orchard Core extensions (modules and themes). This repository contains the Helpful Libraries for Orchard Core that includes DateTime Libraries with TimeZone conversion, Localization Libraries and many more! But it also contains the Vue.js module for Orchard Core, the Training Demo module and that's not all of it! A new blog post about Orchard Core Nuno Cancelo is a software Engineer, eager to learn, and even more to share knowledge. Last week he published a great post about the basics of Orchard Core and he planned to publish 3 more parts where he will write about how you can create a module, a recipe, and a theme. Don't hesitate and start this journey now! Orchard Core workshops The contributors of Orchard Core will hold some unique online workshops in the coming months, between May and September 2020. So even with Orchard Harvest postponed due to the coronavirus pandemic we'll get some new learning events. Lombiq's developers will also give two workshops, on using Orchard from the admin UI and on developing a module. Are you looking to get up to speed with Orchard? Check out the workshops' details on the Orchard Core homepage! Orchard Dojo Newsletter Now we have 148 subscribers of the Lombiq's Orchard Dojo Newsletter! 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!

OpenAPI, Swagger, Taxonomy Localization - This week in Orchard (12/06/2020)

This week we prepared with two new demos: the Taxonomy Localization and the Orchard Core OpenAPI Code Generation Tools based on NSwag! But before doing that, let's see the latest changes that will be added to the RC2 release of Orchard Core that is now really just a few days ahead! Orchard Core updates Refactor Blog recipe to have fewer required fields You may found that creating blog posts in Orchard Core using the Blog recipe could be not very user friendly. When you create a new blog post, you have to provide tags and select the category for the posts, however, you will also need to add a banner image for it. These are all required fields, without these, you cannot publish your post. But from now these fields are optional and the Markdown editor is just below the Title and the Permalink, so you don't need to scroll down to start typing your new exciting post! Add ConfirmationEmailSubject to RegisterUserTask When you are dealing with workflows you can find a task called Register User. This is about register a user from a form field, meaning that the activity is getting the request body as a form to get an IFormCollection and try to get the UserName and Email values from that. If everything goes fine, the task will register the user and if you edit the activity, you will find some more stuff to set up! Here you can say to send a confirmation email to the user with a given subject and you can also use a template for the confirmation email if you want! How to contribute to the Orchard Core documentation? Have you ever thought about contributing to the Orchard Core documentation, but you cannot find a line about how to do that? Well, here comes the good news! From now, you will find a new guide in the documentation that tells you everything that you need to know to add your great getting started guides, tutorials, and everything to the documentation! Thank you for doing that! Change content API permissions You want anonymous users to be able to view your site, view your page/content item and it would just show what the layout is or the view is. But you might not want anonymous users to retrieve the full content item JSON payload, because it might shows some properties and metadata that you don't want to expose. For that, you could use the custom permission called GetApiContent that you can assign to specific roles and this is not assigned to anonymous users by default. Now, this permission was renamed to AccessContentApi and protects all /api/content methods. If you don't want a user to see all the fields, just don't grant access to the APIs at all, hence the GetApiContent permission is not required as a separate one. This will also protect POST that currently returns the full content. And one more thing: the GetApiContent was already added to the Authenticated role. Now it's removed from that role as being authenticated should not grant access to all fields. Prevent array duplication when merging existing content When you do Merge using JSON.Net it will just merge the different arrays. In some cases, it's not what you want. If you want an array to be replaced (for example an array of tags) then it will just add a new tag to that array and not replacing the array with a new array. On the POST operation of the API, you just want to replace the value and the PATCH operation should be the one that merges different arrays in this case. So, the Content ApiController needs to use ArrayHandling.Replace when updating existing content, or array values are duplicated. Here you can see the changed code and here comes the UpdateJsonMergeSettings: private static readonly JsonMergeSettings UpdateJsonMergeSettings = new JsonMergeSettings { MergeArrayHandling = MergeArrayHandling.Replace }; Demos Taxonomy Localization Have you ever wondered how to localize your taxonomy terms in Orchard Core? Well, it could be hard to do it for the first time, but if you are watching the following recording you can get some tips and tricks to reach your goal faster! Orchard Core OpenAPI Code Generation Tools based on NSwag Head to GitHub and clone the master branch of the ThisNetWorks.OrchardCore.OpenApi repository. Make sure that the ThisNetWorks.OrchardCore.OpenApi.Sample project is your starting project then just simply build and run the solution. When setting up your site don't forget to use the Open API Sample recipe to enable the needed modules and theme. If you navigate to https://localhost:44300/swagger, you will see the endpoints that are available in Orchard Core and a sample controller named Foo that comes from the ThisNetWorks.OrchardCore.OpenApi.SampleModule module. Here you can make queries on them and now we will also get schemas that are generated using the NSwag toolchain! Let's check for example the BlogPostItemDto! Now we can use those! The samples folder contains a console client that you can use to try the endpoints. You can simply open the solution with Visual Studio (ThisNetWorks.OrchardCore.OpenApi.ConsoleClient.sln) and fire up the ThisNetWorks.OrchardCore.OpenApi.ConsoleClient project. This is about calling the endpoints by using a static HttpClient. Open the Program.cs file and check the first few lines of the Main method here. You could see that we are getting a content item by the 4qnhdhv3z54xk4fg4tdfke76c9 and we get the content of the content item in the FooTextItemDto object. The content item with the mentioned ID is a content item of the Foo text content type, which has got one Text Field attached, named Foo Field. Our client modifies the text of this field and making a POST request to send the updated data to Orchard Core. Now if you read back from the API you will get the updated content item with the new text in the Foo Field. But there is a lot more than that! You can see that you can get the RecentBlogPosts Lucene query and use the response data, or do other Lucene queries (like give me all the blog posts) and so on. If you are interested in it, there is also a TypeScript client (tsClient.ts) which has the same kind of classes and can be used directly from TypeScript. Of course, before doing that, you have to do the authentication, get the token, and so on. For that, you have to enable the OpenID module and configure it. It also comes with the recipe by default. The back-end, the Swagger is using Authorization Code Flow, and the console client is using Client Credentials Flow. The client app has a specific API role because it's relevant to just give very limited and specific access to the system. And that's not all of it! If you need more details about the project, don't forget to check the recording on YouTube! News from the community Orchard Nuggets: How to access services from another tenant in Orchard Core? Do you run a multi-tenant Orchard Core site? Have you ever wondered how you can cross tenant boundaries? We show you the code! Check out our latest Orchard Nugget post for more! Check out the other posts for more such bite-sized Orchard tips and let us know if you'd have another question! Updated Dojo library We've updated the famous Dojo Library to Orchard Core! Orchard Dojo is a portable package of coding and training guidelines, development utilities. Check out our updated library and start learning today! Orchard Core workshops The contributors of Orchard Core will hold some unique online workshops in the coming months, between May and September 2020. So even with Orchard Harvest postponed due to the coronavirus pandemic we'll get some new learning events. Lombiq's developers will also give two workshops, on using Orchard from the admin UI and on developing a module. Are you looking to get up to speed with Orchard? Check out the workshops' details on the Orchard Core homepage! Orchard Dojo Newsletter Now we have 146 subscribers of the Lombiq's Orchard Dojo Newsletter! 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!

How to access services from another tenant in Orchard Core - Orchard Core Nuggets

The multi-tenancy feature of Orchard Core is great: A tenant is basically a subsite with its own independent content and configuration, under its own domain or URL prefix. You can use tenants to e.g. host websites for multiple customers of yours from a single Orchard Core app. The sites won't know anything about each other but they'll run from the same app built from the same codebase, and have access to the same modules and themes. This makes maintaining such sites very efficient, both for hosting and for development. What if you want tenants to be not that isolated though? What if there is certain content or configuration that you actually want to share among tenants or some functionality that you want to centralize on one tenant? You can use the APIs we show below to cross tenant boundaries and use any service from another tenant! Back in the day, this was also possible with Orchard 1. What we'll see here is a simple controller (just for the sake of easy demonstration, you can do the same thing anywhere). In the Index action, we'll fetch content items from another tenant with the IContentManager service that you already know. This is just an example though, really you can access any other service as well. public class CrossTenantServicesController : Controller { private readonly IShellHost _shellHost; // We'll need IShellHost to access services from a currently running shell's dependency injection container // (Service Provider). public CrossTenantServicesController(IShellHost shellHost) => _shellHost = shellHost; // A simple route for convenience. You can access this from under /CrossTenantServices?contentItemId=ID. Here // ID needs to be a content item ID that you can get e.g. from the URL when you open an item to edit from the // admin (it looks something like "4da2sme18cc2k2rpdgwx3d4cwj" which is NOT made by a cat walking across the // keyboard!). [Route("CrossTenantServices")] public async Task<string> Index(string contentItemId) { // Even if you don't create tenants, there will still be a single tenant in an Orchard app, the Default // tenant. For all other tenants you create you can provide the technical name. // In this example, we'll access content items from the Default tenant but this works for any tenant of // course. Create a tenant in your app (enable the Tenants feature and then create it from under // Configuration / Tenants), enable the Training Demo on it too and check out how this works there! // First you have to retrieve the tenant's shell scope that contains the shell's Service Provider. Note // that there is also an IShellSettingsManager service that you can use to access the just shell settings // for all tenants (shell settings are a tenant's basic settings, like its technical name and its URL). var shellScope = await _shellHost.GetScopeAsync("Default"); // We'll just return the title of the content item from this action but you can do anything else with the // item too, like displaying it. string title = null; // With UsingAsync() we'll create a block where everything is executed within the context of that other // tenant. It's a bit similar to being inside a controller action, but remember that all of this is running // on the Default tenant, even if you're looking at it from another tenant you've created. await shellScope.UsingAsync(async scope => { // You can resolve any service from the shell's Service Provider. This serves instead of injecting // services in the constructor. var contentManager = scope.ServiceProvider.GetRequiredService<IContentManager>(); // We can use IContentManager as usual, it'll just work. // Note that for the sake of simplicity there is no error handling for missing content items here, or // any authorization. It's up to you to add those :). var contentItem = await contentManager.GetAsync(contentItemId); // DisplayText is what you've already learned about in PersonPartHandler. title = contentItem.DisplayText; }); return title; } } Pretty neat, right? If you'd like to play with the code and see it in action check it out in our Training Demo module! Note that a shortcut to achieving this is now part of our Helpful Libraries too! Did you like this post? It's part of our Orchard Core Nuggets series where we answer common Orchard questions, be it about user-facing features or developer-level issues. Check out the other posts for more such bite-sized Orchard Core tips and let us know if you have another question!

Custom Settings, Short Codes - This week in Orchard (05/06/2020)

This week we are going to see some code and code samples that could be good to know when developing your Orchard Core application. But we are not just doing that! We will also show you a nice demo about how to create custom settings in Orchard Core just using the admin UI without typing a line of code! Let's start our journey! Orchard Core updates Adding branding assess to docs You can find a new page in the documentation called Orchard Core Branding where you can find graphics assets for Orchard Core's branding. Allow classes by default with the HTML sanitizer Last week we saw the new HtmlSanitizerService in Orchard Core that is responsible for sanitizing the HTML code. Now when you are adding Orchard CMS to your application by calling the AddOrchardCms extension method, it will call the AddHtmlSanitizer extension method that will set up the HtmlSanitizerOptions. And it will add the class as an allowed HTML attribute to the sanitizer. Change [media] short code to Add IServiceProvider to shape Creating Created contexts The ShapeCreatedContext didn't have a ServiceProvider as the ShapeDisplayContext do. This means services resolved through an IShapeTableProvider with OnCreated either need to be resolved through the constructor, which causes disposed exceptions, and scope capturing, or by directly accessing the ShellScope.Services. But what does it mean in practice? Let's say you inherit from the ShapeFactoryEvents abstract class that implements the IShapeFactoryEvents interface and you want to add some additional logic after your shape has been created. In our case, we would like to show a new notification when a shape has been created. For that somehow we need to resolve the INotifier and the IHtmlLocalizer. To achieve our goal we can just simply get the ServiceProvider from the ShapeCreatedContext and implement the business logic. Update Fluid and YesSql dependencies Now you can track objects that have been saved and then modified again after a flush in YesSql. In Fluid everything is a decimal now and not a double because when you do 10 - 0.9 you want to see 9.1 and not 9.000009. Demos Custom Settings You may know that you can create custom settings on Orchard Core by writing some code: implement the class to store the properties, add a SectionDisplayDriver to it, then pass your class using a ViewModel to a Razor page. You may also need to implement the INavigationProvider interface to be able to reach your setting in the admin UI from a new option on the menu. But you can also create custom settings without the need of writing any line of code in a very easy way. Do you want to know how? First, we set up the site using the Blog recipe, but you can choose any of the built-in ones, you just make sure that the Custom Settings feature is enabled. Now, navigate to the admin UI of Orchard Core and select Content -> Content Definition -> Content Types and create a new content type. Let's call it Company Brand. This setting is about storing some related information about a company. The company will have a name and a logo. For that, we will attach a Text Field and a Media Field to our content type. You have to do two things to make this content type a custom setting: Disable Creatable, Listable, Draftable and Securable metadata as they don't apply. Set the stereotype of the content type to CustomSettings. And that's all! Congratulations, you created a custom setting in Orchard Core without writing any code! If you don't believe that, head to Configuration -> Settings where now you can already see a new option called Company Brand. If you click on it, the CMS will show you the editor of your content type just as you set it up when you defined the content definition of your type. Now you can work with this custom setting as you would work with the ones that you create using code. Don't forget, the documentation of Orchard Core contains a great section about custom settings. If you prefer videos, you can also check out how to create custom settings just using the admin UI on YouTube! News from the community Check your language in the Setup screen of Orchard Core With the next public release so close, please check that your language looks perfect in the Setup screen. Some culture files are only missing a few strings: Greek (1) Japanese (3) Persian (1) Polish (3) Russian (3) Spanish (1) Turkish (8) If you speak one of the listed languages, just fire up a new Orchard Core site and select your language using the picker in the top-right corner of the screen. If you find any incorrect translation or some weird string, just leave a comment below! Orchard Core workshops The contributors of Orchard Core will hold some unique online workshops in the coming months, between May and September 2020. So even with Orchard Harvest postponed due to the coronavirus pandemic we'll get some new learning events. Lombiq's developers will also give two workshops, on using Orchard from the admin UI and on developing a module. Are you looking to get up to speed with Orchard? Check out the workshops' details on the Orchard Core homepage! Orchard Dojo Newsletter Now we have 146 subscribers of the Lombiq's Orchard Dojo Newsletter! 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!

Lombiq Helpful Extensions, HTML script sanitizer - This week in Orchard (30/05/2020)

Have you ever had a hard time implementing the migration files of your content types that you have constructed using the admin UI? Let us show you the Code Generation Helpful Extensions that generate the C# code for you in a click from the admin UI! This week we are also showing you a new and useful feature of Orchard Core about how to sanitize your HTML in an easy way! Orchard Core updates HTML script sanitizer By default, every content part should prevent input from rendering <script> tags. This should be opt-in on a per-type part level. This means that even if a part editor permits it, the rendering would filter these out. We can provide a reusable service as many parts will need it. And here we go! The name of the service is HtmlSanitizerService that is responsible for sanitizing the HTML code. To do that we are using a new open-source NuGet that can be found in GitHub called HtmlSanitizer. HtmlSanitizer is a .NET library for cleaning HTML fragments and documents from constructs that can lead to XSS attacks. It uses AngleSharp to parse, manipulate, and render HTML and CSS. As you can see in the code, there is a new class called HtmlSanitizerOptions that you can use to configure the sanitizer. If you checked the Usage section of the README.md file on the GitHub page of HtmlSanitizer you could see several lists that contain the tags allowed by default, the attributes allowed by default, CSS properties allowed by default, and so on. If you navigate to the HtmlSanitizerTests file and check the ShouldConfigureSanitizer method, you could see how to use the HtmlSanitizerOptions to set up your sanitizer by for example adding additional allowed attributes to it. In the 34th line, we are adding the class as an allowed attribute. And the Sanitize method of this service (you will never guess!) is responsible for sanitizing the HTML. OK, that's cool but where and how can I use this feature in my Orchard Core site? If you have a HtmlBody Part, an HTML Field, or a Markdown Field you will find a new option in the editor of the field or the part with a new checkbox: Sanitize Html. This checkbox is enabled everywhere by default, but of course, you have the availability to disable this feature. Let's say you have a site installed with the Blog recipe and you would like to create a new Article and do some evil stuff in the HtmlBody Part. You view the HTML source and enter the line there <a href=\"javascript: alert('xss')\">Click me</a> Then hit Publish and view the HTML source again. You will notice that the code changed to <a>Click me</a>. Preview feed moved to Cloudsmith For Orchard Core, the community has switched the preview feed package repository to Cloudsmith due to much nicer retention and bandwidth policies for open source projects. It means now you can use a different feed when using the nightly build packages of Orchard Core. If you open the documentation and select the Configure Preview package source in the Getting started section you will find the new feed URL and the way about how to set it up using Visual Studio or using the NuGet.config file. Templates content items If you remember, we had the Layout Template in Orchard 1, where you could define a layout page and save it as a template to start new pages out of this template. The idea would be to make it for any content item that you could store as a template and then create items that are just clones of that. In GitHub there is a feature called issue templates: when you create a new issue, you have templates for different types of issues. To see a good example of this idea navigate to the GitHub repository of ASP.NET Core and start to fill a new issue. Here GitHub will ask you what kind of issue you would like to create. These are the issue templates. What about creating a content item and saving it as a template? The same way you have a Publish or Save as draft, you can say: Save as a template. And then it would be a content item of the specific type that might appear in the menu somewhere or might appear in the New button when you create a new content item based on the given type. When you create a new of this thing, it will just clone it and you start with a new content item that is based on that. If you have like articles with the specific background or specific text that you want to reuse you can do that. Same thing for a content type with a Flow Part attached. In this case, you can reuse the widgets too! What do you think about this idea? Do you like it? Or do you have any other thoughts about this feature? Leave your reply in the comments section below and let us know! Demos Code Generation Helpful Extensions in Lombiq Helpful Extensions for Orchard Core If you navigate to the GitHub page of the Lombiq Helpful Extensions for Orchard Core, you will find a module that contains some handy extensions that you can use in your Orchard Core solution. Note that if you are using the nightly builds of Orchard Core, you should checkout to the orchard-core-preview branch, otherwise clone the dev branch of the repository. To use this module place the content of it to your solution and if you are using Visual Studio use the Solution Explorer and add this module as an existing project to your solution. Don't forget to add this as a project reference to your ASP.NET Core Web Application. This is the way how you could add any external module or theme to your Orchard Core solution. Now if everything goes well, you can build your solution and install your Orchard Core site! Note that if you are using the nightly builds, you may need to add the preview package source as described here. Set up your application using the Agency recipe. Go to Configuration -> Features and enable the Code Generation Helpful Extensions - Lombiq Helpful Extensions module. Now head to the content definition of the Landing Page (Content -> Content Definition -> Content Types -> Landing Page) and hit the Toggle showing generated migration code button. Here you could see the power of this extension. This module is about generating migration code from content definitions. You can use this to create (or edit) a content type on the admin and then move its creation to a migration class. Generated migration code is displayed under the content types' editors. If you are interested in the full demo, don't forget to check out the recording on YouTube! News from the community New websites using Orchard Core https://saintsrow.com is the website where you can get information and order the different Saints Row games. And if you visit https://chorusthegame.com, you will find everything about an upcoming game called Chorus. If you are interested in more websites using Orchard and Orchard Core, don't forget to visit Show Orchard. Show Orchard is a website for showing representative Orchard CMS (and now Orchard Core) websites all around the internet. It was started by Ryan Drew Burnett, but since he doesn't work with Orchard anymore, as announced earlier it is now maintained by our team at Lombiq Technologies. Orchard Core workshops The contributors of Orchard Core will hold some unique online workshops in the coming months, between May and September 2020. So even with Orchard Harvest postponed due to the coronavirus pandemic we'll get some new learning events. Lombiq's developers will also give two workshops, on using Orchard from the admin UI and on developing a module. Are you looking to get up to speed with Orchard? Check out the workshops' details on the Orchard Core homepage! Orchard Dojo Newsletter Now we have 145 subscribers of the Lombiq's Orchard Dojo Newsletter! 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!

Short codes, new content filters - This week in Orchard (22/05/2020)

Would you like to have an enhanced way to filter your content items in the content items list? Or are you looking for a feature that could work similarly to the short codes in WordPress? If your answers are yes, then this post is written for you! Orchard Core updates Configure Dev package source If you would like to use the nightly builds of Orchard Core, then you will need to use MyGet instead of NuGet. Now the documentation contains a dedicated page to explain how to add the dev package source pointing to MyGet. Preserve external authentication tokens There is a new feature to save the external tokens to be able to reuse them inside the user payload. They are encrypted inside the User object and the UserStore now implements the interface named IUserAuthenticationTokenStore. If you are about to manage tokens you just need to use the methods here to get/set/update or remove the tokens. Document activate-links.js and extend functionality for nested menu items and action URLs In the past, by using the activate-links.js script there was no way to expand a nested menu item if the active URL was in a sub-navigation item. Also if you had an active menu link like for example /todo-items, and navigated to an action from there like /todo-items/Create or /todo-items/Edit/{id} and the URL does not appear in the menu, no item was active in the menu. Now the activate-links.js is extended to traverse URL segments to find out the active menu item and you can find a callback function to perform more actions on nested menus. There is also nice documentation about how to mark the active item in a menu. Short codes Let us show you a way to inject some predefined HTML snippets like a media snippet that you can inject in your content editors. Today when we render for example an HTML BodyPart, we will optionally evaluate it as a Liquid template, and we will also use the new Short Codes feature of Orchard Core. The idea is that there is a module in Orchard Core called ShortCodes. This feature is about letting you evaluate some HTML blocks and replace short codes. We had that in Orchard 1 (remember the notion of filters and the tokens feature). This short code is actually looking much more like tokens in Orchard 1, but with a difference. You have a ShortCodeService that has a ProcessAsync method with string input. It processes and replaces all the short codes in the HTML and returns you another string. The implementation is looking for IShortCode implementations, right now we have only one implementation, called MediaShortCode. When you call ProcessAsync, it will look for everything that has the text between [media] and [/media] and then take whatever is inside. Ensure its a valid URL and sanitize the output of this thing just in case it would contain some ref to a JavaScript or anything that could look like a script and returns the result. That is actually lighter than Liquid and easier to read. We use Liquid, because we had that, and of course you can still use Liquid. So, now you can create as many short codes as you want. For example there could be a Read more short code that is just about to render a Read more link from the summary to the full blog post. Later we can have a service like ShortCodeDefinition, that would let you describe the short code that you can support with the name, the properties, and the description, like in Orchard 1, where whenever something is tokenizable there is a little pop-up button that you can use to list all the tokens that are available. This would be very useful to have in Orchard Core too. In Orchard 1, the tokens were code-based. There was a way to chain them, which means you could have a token to return the user and from the user you could say give me his email, and so on. But in this case you had to chain them in some way. For that you can use Liquid in Orchard Core by providing good flexibility to write anything without the limitation of tokens. The token is like in the middle between the short codes and Liquid. It's not powerful enough, but it's more powerful than short codes. Short codes would be super-easy to use and you can't chain them. But you can use them recursively like you could use maybe B short code to make something bold inside an A short code. They are individually functional, they don't work together like tokens would do. And we can make short codes dynamically or from the admin like templates. We could not change the behavior of tokens from the admin, but with this logic we could list all the available short codes and also add new custom short codes. Like you could add a new Twitter short code by yourself where the template itself could be in Liquid. In this case the users can use short codes that could be easier to write than Liquid. But why is it call short codes? This name comes from WordPress, where you can already meet with a thing called shortcodes. Here is a screen from WordPress where you can see all the short codes. We can also add queries to this list, like let's inject the recent blog posts! But that's enough talk for now, let's see the media short code in action! Imagine we have an Orchard Core site installed with the Blog recipe. Now navigate to the admin site and upload an image to the root of the Media Library. We added an image here called cat.jpg. Leave a comment below and try to guess what can you see in this picture! Now navigate to the Blog and edit the built-in one. The goal is to add the media short code somewhere in the body of the post. Here you could see the way of using the media short code. Now we have one step left to do: publish the post and see it in action! As we mentioned you can use as many short codes here as you want and can display multiple cats too! Demos New content filters The header section of the content items list will be updated and different modules and features can apply filters to the content listing. The first one is the culture filter, which means that you will have the availability to filter by localized content. You can also apply the taxonomy filter and filter by categories. Or you can filter by tags if you want. To set up which taxonomies you want to use in the content list to filter on, you will find a new setting under Configuration -> Settings -> Taxonomy Contents List Filters, where you can choose which you want to use. If you are interested in the full demo and the way how it will implement, don't forget to check out the recording on YouTube! News from the community Poking around with Orchard Core You can find a huge detailed blog post about how to build modular, multi-tenant applications using Orchard Core. Thanks to Lewis for this great post! A new website using Orchard Core Shipwrecked alone on an uncharted island, explore, adapt, and navigate the land and perilous seas to stay alive. Brave the storm in Windbound, the new survival open-world role-playing game coming this August 2020 on PC, PlayStation 4, Xbox One, and Nintendo Switch. Let us show you the official website of Windbound - Brave the storm! If you are interested in more websites using Orchard and Orchard Core, don't forget to visit Show Orchard. Show Orchard is a website for showing representative Orchard CMS (and now Orchard Core) websites all around the internet. It was started by Ryan Drew Burnett, but since he doesn't work with Orchard anymore, as announced earlier it is now maintained by our team at Lombiq Technologies. Orchard Nuggets: How to call an external API from a workflow task? In our newest Orchard Nuggets post we will show you the way how to use the Http Request Task to call an external API in Orchard Core! And guess what, we will also show you the way how you can work with the response data in your custom workflow task! Check out the other posts for more such bite-sized Orchard tips and let us know if you'd have another question! Orchard Core workshops The contributors of Orchard Core will hold some unique online workshops in the coming months, between May and September 2020. So even with Orchard Harvest postponed due to the coronavirus pandemic we'll get some new learning events. Lombiq's developers will also give two workshops, on using Orchard from the admin UI and on developing a module. Are you looking to get up to speed with Orchard? Check out the workshops' details on the Orchard Core homepage! Orchard Dojo Newsletter Now we have 145 subscribers of the Lombiq's Orchard Dojo Newsletter! 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!

How can I call an external API from a workflow task? - Orchard Core Nuggets

You have several options to send an HTTP request to an external API in Orchard Core, but maybe you haven't tried the Http Request Task. Let's see quickly how you can hook up a workflow! The HTTP Request Task comes from the HTTP Workflows Activities feature, so before doing anything, don't forget the enable that module. Now navigate to the Workflows option from the menu and hit Create Workflow Type to add your workflow. JSONPlaceholder is a nice fake online REST API that you can use whenever you need some fake data. It comes with a set of 6 common resources and we are going to use the first one and making a GET HTTP request to get 100 user posts in a JSON format. Choose the Add Task button in the Workflow editor and select the HTTP Request one from the HTTP category. Here you can see a nice editor where you can provide the details of your request. We added a custom title to our activity as Get 100 posts. The URL will be the URL provided by the JSONPlaceholder API. To get the posts we have to make a GET request. If you would like to add a new post, make a POST request to the same endpoint, and provide the body to send. Don't forget to handle the 201 HTTP response code, because this will be the number that will show you that you are good to go and the server faked that your content was created. You may notice that you can type Liquid code everywhere in this editor. Let's say that the title of our new post will be the name of our site. To do that, we can pass the {{ Site.SiteName }} Liquid expression. As we mentioned, we get 201 if everything goes well. If the server returned with anything else, then something bad happened and we should handle that in our workflow of course. To handle the failed requests, we can use the Unhandled HTTP Status branch of the HTTP Request Task (we named in Create a new post) and notice the user somehow. OK, it's not a useful workflow, because we are only dealing with the response codes, but not with the response body. But how can we use the response details? To find the answer we have to check the source code of the HTTP Request Task activity and take a look at the ExecutyAsync method. Here you can see that the code uses the LastResult of the workflowContext and the LastResult has a Body property where you can find the response body itself. The LastResult property of the WorkflowExecutionContext is an object, that means you can easily put everything into the LastResult, but it could be a little bit harder to get the content from it. public override async Task<ActivityExecutionResult> ExecuteAsync(WorkflowExecutionContext workflowContext, ActivityContext activityContext) { using (var httpClient = new HttpClient()) { var headersText = await _expressionEvaluator.EvaluateAsync(Headers, workflowContext); var headers = ParseHeaders(headersText); foreach (var header in headers) { httpClient.DefaultRequestHeaders.TryAddWithoutValidation(header.Key, header.Value); } var httpMethod = HttpMethod; var url = await _expressionEvaluator.EvaluateAsync(Url, workflowContext); var request = new HttpRequestMessage(new HttpMethod(httpMethod), url); var postMethods = new[] { HttpMethods.Patch, HttpMethods.Post, HttpMethods.Put }; if (postMethods.Any(x => string.Equals(x, httpMethod, StringComparison.OrdinalIgnoreCase))) { var body = await _expressionEvaluator.EvaluateAsync(Body, workflowContext); var contentType = await _expressionEvaluator.EvaluateAsync(ContentType, workflowContext); request.Content = new StringContent(body, Encoding.UTF8, contentType); } var response = await httpClient.SendAsync(request, HttpCompletionOption.ResponseContentRead); var responseCodes = ParseResponseCodes(HttpResponseCodes); var outcome = responseCodes.FirstOrDefault(x => x == (int)response.StatusCode); workflowContext.LastResult = new { Body = await response.Content.ReadAsStringAsync(), Headers = response.Headers.ToDictionary(x => x.Key), StatusCode = response.StatusCode, ReasonPhrase = response.ReasonPhrase, IsSuccessStatusCode = response.IsSuccessStatusCode }; return Outcomes(outcome != 0 ? outcome.ToString() : "UnhandledHttpStatus"); } } Imagine you are implementing a custom activity that creates content items based on the response body. For that, you need to get the JSON then serialize it to a typed class. That makes the data easier to work with. In the ExecutyAsync method of your custom activity you can get the JSON like: var responseBody = workflowContext.LastResult.GetType().GetProperty("Body").GetValue(workflowContext.LastResult).ToString(); Here the responseBody variable will contain a JSON in a string. You may notice that the value of the title here is Orchard Core, which comes from the {{ Site.SiteName }} Liquid value. To deserialize the response to typed classes you can use the built-in Json.NET package in Orchard Core and for instance, use the JsonConvert.DeserializeObject method of it. And that's it, now do what you want with the data. Did you like this post? It's part of our Orchard Core Nuggets series where we answer common Orchard questions, be it about user-facing features or developer-level issues. Check out the other posts for more such bite-sized Orchard Core tips and let us know if you have another question!