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

Show a badge if a user is locked out, Lombiq Orchard Visual Studio Extension v.1.8.1 - This week in Orchard (27/06/2025)

This week's topics include displaying a badge when a user is locked out, renaming the ResetIndexProfile and RebuildIndexProfile recipe steps, and enhancing documentation for the indexing module. And have we mentioned that we've released a new version of our Orchard Visual Studio Extension, which now includes support for Razor Pages to the Dependency Injector?

Latest tutorials

Featured tags

IIS
API
SMS
SEO
MCP
All tags >

VueForms module, Obsolete IContentAliasManager - This week in Orchard (22/10/2020)

We prepared with a huge demo about showing you how you can use the custom VueForms module for Orchard Core! But first, let's check out the latest news around Orchard Core. Read our current post to find out an obsolete interface! Orchard Core updates Fix sizing of HTML/MarkdownEditor settings to be consistent in the correct zones There were some inconsistencies with the sizing of some field elements settings and other views. Some hints were full-width, some were restricted to col-md-6, other col-sm-6. Hint boxes should also align together with the rest of the fields.And one more thing here: the general settings/common to all editors should be in the Content zone and editor modes should be in the Editor zone. The issues had been fixed, they all look like this now, without uneven padding, and shapes are consistently ordered. Obsolete IContentAliasManager The IContentAliasProvider was renamed to IContentHandleProvider. The idea behind that is the alias was a bad name because it was in conflict with the AliasPart and they are two different things. They are related somehow because a handle now can come from an alias, but a handle is a generic term to say you can get a content item from different ways, like using a content item ID or a slug or alias. Whatever kind of identifier you want to give to your content item and then when you load a content item by its handle, you provide a prefix. In the past, the IContentAliasManager was just marked as obsolete and make it backward compatible, but the backward compatibility code didn't work. So, don't forget, if you injected the IContentAliasManager in the past and you update your Orchard Core solution to the latest, you will need to use the IContentHandleManager instead. Ensures shell terminating and disposing When e.g. we enable a feature for a given shell through the admin, the shell is released in the context of a shell scope, and at the end of this scope (if it is the last one for this shell) the terminate events are called and then the shell is disposed. But when e.g. we reload a tenant through the admin or when a shell releases its dependents, a shell may be released without having any current scope on it, so it is disposed immediately but without calling the shell terminate events. So here, in that case, we create a new scope (without using it) and dispose it to let it manage the shell state as usual. Note: In that case, the terminate events are called synchronously, we would need a shell ReleaseAsync(), but at least there are called. Another suggestion would be to get rid of the terminate events that are not used in the current code. So, in summary Here we ensure that the shell terminating/terminated events are called, even if the shell is not terminated by the last shell scope, e.g when the shell is released by dependency or when changed through the tenant's admin UI. So, right now we kept the terminate events. Here we also call the shell terminating/terminated events before the BeforeDispose callbacks that we use to call the session commit asynchronously, which is better if a terminate event uses an ISession. Demos VueForms module The StatCan Orchard Core repository houses a collection of custom Orchard Core resources, modules, and themes that support various web applications and software-as-a-service (SaaS) products. Built on top of Orchard Core CMS, developers have a suite of web application features out of the box (e.g. content management, authentication, forms, themes, etc) by customizing the selection and configuration of components. The extensibility of the framework allows new features and components to be added easily. One of the custom modules called VueForms, which aims to simplify the creation of client-side forms in OrchardCore. Let's see that module in action! Clone this repository and set up your site. Now go to Configuration -> Features and enable the VueForms and the VueForms Localized modules. The first is about provide a Form content type that simplifies using VueJs forms in the frontend and the second one is about to weld the LocalizedText part to the VueForms. The difference between the built-in Forms module and this one is that it's using client-side validation using Vue.js, Vuelidate, and Vuetify. Now if you navigate to the Content menu option, you will find a new one called Vue Forms. Here you can manage your Vue Form content types. Let's create a new one called Contact us! You have the option to disable or enable your form. If you disable the form, you can set an HTML, that is displayed when someone tries to render a disabled form. This feature is about creating the form on the back-end and no one can access it on the front end. If the server-side validation passes you will get the message that you can provide in the Success Message text box. Or it's doesn't, you can display the text that you can type in the Error Message textbox. Next one is the client init script. This is actually a client-side JavaScript, where you can set client-side actions. Right now here we set the required fields and in this case, we use it to localize the VeeValidate field validations. The required messages are coming from our localize liquid filter. The OnValidation is a server-side script, this is using Jint. Here you can get the form data and then you can perform validation here. This is not complete yet, the end goal would be to have widgets and the validation would be placed inside the widgets. The widgets would generate the client-side and server-side validation together. The addError() method allows you to add an error and map that input into the client-side. Here comes the OnSubmitted section. This is where you would perform actions after validation. Let's say the validation passes, there are no errors added, that means this script is called. In this case, we are creating a new predefined ContactRequest content item. And in the Localized Text section, you can create localizations with a key-culture pair. Here you can add as many as you want by clicking on the Add button, you can delete them by clicking on the trash bin icon, and reorder them with the little hamburger icon. The getLocalizedTextValues() function in the OnValidation section is used to get the localized text for the current culture that you defined here. This content type has a Form Part too that you can use to add a new Vue Component widget. Using that you can set the VueJS Component template. It's basically code, you are writing your Vue.js component here. You provide the template and you also have the script that is a typical Vue.js component script. The template is using the ValidationProvider component that wraps your inputs and provides a validation state using scoped slots. Now let's publish this new content item and view it in the front-end! Here you can see we have already filled out this form with some data but the email address is wrong. If we click on send, we will get the Your email is invalid error message, which is a client-side validation error. But that's not all! Enable the Workflows module and create a new workflow type called VueForm submitted. Click on the Add Event button and you will find a new category in the modal window called VueForm. And there is a new VueForm Submitted event that is fired when a VueForm passed validation and is submitted. Here you can also select the forms for which this workflow runs. We have only the Contact Us right now, so select this one. And using that event you can say send an email to the site admins if the form submission was successful. The whole repository and this module have great documentation where you can read more about these scripts and how to customize your VueForm content items. And don't forget to check out the recording of this demo on YouTube! News from the community Using the OrchardCore OpenID management feature with an existing OpenIddict deployment Kévin Chalet is one of the main contributors of Orchard Core. He developed the OpenID management feature for Orchard Core. In his blog post, he writes about how you can use the GUI of Orchard Core with an existing OpenIddict server, that is typically located in another project. Orchard Dojo Newsletter Lombiq's Orchard Dojo Newsletter has 163 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!

Media Profiles, Renamed SummaryAdmin shapes - This week in Orchard (16/10/2020)

Media profiles feature to Orchard Core that allows you to defined preset image resizing and formatting commands! Renamed SummaryAdmin shapes, and new routes to avoid features URL blocking by IIS, and a lot more in our current post! Orchard Core updates Prevent disabling or removing administrator role Let's say you set up your Orchard Core site using the admin as the user name and for some reason, you navigate to Security -> Users to disable your own account. The problem here is that in this case, you are the only user with an Administrator role in the system. From now you can't do that, you will get a warning message saying you cannot disable the only administrator. Go back and edit your own user again and try to edit the user name too. This also triggers a new validation error, because you cannot modify the user name of the currently logged-in user. The last thing here is about removing the Administrator role from your user account. You could do that, but if your user is the only user with the Administrator role assigned, you will get a warning message about you cannot remove the Administrator role from the only administrator. Avoid features URL blocking by IIS IIS has some default filters for security like you can't have specific words in the URL. There are a few words used by us too like .sitemap. IIS also blocks any request ending in .resources by default. The list of blocked extensions includes a bunch of other terms that could conceivably be used in feature IDs such as .master, .browser, .config, .skin, etc. It's possible to override this behavior in the web.config file but this would have to be done on a per-application basis and carries unwanted security implications. The solution is just to put these parts in a different segment. If you want to enable a feature the URL to do that was:https://localhost:5501/Admin/Features/Enable/OrchardCore.Sitemaps Now the new URL is:https://localhost:44300/Admin/Features/OrchardCore.Sitemaps/Enable So the goal of this fix is to use the pattern Admin/Features/{id}/Enable in place of Admin/Features/Enable/{id}. The same goes for when you want to disable a feature. Renamed SummaryAdmin shapes of ContentsDriver These shape names are not compatible when defining custom placement, so they have been renamed. They are admin shapes, so the impact is quite low. If you have your own custom theme and redefined these ones you have to change them. So, the ContentsDriver creates four shapes with different shape types. Shape("Contents_SummaryAdmin__Tags", new ContentItemViewModel(model)).Location("SummaryAdmin", "Tags:10"), Shape("Contents_SummaryAdmin__Meta", new ContentItemViewModel(model)).Location("SummaryAdmin", "Meta:20"), Shape("Contents_SummaryAdmin__Button__Edit", new ContentItemViewModel(model)).Location("SummaryAdmin", "Actions:10"), Shape("Contents_SummaryAdmin__Button__Actions", new ContentItemViewModel(model)).Location("SummaryAdmin", "ActionsMenu:10") However, the actual shape type is considered before __ i.e. all the above shapes are resolved to the same shape type Contents_SummaryAdmin. Renamed these shapes as following to apply a unique placement record for each shape. Contents_SummaryAdmin__Tags renamed to ContentsTags_SummaryAdminContents_SummaryAdmin__Meta renamed to ContentsMeta_SummaryAdminContents_SummaryAdmin__Button__Edit renamed to ContentsButtonEdit_SummaryAdminContents_SummaryAdmin__Button__Actions renamed to ContentsButtonActions_SummaryAdmin So that placement will target a single shape type. { "ContentsButtonActions_SummaryAdmin": [ { "shape":"ContentsButtonEditNoView_SummaryAdmin" } ] } Demos New ImageSharp.Web Features ImageSharp is a new, fully-featured, fully managed, cross-platform, 2D graphics library. Designed to simplify image processing, ImageSharp brings you an incredibly powerful yet beautifully simple API. With the v1.0., ImageSharp has got a bunch of new features and it's now a lot faster. And Orchard Core is also using ImageSharp to work with images. New features included: Format support to the Tag Helpers/Liquid Filters: The slight weirdness with adding this is the file extension on the URL will remain .png, but the image will be returned with the correct mime/type. Quality support to jpg encoding and Tag Helpers/Liquid Filters: The Quality support allows you to specify a quality % to jpg encoding. Note: only jpg encoding is supported, but the Format support allows you to convert an image from saying png to jpg, and then reduce the quality. CurrentCulture/InvariantCulture for query string parameters: Supported through custom ImageSharp configuration, but not integrated into Orchard Core. Basing this decision primarily on the idea that most of our resizing/processing query string building, is done through templates, which are culture invariant. And that's not all of it! There is now a new Media profiles feature in Orchard Core that allowing you to specify resizing options and much other stuff. A profile can then be called with the profile name resize_url: profile: 'banner' rather than having to specify all the resizing options that may apply. But that's enough talk for now, let's see them in action, after all, we are in the Demos section of This week in Orchard, right? Use the latest nightly build of Orchard Core and set up your site using the Agency recipe. Then navigate to the admin UI where you will see a new option in the menu (make sure to enable the Media profiles feature): Configuration -> Media -> Media Profiles. Media Profiles are quite simple, they just have the standard resizing options that we have in ImageSharp. Notice that here you can set the width and the height values only from the supported ones. We add the name md to this media profile, let's note it, we will need it right away. Now navigate to Design -> Templates and edit the predefined Content__LandingPage Liquid template. We will use the newly created image profile when displaying the portfolio images. Just a note here: the home page in this agency is a LandingPage content type that has several Bag Parts attached. The one with the display name Portfolio is about to add Project content types to your LandingPage content type. And the Project content type has a Media Field attached, called Image. In this Liquid template, we will use our newly created md media profile. Here we say use the md media profile when displaying these images and in this particular case we would like to override the resize mode for the processed image. Instead of crop, we would like to stretch these images, but just in this case. When you define a media profile, you can say I don't want to specify the width, the height or the resize mode. In that case, you can set them in your Liquid helper, just as you could do that before. Now, let's just check out how does the home page of our site looks like. Remember that we set a lot of values when setting up our md media profile and we also set the quality percentage for the processed image and we set it as 10. We also change the width and height values and override the resize mode to stretch the images. This result is low quality stretched images in the Portfolio section. Now let's see the source code of this page and check out the img tags using the DevTools of Chrome. As you can see it's not tied to ImageSharp, the logic just converts the media profile into a good query string. This means we can do the override easier and if we change the values the URL will change, and it breaks the cache. When you would like to show the kittens.jpg with 100 width and 100 height, by using the crop resize mode (that resizes the image using the same functionality as max then removes any image area falling outside the bounds of its container) and use only 50% as the quality when compressing the image you would write a Liquid filter like this: {{ 'animals/kittens.jpg' | asset_url | resize_url: width:100, height:240, mode:'crop', quality: 50, format:'jpg' }} The documentation is also updated to help you how to use these new arguments. Don't forget to head to YouTube and watch the recording of this awesome feature! News from the community Orchard Dojo Newsletter Lombiq's Orchard Dojo Newsletter has 162 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!

Distributed cache, YesSql improvements - This week in Orchard (09/10/2020)

Get ready for the upcoming additions of Orchard Core! This week you can see demos about adding distributed cache to Orchard Core and the latest improvements of YesSql! Orchard Core updates Restrict Content Types Admin Node to only create the specified content type Let's say you have a site set up with the Blog recipe and your goal is to add a new admin menu that is about to list all the existing Article content items. To do that you have to navigate to Configuration -> Admin Menu and click on the Add Node button. Here you will need to select the Content Types Admin Node because you would like to add a link for each one of the selected content types from the list. And yes, you will only select the Article content type in the next screen. And that's it, you have created a new admin menu that lists all of the Article content items from the system. If you click on that you will see the list of the Article content items. Note that from now you will not see a filter here to filter by content types because that really doesn't make much sense. You created this Content Types Admin Node to list only the Article content items. If you would like to filter by content type, use the filter in the Content -> Content Items page as you would do it before. Remove ManageOwnMedia permission The ManageOwnMedia permission isn't handled today and we can replace it with the ManageMedia permission. So, now there is no separate permission to manage their own media or manage the media. It will be added back to the system again if the authorization logic is to be able to separate the user's media and the media uploaded by others. Right now, if you head to Security -> Roles and hit the Edit button near one of the Roles, you will see the missing Manage Own Media permission. Use a dropdown menu on the admin top navbar for the user menu The user menu on the admin theme is just about listing the user name of the currently logged-in user with a little icon near it. And there was a Log off link at the right side of the user name. It was just a piece of HTML code in the Layout.cshtml file of the default admin theme. From now the whole user menu gets its own shape, called UserMenu.cshtml. If you would like to override the user menu, you don't need to create a Layout.cshtml file in your admin theme, you just need to override the UserMenu.cshtml file. And if you check out this GIF, you will see that now the content of the user menu is placed in a dropdown instead of having it's content inline. Document release procedure Orchard Core is open-source that means you can check out and request changes to the source code, tell your opinion about it, and update the relevant documentation for that piece of code. Now there is a new page in the Orchard Core Documentation about how to publish a new Orchard Core release. These notes are primarily for Orchard's core contributors to guide them on how to prepare a new release, but if you just take a look at these you can now see what are the steps that need to be done to be able to ship a new release of Orchard Core. Add option to allow Lucene query syntax in the search There is a setting in the Lucene module that you can turn on and whatever you type in the search box won't be parsed as 'these are the words that I need to search on', but parsed as this is a Lucene query. You can use the Lucene query syntax in search forms, like the quotes, plus signs and things like this. But by default, it will still be like today, which is type words and it looks for these words. If you type stuff that has weird characters, they would be ignored. But how can I turn on that feature? Just navigate to the admin UI of Orchard Core, then find the settings in Search -> Settings -> Search (make sure you have enabled the Lucene module). Demos YesSql: Adding support for multi filters on the same table index There is a new method on .IQuery called .Or(), which starts a filter on a distinct table. This can be used for instance when the same index needs to be queried for multiple sets. It will actually add many filters on the same record of the index. With .Or() you can do now filters on different inner joins of the same index. Which means it will do unions of result with the filters. Let's check out the following unit test. [Fact]public async Task ShouldQueryMultipleIndexes(){ // We should be able to query documents on multiple rows in an index. // This mean the same Index table needs to be JOINed. _store.RegisterIndexes<PersonIdentitiesIndexProvider>(); using (var session = _store.CreateSession()) { var hanselman = new Person { Firstname = "Scott", Lastname = "Hanselman" }; var guthrie = new Person { Firstname = "Scott", Lastname = "Guthrie" }; session.Save(hanselman); session.Save(guthrie); } using (var session = _store.CreateSession()) { Assert.Equal(2, await session.Query<Person>() .With<PersonIdentity>(x => x.Identity == "Hanselman") .Or() .With<PersonIdentity>(x => x.Identity == "Guthrie")) .CountAsync()); }} This PersonIdentitiesIndexProvider will just map the first name and the last name of each person. We created two persons here that means the provider will be creating four PersonIdentity records. Two to store the first name and last name for Scott Hanselman and two to store the first name and the last name of Scott Guthrie. If without using the .Or() it will issue a query where the Identity == "Hanselman" AND Identity == "Guthrie", which will return nothing. With the .Or(), it will do an inner join on PersonIdentity with a filter on Identity == "Hanselman" and another inner join on PersonIdentity with a filter on Identity == "Guthrie". In this case, we will get both the two persons. It's like give me any person who's PersonIdentity has a record like Hanselman OR where the PersonIdentity equals Guthrie. Let's see another example! // Creating articles.using (var session = store.CreateSession()){ session.Save(new Article { Content = "This is a green fox" }); session.Save(new Article { Content = "This is a yellow cat" }); session.Save(new Article { Content = "This is a pink elephant" }); session.Save(new Article { Content = "This is a green tiger" });}using (var session = store.CreateSession()){ Console.WriteLine("Boolean query: 'pink or tiger'"); var boolQuery = await session.Query<Article>() .Where(x => x.Word.IsIn(new[] { "pink" })) .Or() .Where(x => x.Word.IsIn(new[] { "tiger" })) .ListAsync();} This is a full-text sample where in this case we can query documents by their content, by their words. If we have the documents as you could see in the code, we are creating an index for all the words pointing to the document, like green and fox points to the first Article. Now the query is about to give me all the documents that have pink in it OR all the documents that have tiger in it. The goal is to get the last two articles in this case. Let's check out this query: var boolQuery = await session.Query<Article, ArticleByWord>().Where(a => a.Word.IsIn(new[] { "white", "fox", "pink" })).ListAsync(); This query will return all the articles that have white AND fox AND pink in it and there is none in this case. You can find the recording of this improvement on YouTube! But wait a minute! Could this syntax be better? When you have a query, you can say .Any() and every predicate will be done in a different table. .Any() being an OR, and .All() being an AND. In this case, we're querying on the same index (ArticleByWord) but each of the calls on .With() will be a different projection, a different inner join in this case. Here we are looking for an article that has the word pink OR the words green AND fox. await session.Query<Article>() .Any( x => x.With<ArticleByWord>(a => a.Word == "pink"), x => x.All( x => x.With<ArticleByWord>(a => a.Word == "green"), x => x.With<ArticleByWord>(a => a.Word == "fox"))).ListAsync(); SELECT DISTINCT Document.* FROM DocumentINNER JOIN ArticleByWord_Document AS [ArticleByWord_Document_a1] ON ArticleByWord_Document_a1.DocumentId = Document.IdINNER JOIN ArticleByWord AS [ArticleByWord_a1] ON [ArticleByWord_a1].Id = ArticleByWord_Document_a1.ArticleByWordIdINNER JOIN ArticleByWord_Document AS [ArticleByWord_Document_a2] ON ArticleByWord_Document_a2.DocumentId = Document.IdINNER JOIN ArticleByWord AS [ArticleByWord_a2] ON [ArticleByWord_a2].Id = ArticleByWord_Document_a2.ArticleByWordIdINNER JOIN ArticleByWord_Document AS [ArticleByWord_Document_a3] ON ArticleByWord_Document_a3.DocumentId = Document.IdINNER JOIN ArticleByWord AS [ArticleByWord_a3] ON [ArticleByWord_a3].Id = ArticleByWord_Document_a3.ArticleByWordIdWHERE ArticleByWord_a1.Word = 'pink' OR ( ArticleByWord_a2.Word = 'green' AND ArticleByWord_a3.Word = 'fox') Here you can also see how does the query look like. That's the current syntax right now. And it's not breaking change because if you had .query.With().With(), it will still behave the same as before. It will be a single projection with two .With(). If you project on the same table it will be an AND on the same table, the same projection.If you would like to know more about the current syntax and the latest features, this is the YouTube video that you are looking for! Distributed Redis Cache There is a huge PR with a great addition to Orchard Core about having Distributed Cache in Orchard Core. In fact, this PR is related to all modules services using cached data that need to be in sync with a shared database, e.g. site settings and other admin settings, templates, queries, layers, and so on. Currently, in the dev branch, this is already the case for most of them but by using local memory cache entries that are invalidated through a distributed signal. This PR has changed this pattern by using a multi-level cache including a distributed cache. And Jean-Thierry Kéchichian made more services to be distributed aware, there are remaining things but could be done in other PRs. And recently he added the ability through a separate feature to also keep in sync tenant states, when you enable/disable/create/setup a tenant. To summarize: All services that were using the memory cache are now using a multi-level cache including a distributed cache, this cache is kept in sync with the database without using a message bus but document identifiers. We have concrete implementations of distributed services based on Redis, Redis cache, Redis data protection, Redis message bus, and Redis lock. In the current code, we never use a message bus/distributed lock. When enabling a concrete distributed cache in the default tenant, we automatically keep all tenants in sync through a hosted service, here also without using a message bus but identifiers. Here a stateless configuration is needed. There is a separate feature (DefaultTenantOnly) to keep tenants in sync. Don't forget to head to YouTube and watch the recording of this upcoming feature! News from the community Orchard Dojo Newsletter Lombiq's Orchard Dojo Newsletter has 160 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!

New custom filters in Fluid, Media options admin page - This week in Orchard (02/10/2020)

We prepared two interesting demos for this week: The first one is about having new useful custom filters in Liquid to make formatting numbers and string easier. The other upcoming feature is about how you can show your settings from your appsettings.json files without having the need to open these files in your file system. Orchard Core updates Restrict Content Type Admin Menus to only create the specified Content Type Several issues fixed regarding creating content items from the admin UI: Restored the new button specific to each content item when user filters by content type or accesses the content item list interface by link for a single content type in the admin menu. Fixed the behavior of the admin menu's links to Menus and Content Items: if they are not defined inside a recipe, they have a dynamic behavior and it causes an issue if the user defines a link for a specific content type inside the admin menu. In the BlogTheme, the Content Items link of the admin menu is defined in the recipe and doesn't have dynamic behavior. See the following GIF here where you can also see the creation of a new content type admin menu node that is about to list the Article content items. The new button under the new Article menu option is just about to create new Article content items. Update Blob Storage to search folder hierarchies The problem is that the method that is responsible to handle Blob Storage items does not correctly implement the includeSubDirectories = true option - it never did. This is because it's not like a normal file system where you can make one request and list everything, so it would have to make recursive requests for every directory it finds. Ironically the media step driver does this recursion already itself, but the recipe step does not when using Include All Media. So the short term workaround should be to specify the attached fields' folder's media fields, rather than Include All Media when creating the step. This issue withincludeSubDirectories = true affects this step, and the GraphQL media query - it's the only place we use it. So, Blob storage never handled searching subfolders correctly, so this should now work for the media step, and better in GraphQL queries (behaves identically to normal file system now). Now if you would like to get the content of the directory including subfolders too, the GetDirectoryContentFlatAsync method in the BlobFileStore class will return the files inside the subfolders too. Rename Smtp admin menu to Email The goal of renaming Smtp to Email is to make sure that you can edit settings related to sending emails even if you don't know what SMTP is (and this screen is also for testing email sending). Toggle password visibility on the login form and on the setup screen The login form and the setup screen now support toggling the password visibility, so can make sure that you typed the correct passwords in these textboxes. Demos Media options admin page In the appsettings.json file, you can define your media-related settings, e.g. change the list of allowed file extensions or the path used when serving media assets. The documentation includes all the default configuration values that can be overridden. The goal of this feature is to have a read-only version of the settings where you can see these configuration values without needing to navigate to your appsettings.json file to see the configured values. Head to YouTube to check out this short recording about this upcoming feature! New custom filters in Fluid Fluid is an open-source .NET templating engine that is as close as possible to the Liquid template language. It's a secure template language that is also very accessible for non-programmer audiences. It also contains an ASP.NET Core MVC View Engine. And of course, Orchard Core is using Fluid too to generate templates. If you would like to render numbers correctly, Fluid just renders them in a format 124456789, but you could not format it like for example 12,445.68 )(and you can't do it in Liquid by default either). We already had the format_date helper in Fluid where we can use the .NET formats, so the new helpers added are format_number and format_string, which are using the .NET format methods. They are not standard in Liquid, but there is nothing in Liquid to help achieving these. format_number: It will format the number with the current culture. If you pass "N", which means number in the standard numeric format strings, then it will use the number format that we have just mentioned above. So, to generate 12,445.68 from the 12445.6789 value, you can do that like 12445.6789 | format_number: "N" You can find a documentation about the standard numeric format strings here. format_string: In this case, you can pass a string with a String.Format inside and after using the format_string you can pass the values. Let's say you have the following expression: "hello {0} {1:C}" | format_string: "world" 123. This would be rendered as hello world $123.00. Notice that here we also used the currency ("C") format specifier to convert a number to a string that represents a currency amount. The documentation of Fluid contains the available custom filters where you can learn more about the other features of Fluid too. Head to YouTube to check out the recording about the new custom filters! News from the community Orchard Dojo Newsletter Lombiq's Orchard Dojo Newsletter has 161 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!

Pager with page size, refactor IContentAliasManager to IContentHandleManager - This week in Orchard (25/09/2020)

Several great features and fixes were added to Orchard Core this week! You could see a fix for an interesting issue about how you can use XSS in an SVG file, the new IContentHandleManager, and two great demos! One is about the upcoming Pager with the page size, then check out the improvements of the Shape Components! Orchard Core updates Media Content Security Policy There was a Stored Cross-site Scripting security breach through the upload of a malicious SVG file, containing malicious JavaScript code, that is then executed whenever a user tries to view the contents of the uploaded file. In order to replicate this issue, you just needed to follow the steps described below: Create an SVG file with malicious JavaScript: <?xml version="1.0" standalone="no"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg version="1.1" baseProfile="full" xmlns="http://www.w3.org/2000/svg"> <rect width="300" height="100" style="fill:rgb(0,0,255);stroke-width:3;stroke:rgb(0,0,0)" /> <script type="text/javascript"> alert(1); </script> </svg> In the Media Library, upload the file you just created. Locate the uploaded file in the Media Library and select View. Observe that a JavaScript alert popup is triggered. To prevent that the fix is to add a new security policy. This means the browser will render the SVG without executing the inline scripts. The Media.StaticFileOptions is now slightly more configurable with services.PostConfigure to allow more fine-grained controlled, if any wants to adapt the event handlers and/or use them to block certain types of requests, or whatever they feel they need to. You can see the changes in the MediaOptionsConfiguration where the DefaultContentSecurityPolicy stores the value of the content security policy header. Refactor IContentAliasManager to IContentHandleManager This is about refactoring the IContentAliasManager and associated providers to be referred to as handle. From now you will see new extension methods: Orchard.GetContentItemIdByAlias("my-alias"); Orchard.GetContentItemIdBySlug("blog/post-1"); Orchard.GetContentItemIdByHandle("slug:blog/post-1"); and generally refactors everything else that referred to as an alias as a handle. It will not break anything, because it's keeping the IContentAliasManager and registering it to resolve the IContentHandleManager. The IContentAliasManager is not obsoleted to prevent compilations errors. But we could also just drop it completely in the near future. The IContentAliasProvider however has been renamed to IContentHandleProvider with no cross resolving. Now let's see an example to make this change clear. Let's say you have a content type that has the AliasPart attached. Every alias has a pattern, which is generated by the DisplayText of the content item: {{ Model.ContentItem | display_text | slugify }} So, if you create a new content item of this content type with a display text My new content item, your alias will be my-new-content-item. OK, now we have this content item. Let's say we need to get this content item and modify some properties of it from code. But how can we get this content item? Well, you can use the default implementation of the IContentAliasManager to do that: var myContentItem = await _contentAliasManager.GetContentItemIdAsync("alias:my-new-content-item"); Notice that here we need to pass the alias: string also because we would like to get a content item by an alias. From now we can use IContentHandleManager instead of the IContentAliasManager in the following way: var myContentItem = await _contentHandleManager.GetContentItemIdAsync("alias:my-new-content-item"); The GetContentItemIdAsync method of the IContentHandleManager iterates through all of the IContentHandleProver implementations and we have an AliasPartContentHandleProvider, that checks if the handle starts with the alias: string, and if yes, it returns the content item by using the AliasPartIndex table. As we mentioned you have new extension methods to use in your Razor code. The GetContentItemIdByHandleAsync is now just about calling the same IContentHandleManager implementation as we showed you above. Configure cookie lifetime for CulturePicker The issue was about you cannot change the expiration of the content localization cookies. By default, the cookie lifetime is set to 14 days, but if you would like to set it to 1 day, you couldn't do that until now. If you open the appsettings.json file in the OrchardCore.Cms.Web, you will find an OrchardCore_ContentLocalization_CulturePicker section there. Just uncomment that lines and use the CookieLifeTime to set the culture picker cookie lifetime in days. Demos Pager with page size If you have ever worked with an Orchard 1.x site, you may have seen how does the pager looks like at the bottom of the lists, like when you are on the page that shows you the contents list. It shows you the total number of items, the current page where you are right now, and you can also set how many items you would like to see on each page. It's slightly the same in Orchard Core too. The only difference is here that you don't have the option to set how many items you would like to see on the current page. If you navigate to Configuration -> Settings -> General you will see an option called Page size, but that's about saying 'I would like to see 10 items in every page'. You can't set the page size of the current page near the pagers. Antoine Griffard decided to start working on this feature for Orchard Core too. If you enabled the Tenants feature and navigate to Configuration -> Tenants, you will see the first prototype of this feature on that page. We have 11 tenants in the system and we set the page size to 10. In this case, the pager shows two pages and you can see the number 10 here as well. There is also a recording that shows you this feature, head to YouTube to know more! Shape Components updates Two weeks ago we wrote about a great upcoming feature to Orchard Core about having Shape Components. Let's think about a shape like a reusable component, like a view component in ASP.NET, but like an Orchard shape component, that can be reused. The development on that feature is continuing, this time you could see making the Razor Tag Helpers a little bit more feel like a component. Watch this recording on YouTube to see the current state of this upcoming feature! News from the community Blogs posts about Shortcodes, Shortcode Templates, and Shortcode Delegates I think we don't need to introduce David Hayden to the Orchard community. David Hayden is primarily a C#, .NET and Orchard CMS Developer with 20 years experience developing ASP.NET Websites and related technologies. David is currently primarily focusing on .NET Core, Orchard Core, and Orchard Core CMS for building modular, multi-tenant web applications and websites. He recently published two new posts in his blog about Shortcodes and Shortcode Templates in Orchard Core CMS and Shortcode Delegates. If you would like to learn more about Shortcodes or you haven't heard about them yet, it's definitely worth to check out these articles! But don't forget that you can find two videos on YouTube about Shortcodes: check out this one first, then watch this video for the second part of the demo! We also mentioned these features in This week in Orchard too several times. Check out this for an introduction, then this one for the first demo, finally don't forget to read this post to see the improvements of the Shortcodes! And the documentation is available in this URL! Orchard Dojo Newsletter Now we have 160 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!

Secret Management Updates, ChallengeOrForbid() in Api controllers - This week in Orchard (18/09/2020)

This week you could see two great demos: one is about showing you how you can manage and import/export your secrets between servers, the other is about using Blazor WebAssembly with Orchard Core! Orchard Core updates ChallengeOrForbid() in Api controllers Most of the API controllers are configured to use the Api scheme for authentication but return ChallengeOrForbid(), which ultimately uses the default challenge scheme (which is typically the cookie handler when the Users module is enabled). To fix that, the API controllers are updated to do ChallengeOrForbid("Api") instead of ChallengeOrForbid(), so that challenges are properly handled by OpenIddict when the OpenID token validation feature is enabled. Now there is a new override for the ChallengeOrForbid() extension method that accepts the authentication schemes to challenge. And now you can use this extension method in your API controller just by passing the Api, like: return this.ChallengeOrForbid("Api");. Include ContentsMetadata (PageTitle) in Blog Theme Category Taxonomy If you use the Blog recipe, a taxonomy Category with entry Travel is created by default. However, the title for the Travel page was not correct. If you created a site name Blogging using the Blog recipe, the expected title would be: Travel - Blogging, but you got a title: Blogging. The fix was to include the ContentsMetadata in the Content-Category.liquid file. Link to GitHub Discussions in Contributing If you open the GitHub repository of Orchard Core you will find a CONTRIBUTING.md file in the root of the repository. Now this markdown file has a direct link to GitHub Discussions. But what is GitHub Discussions? GitHub only offered issues and pull requests as places to have these conversations. But issues and pull requests both have a linear format - well suited for merging code, but not for creating a community knowledge base. Conversations need their own place - that’s what GitHub Discussions is for. If you have a question and need an answer, just visit the Discussions page and if you haven't find the answer for your issue, let's ask it there. Here you can find detailed and valuable answers for questions like what is a shape? Demos Secret Management Updates Head to the GitHub repository of Orchard Core and checkout to the deanmarcussen/secrets branch to be able to try out this upcoming feature! After you set up your Orchard Core site, head to Configuration -> Features and enable these features: Configuration Secrets Store: The secrets configuration store is a read-only store for secrets. Database Secrets Store: The secrets database stores encrypted secrets in the database. Secrets: The secrets feature manages secrets that other modules can contribute to. After you will find a new option under Configuration called Secrets. Here you can add two kinds of secrets: Authorization Secret: A secret used to manage a secure password or authorization key. Rsa Secret: A public / private RSA key pair used for encryption. Let's add a new Authorization Secret now and see what are Secret Bindings exactly? Secret Bindings can be used to enter secrets, like SMTP passwords. And you can choose where it's gonna come from. Right now they can be stored either in the database or in the configuration. But there is a plan to support the Key Vault provider as well. Let's use the smtp_password as the name and store it now in the Database Secret Store. And add the password into the Authentication String textbox. But how can use that secret? If you enable the Email feature, you can navigate to Configuration -> Settings -> Smtp and set up the network delivery options. If you put a tick on the Require credentials checkbox, you have to provide a user name and a password for authentication. If you would like to use your secret, you can use a Liquid filter to access the password stored in it. Here you can see that we entered the following Liquid expression to retrieve the password: {{ "smtp_password" | auth_secret }}. Remember, the smtp_password was the name of our secret. When we added our secret, we had the option to choose to create an Authorization Secret or an Rsa Secret. We created an Authorization Secret, so let's create an Rsa Secret this time! The RSA key pair is what we could use to actually crypt secrets when transmitting them to another server. At the moment the private key is in the editor, the idea is that once you created the private key you will never see it again. You can use the public key as an encryption key. Now let's create a new Deployment Plan and call it Secrets RSA! Add the All Secrets deployment step to it then hit Execute! After you will end up with a recipe that looks like the following. Here you can see the encriptionKey used for this particular recipe. It's a symmetric encryption key that is encrypted with the public key from the RSA key pair. Then all of the bindings that are available are here in the recipe. You will also find a decryptor here (js: decrypt()) which will use the encriptionKey and the private key on the other end to decrypt them. And when you run this recipe on your remote server - assuming you have installed the private key on the remote server - it will unencrypt your secrets correctly. But it's not all! If you would like to know more about this great upcoming feature, don't hesitate to watch the recording of it! Blazor WebAssembly with Orchard Core In this demo, you will see how to use a Blazor WebAssembly application that queries a blog post content through a REST API call using GraphQL. A JWT token used as a bearer token when calling the REST API GraphQL endpoint. Head to YouTube now to see the full demo! News from the community Orchard Dojo Newsletter Now we have 159 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!

Shape Components, new Anchor Tag Helper - This week in Orchard (11/09/2020)

We prepared with an interesting topic for this week about how could you use shapes like reusable Angular components? But before that, we checked the latest updates of Orchard Core, like the new updates around Tag Helpers. Orchard Core updates Add UI permissions based on the user role This is about hiding some buttons based on the permissions, instead of returning the 401 page when clicking on those. What do we mean? Well, let's say we have a permission that doesn't contain a role to publish or unpublish pages. That means users with that permission can't see the Publish button at the bottom of the editor in a case of a Page content item. Meeting information in the documentation When you open the Orchard Core documentation page and navigate to Resources, you will find a new link in the Resources column at the left called Meeting. If you click on that you will see a brand new page where you can find every relevant information about the steering committee and the triage meetings. Support for dropping a password from a password manager during setup Some password managers let you drag and drop a password to a textbox. During setup, if we do this rather than focus then type or paste, the tick appears in the input, but the strength indicator doesn't update and clicking Finish setup just does nothing with no indication. The fix was to update the strength.js file to check for the drop event. Add missing Tag Helper references The root of this issue was the Tag Helpers are found during development because of the runtime compilation. But when you change the environment from development to production, it stops working if you don't have a direct reference on the ResourceManagement project. The compilation doesn't find the issue, because it's a runtime resolution. Yes, you can use the a tag it will compile, but in runtime, it has a different behavior based on the projects you reference and you don't get the behavior you expect. The only thing you can do is to have a functional test to be sure that it would work. Tag Helper for the anchor tag with asset-href attribute Added an HtmlTargetElement to the Anchor Tag Helper to also address anchor tags with asset-href attributes. Added needed const and property and changed the Process logic to require non-null asset-href for anchor tags. So, if you use the asset-href in the anchor tag, it will convert the URL of a media URL to a public URL. Demos Shape Components What makes it hard to build a new site using Orchard Core? The ultimate solution would be to remove the templating in Orchard and just use decoupled. So, you don't have to know about shapes at all. And then you just write your pages, your controllers, you have lot's of APIs to get your content, you can reuse ASP.NET caching and do your decoupled site like this. It would be a decoupled site. Let's just forget about shapes and rendering everything from modules. Just let people render their own things and provide tools to render the site. It might be slower at first to build the site, but they will never be blocked by 'I don't know what a shape is.' or 'I don't understand how shapes work.', 'What is placement?' and so on. We have themes and recipes today that build some predefined solutions, like a blog or an agency site and they can be extended to anything. For that, you still have to understand all the shape- and display mechanisms to build these elements. A new solution would be to still create recipes, but recipes that would contain Razor Pages and controllers and anything that would build a blog even if we didn't have shapes and placement and everything. Like build a decoupled site that is a blog and this is the recipe. When you install it you have the same blog, the same theme working and if you want to change it, you don't have to learn shapes. You just look at the page that renders the blog, the blog post and you just change it. Or you create a new one and change the code directly. This would be just ASP.NET, there is nothing new to learn out of ASP.NET. That would be a solution to have. But let's say the issue is not about the shapes, because shapes are great. The issue is zones and placement. And these are harder to learn. Shapes in the end, if you just take shapes by themself, they are just dynamic ViewModels that have alternates and that can be rendered using templates. It's like a view component in ASP.NET. But it's like a view component with more features like it can have an ID, CSS classes, attributes, it can have dynamic behavior, it can have a caching, it has alternates. So, it has a dynamic resolution of templates, which the view component doesn't have. Let's think about a shape like a reusable component, like a view component in ASP.NET, but like an Orchard shape component, that can be reused. Were we able to pique your curiosity? Then just navigate to YouTube and see this exciting demo about shape components! News from the community Orchard Dojo Newsletter Now we have 160 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 .NET Analyzers, Shortcodes feature merged - This week in Orchard (04/09/2020)

We have mentioned the Shortcodes feature several times and now it's available in the preview packages of Orchard Core. We will also show a demo about how you can use our .NET Analyzers in your Orchard Core solution. Check out our post for more! Orchard Core updates Tabs syntax changed in the documentation Orchard Core documentation contains code samples both in Liquid and Razor languages. You can see the given code samples in tabs near each other. If you want to change between them you just need to click on the Razor or the Liquid tab to see the snippets. Now, if you would like to improve the documentation and put some snippet there too, you have to use a new syntax in Markdown. In the screen below you can see the old one in red, and the new one in green. Thank you for making the documentation better and better! Media root folder selected by default If you navigated to the dashboard of Orchard Core and opened the Media Library (Content -> Media Library) you may found that the images in the root folder were not available on the list on the right. The workaround was to create a new folder to see the files in the root. Now, this issue is fixed, the media root folder is selected by default and you are able to see the content in the media library without any workarounds. New icons for User Disabled and Enabled events A small UI change here. When you add a new User Disabled or User Enabled event to your workflow you will find new icons here. These icons are also used when you are working on your events on the kanban board of your workflows. Shortcodes feature merged Shortcodes are small pieces of code wrapped into [brackets] that can add some behavior to content editors, like embedding media files. The Image Shortcode can be used to display an image from the media library in your WYSIWYG editors. The simplest way to use that Shortcode is the following: . And the good news is that now you can find the Shortcodes and the Shortcode Template features in the preview packages of Orchard Core! In case if you missed you can find two videos on YouTube about Shortcodes: check out this one first, then watch this video for the second part of the demo! We also mentioned these features in This week in Orchard too several times. Check out this for an introduction, then this one for the first demo, finally don't forget to read this post to see the improvements of the Shortcodes! And the documentation is available in this URL! Update configuration documentation The documentation now contains more lines to explain how to read a configuration from an external config file, that you can use in your Startup class. Click here to see the updated page! New workflow task to validate user There is a new Validate User Task to check if the user exists for the current request and has the specified role(s). This task has three outcomes: InRole: if the user in the current request has at least one of the selected roles. Anonymous: if the user in the current request is anonymous. Authenticated: if the user in the current request is authenticated If you check the Set the 'UserName' workflow property if the user is authenticated checkbox, the username of the current user will be added to the Properties dictionary of the WorkflowExecutionContext that you can use in the upcoming tasks. Demos Lombiq .NET Analyzers Our Lombiq .NET Analyzers repository contains .NET code analyzers and code convention settings for Lombiq projects. We use these to enforce common standards across all our .NET projects, including e.g. in all of our open-source Orchard Core extensions. If you contribute to our open-source projects while using that solution you'll be guided by these rules too. There is a built-in code analyzer in Visual Studio, but there is a lot of other analyzer projects out there. These analyzers can find issues in your code, but this is about to extend that and try to find even more issues. The Readme.md file in the repository tells you how you can add these files to your solution in just two quick steps! Now let's see a simple example of this! Let's imagine that you have an interface with a method that represents an asynchronous operation. After we created our great interface with the method you will notice that the IDE complains about some stuff. First of all, we have an interface and a method in it with no documentation. The DoSomethingGreat method is an async method, so the correct name of the method would be DoSomethingGreatAsync. Pretty cool, right? But that's not all! Head to YouTube to see the full demo about Lombiq .NET Analyzers! News from the community Extending event handlers sample in the Lombiq Training Demo for Orchard Core Orchard Core Training Demo module is a demo Orchard Core module for training purposes guiding you to become an Orchard developer. You can use this module as part of a vanilla Orchard Core source that including the full source code - which is the recommended way. You can use it as part of a solution the uses Orchard Core NuGet packages, however, it's harder to look under the hood of Orchard Core features. The latest update of the module is about to show you how you can extend Orchard Core with event handlers. The LoginGreeting class is about to implement the ILoginFormEvent interface and shows a notification to the user after a successful login. Check out the code here! Orchard Core workshops The contributors of Orchard Core will hold some unique online workshops in September 2020. So even with Orchard Harvest postponed due to the coronavirus pandemic we'll get some new learning events. 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 160 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!

Shape Tracing Helpful Extensions, Alt and Class attributes for the Image Shortcode - This week in Orchard (28/08/2020)

New guides in the Orchard Core documentation to learn how to build a blog that allows users to login with their AzureAD account and gets assigned roles based on the Security Groups they belong to, and how to create a Deployment Plan to migrate from the File Content Definition feature. After we will show you our new Shape Tracing Helpful Extensions feature! Orchard Core updates Content definition stores guide Now you can find a new small guide in the Orchard Core documentation that explains what the File Content Definition feature is, and how to create a Deployment Plan to migrate from the File Content Definition feature. Implement class and alt attributes for ImageShortCode Shortcodes are small pieces of code wrapped into [brackets] that can add some behavior to content editors, like embedding media files. The Image Shortcode can be used to display an image from the media library in your WYSIWYG editors. The simplest way to use that Shortcode is the following: You can also provide several attributes, like the width, height, and mode. And now you can also pass the alt attribute that specifies an alternate text for an image if the image cannot be displayed. And you can pass your custom classes too! In the following line we used the Image Shortcode with multiple parameters: Users with Manage Users permission can't delete themselves or change their roles If you try to delete the admin account and you are currently the admin what you could do is actually block everyone from being able to edit the site if the admin is the only user. The idea here is that you can't delete yourself. If you navigate to Security -> Users and edit the admin user, you will see that the editor of the roles and the Is enabled? checkbox are disabled. Don't Detach a document already loaded for update This is about how documents are loaded from cache stores. If you use the ASP.NET caching abstractions you can store in the IMemoryCache or in the IDistributedCache. The main difference between these two is that in the IDistributedCache you would put stuff that has to be and can be serialized. In IMemoryCache you can put stuff that is not serialized. It's a live object that can be changed and updated. There is a new method for documents in the ISessionHelper called GetForCachingAsync that gets a single document (or create a new one) for caching and that should not be updated, and a bool indicating if it can be cached, not if it has been already loaded for an update. Note that for full isolation, it needs to be used in pairs with the LoadForUpdateAsync method that loads a single document (or create a new one) for updating and that should not be cached. When you call the GetForCachingAsync method you say that the object that you want to load from the database will be cached, which means you should not change it. You should not be able to update it, it's for caching. When you get a document from the database from this layer it will tell you if you are allowed to change it or not. This way you know you can put it in a durable cache or a live cache. Use Azure AD as an external identity provider guide In order to authenticate users with AzureAD, you must enable and configure the OrchardCore.MicrosoftAuthentication.AzureAD (you can learn more about here) and the OrchardCore.Users.Registration features. There is a new guide in the documentation where you will learn to build a blog that allows users to login with their AzureAD account and gets assigned roles based on the Security Groups they belong to. Demos Shape Tracing Helpful Extensions Lombiq Shape Tracing Helpful Extensions adds a dump of metadata to the output about every shape. This will help you understand how a shape is displayed and how you can override it. But let' see how you can use it in your solution! Imagine you have a NuGet-based Orchard Core solution and you would like to use the Shape Tracing Helpful Extensions. For that, you have to clone or download the orchard-core-preview branch of the Helpful Extensions repository that is targeting a recent nightly build of Orchard Core and you will only find the Shape Tracing Helpful Extensions in that branch. Now head to the GitHub repository of the Helpful Libraries module (same branch) and clone or download that too. You will need this library to use the Helpful Extensions. Now add these as an existing project to your solution and don't forget to check the project reference between these two! Reference the Lombiq.HelpfulExtensions module in your Web project and now you are ready to go! Set up a site using the Blog recipe then navigate to Configuration -> Features and search for the word helpful. Here you can find all of the following independent extensions of the module. If you are interested in the other ones too, check out the Readme.MD file of the repository for more! Now we will enable the Shape Tracing Helpful Extensions - Lombiq Helpful Extension feature. After you will get a dump about shapes in the HTML output. Just view the page source where you will see several comments in the code. These are generated when the shape is displayed that gives you some basic debug data. You can use these to actually override the shape. If you navigate to the detail view of the built-in blog post, you will see every relevant data that could be important for you to override the given shape, check the display type, the position, the differentiator, the wrappers of the shape and many more! But that's not all about Shape Tracing Helpful Extensions! If you would like to see more, don't forget to check out this recording on YouTube! News from the community Orchard Nuggets: How to debug a NuGet-based Orchard Core solution? How can you debug Orchard Core code when you're working with a solution that loads Orchard packages from NuGet? Easily! In our newest Orchard Nuggets post, we give you the answer! 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 September 2020. So even with Orchard Harvest postponed due to the coronavirus pandemic we'll get some new learning events. 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 160 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!

Shortcodes improvements, Lombiq Training Demo updates - This week in Orchard (14/08/2020)

This week we see the latest improvements of the Shortcodes module and the new pages of the Orchard Core documentation! Don't forget about our Traning Demo module, which has now got a new RESTful web API sample! Check out our current post for more! Orchard Core updates Highlight invalid fields When you have a driver for your content part or for your content field, the UpdateAsync method will be called when you are about to save and persist the new values of it. Let's say you have a TextField and you want to set it to be required. In the UpdateAsync method of the TextFieldDisplayDriver, we get the TextFieldSettings and if the value of the Required property is true and the Text property of the TextField has no value, then it's time to show an error for the user. Notice the second parameter of the AddModelError method. This is about passing a key to the ModelStateDictionary. The key would be the value of the Text property of the TextField and the Prefix would be the BlogPost.Subtitle string. But why is it important right now? Because there was an issue in Orchard Core about the different highlightings. If there is a validation error, it would be great to highlight the input editor, not just showing the validation summary at the top of the form. So, imagine you have a site installed with the Blog recipe and you set the Subtitle TextField of the Blog Post content type to be required. If you would like to save the existing blog post without providing a subtitle, the driver will pass the BlogPost.Subtitle as the Prefix and the name of the field.Text will be null. It's a small, but a good to know tip to provide a better user experience when editing values. Document Link Tag Helper There is a Tag Helper and a Liquid Helper in Orchard Core called Link that you can use to define the relationship between the current document and an external resource such as a favicon or stylesheet. This helper is available for a while, but there were no words in the documentation about it. Now you can find some lines in the documentation about how to use these helpers in your Orchard Core site. Add user updated event Two weeks ago we wrote about the new user deleted event, which is about to add a new DeletedAsync method to the IUserEventHandler. Now there is another new event for user events, that is about to occur when a user is updated. You can find the new UpdatedAsync method in the IUserEventHandler. And a new event is also accessible from your workflow type. If you create a new workflow type and click on the Add Event button, you will find the User Updated event in the User category. Password configuration documentation The password restrictions are set with the settings configured in ASP.NET Identity. Those options are used to define the required password strength when a user password is set. You can configure these requirements in order to specify properties like the minimal password length or if the process is expecting digits, uppercase, or non-alphanumeric characters. Check out the new how-to guide in the Orchard Core documentation to see how to change these settings and how to read configuration from an external config file! Demos Shortcodes improvements Two weeks ago we wrote about the upcoming Shortcodes feature for Orchard Core. Shortcodes are essential to WordPress, and for the Orchard Core, we wanted a similar feature. The parser was written by hand as the syntax is simple and it needs to be efficient. Check out that post if you haven't read that yet and don't forget to watch the recording on YouTube about that too! Now, let's continue from where we left off and see the newest improvements in that module! Set up your site using the Blog recipe, then head to Configuration -> Features to enable these features: Shortcode Templates: The Shortcode Templates feature provides a way to write custom shortcode templates from the admin. Shortcodes: The Shortcodes feature adds shortcode capabilities. Now head to Design and notice that the Shortcode Templates options is renamed to Shortcodes. Click here and add a new Shortcode! Here you will meet with a slightly changed editor. The first thing that you will notice is when you are starting to fill out the Name, the Hint, and the Usage inputs you will get a live preview in the right about how the card of the Shortcode will look like. You can ask what card do we mean, but let's not move so fast! The Categories selector is now working the same when you add tags to your blog post. You can type to search for the existing categories or add a new category right here from the editor. The Content will be about having the logic of the Shortcode. Here we create a Shortcode called safeimage, it means we sanitize the input from the user before rendering the content. We also created another Shortcode called unsafeimage. That would be the same, the only difference is we didn't call the sanitize Liquid helper. Now edit the Article content item named About. The HTML editor here has the Insert Shortcode button on the toolbar. Click on it and now you will see the cards we have just mentioned a few lines ago! Here you can filter by the name of the Shortcode and can filter by categories. Now let's try out the unsafeimage and the safeimage Shortcodes! After editing the code we have the following lines in the HTML body: unsafeimage: [unsafeimage]media/samoyed.jpg" onload=alert('xss')[/unsafeimage]unsafeimage: [unsafeimage]media/samoyed.jpg[/unsafeimage]safeimage: [safeimage]media/samoyed.jpg[/safeimage] Notice the script in the first line! Because we added this inside an unsafeimage Shortcode, it will render the alert when the user views this page. If we would put this little hack inside a safeimage Shortcode, then it would prevent the alert to appear. But that's not all about Shortcodes! If you would like to see more, don't forget to check out this recording on YouTube! News from the community RESTful web API sample in the Lombiq Training Demo for Orchard Core The Lombiq Training Demo for Orchard Core is a demo Orchard Core CMS module for training purposes guiding you to become an Orchard developer. You can use this module as part of a vanilla Orchard Core source that includes the full source code - which is the recommended way. You can also use it as part of a solution that uses Orchard Core NuGet packages, however, it's harder to look under the hood of Orchard Core features. And the module just got a new little RESTful web API sample! Check it out if you're learning Orchard and want to develop web APIs! Orchard Core workshops The contributors of Orchard Core will hold some unique online workshops in September 2020. So even with Orchard Harvest postponed due to the coronavirus pandemic we'll get some new learning events. 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 157 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!