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

Featured tags

IIS
API
SMS
All tags >

Extend user permissions, add Contained Stereotypes Bag Part Settings - This week in Orchard (30/09/2022)

Add Contained Stereotypes Bag Part Settings to allow a user to include content types by stereotype, add Displayed Stereotypes property to Content Picker Field Settings, demo about extending the user permissions, and many more waiting for you in our current post! Orchard Core updates Add Contained Stereotypes Bag Part Settings to allow a user to include content types by stereotype When attaching Bag Part to a content type, the user must explicitly set Contained Content Types with an array of content types to be included in the Bag Part. This is good for most cases; however, it would be great to allow for setting the contained content types using Stereotype. The stereotype would be in addition to not in place of Contained Content Types. For example, we want to group all Contact Methods (phone number, address, email address, etc.) by a stereotype type called ContactMethod. All of these content types share a similar functionality which is a way to contact a person. Now we created a Person content type and attached a Bag Part to it. In this case, we had to explicitly specify each content type in the Contained Content Types. But if a new content type was added later from other feature/module, the user would have manually to edit the Bag Part settings every time/everywhere ContactMethods are used to add the new content type which isn't efficient. So now the Bag Part is more flexible. And as you can see here, now we have two radio buttons under the Contained Content Types option where the user can select Content Types or Stereotype. Add Displayed Stereotypes property to Content Picker Field Settings And this one is quite the same as the previous feature but for the Content Picker Field. For example, we want to group all to-do items (appointments, meetings) by a stereotype type called ToDoTask. All of these content types share similar functionality which is a to-do task. Now we want to use Content Picker Field in a different content type to allow the user to select a to-do-task of any kind. In this case, we have to explicitly specify each content type in the DisplayedContentTypes. But if a new content type was added later from another feature/module, the user would have to manually edit the Content Picker Field settings all time. Everywhere to-do tasks are used to add the new content type which isn't efficient. So, let's say we navigate to the editor of a Content Picker Field. And here you can say that you can select the Contained Content Types to: Display All Content Types Content Types Stereotype Add settings to form widgets There was a bug in OC. The option editor wasn't loaded when trying to add Select Input while creating a form. Also, the edit button did not open the modal that would allow you to populate the options using JSON. If the content is saved, and the page is loaded again then the modal and the options editor work just fine. Another form-related improvement is validation. When creating a form using the Form input widgets like (Input, Select, and Text Area) there is no easy way to add a label and validation elements to the input. The current approach is to add a label widget and then a validation widget which is not always ideal. We can make this process much simpler by adding settings to the Input, Select, and Text Area widgets with the following properties: LabelOption an enum value with the following values (None, Standard, ScreenReaders). By default, None is selected to keep it backward compatible. ValidationOptions an enum value with the following values (None, Standard). By default, None is selected to keep it backward compatible. Now, if the user selects an option other than None in the settings, we’ll create the label in the same widget block. The same applies to ValidationOptions. This will make things like dragging/dropping widgets during edit and controlling the size much easier. At the same time, we output less HTML code. And if we add the validation rules, we’ll have more validation logic which makes the widgets more useful. And now, the editor of the Select Input looks like the following with the additional options. And of course, the same applies to all of the built-in form inputs. Demos Extend user permissions A couple of months back there was a need reported to have some roles to be able to edit a user and some not. And there is a conclusion that the user interface is not very flexible at the moment with the permissions. So, it kind of makes it hard if you have a unique case where you need some specific users to be able to do stuff. And also, to set up who can see what users, when you are listing the users. To be able to test out this feature with us, you have to check out this PR on GitHub. The first thing that you will notice is the new permissions regarding Users. In this case, we navigated to Security -> Roles and edited the Moderator role. There are new permissions, for example, Assign any role, Delete any user or Delete users in role - Administrator, List all users, etc. So, you can say you can list all the users, but it doesn't mean you will be able to edit all the users. If you try to edit a given user, you will notice something new here. As you can see, the user name of the user is not editable, but you can edit the email address of the given user. This is controlled by settings that you can reach under Configuration -> Settings -> User Profile Settings. As you can see, here you can allow or deny changing the user names or email addresses of the users. But now back to the users' list. Let's say we have some predefined users and made some changes regarding the permissions of the Moderator role. Now, we logged in with a user who has the Moderator role. After that, the user with the Moderator role will see something like this. First of all, you can notice that there is a little badge under every user that shows the roles the user has. You can also see that this user has permission to see users in the Editor role, but they can't edit or delete the editor user. Now let's edit the author user! Here you can see that this user can edit the settings of this user but can't fully manage the roles of the author user. They have the option to add or remove the Author role but that's it, nothing more. And we are just showing you some simple scenarios about what you can achieve and how you can customize the user permissions. If you want to see more complex scenarios, head to YouTube for a recording! News from the community Helping Global Health build an Advanced Form Builder using Form.io When Global Health from Australia approached us with the request to build an advanced form builder using Form.io, it promised to be an interesting project. They were looking to integrate this new form builder deeply into MasterCare+, their Multi-Tenanted SaaS-based platform for Health Care which is built on Orchard CMS. It would allow creating custom forms for a wide range of scenarios in the health care domain, using the advanced editing capabilities of Form.io. The solution built by Lombiq was an important step in bridging the gap between paper forms and electronic health care management. Check out the full post here! Orchard Dojo Newsletter Lombiq's Orchard Dojo Newsletter has 354 subscribers! We have started this newsletter to inform the community around Orchard of the latest news about the platform. By subscribing to this newsletter, you will get an e-mail whenever a new post is 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 Orchard meeting!

Archive Later Feature, Notifications Feature - This week in Orchard (23/09/2022)

Archive Later Feature, extract GetLanguageDirection() and IsRightToLeft() to CultureInfoExtensions, introduce EnabledByDependencyOnly flag for features to allow the feature's state to be auto, and a demo about a feature called Notifications! Check out our post for the details! Orchard Core updates Archive Later Feature Back in 2020, we mentioned the Publish Later Feature which adds the ability to schedule content items to be published at a given future date and time. Now here comes the Archive Later Feature, which provides a way to unpublish content items at a given time. Let's see a simple example of the usage! Open up the admin UI of Orchard Core and head to Configuration -> Features and enable the Archive Later module. If you would like to use this feature with your content type you have to edit its definition by attaching the Archive Later Part to it. Let's attach the Archive Later Part to the Blog Post content type! Now let's edit our predefined blog post! At the bottom of the editor, you will see a new input Tag Helper with the datetime-local input type. If you set the date and the time here and hit the Archive Later button, the status of the current version will automatically change to draft when the time goes by using a background task. We also have a Cancel Archive Later button, so we can cancel the archiving process. And in the SummaryAdmin list, you also had a little message that shows you the date and time when the content item will be archived. Extract GetLanguageDirection() and IsRightToLeft() to CultureInfoExtensions We have some extension methods for CultureInfo to deal with language direction. These extension methods were placed in the LanguageDirection class and now they have their own class called CultureInfoExtensions. So, from now on you can find these extensions here. Small change but nice to have extension methods in a separate class. Introduce EnabledByDependencyOnly flag for features to allow the feature's state to be auto To represent this new change, we will use the features that you can check out in detail in the demo down below regarding the Notifications Feature. So, let's say you are on the Features page and search for the "notifications" word. Here you can find the Notifications module, which is only enabled if you enable one of its dependencies. So, you can't enable it right away. But the Email Notifications module requires it, meaning if you enable the Email Notifications module, the Notifications module will be enabled as well. And if you disable the Email Notification module, the Notifications module will be disabled as well because none of its dependencies are enabled. And it's a flag that is very easy to use! If you open up the Manifest.cs file of the OrchardCore.Notifications module (can be found in this branch), you will see the feature with ID OrchardCore.Nofitications has this property set to true. It means that if we enable one of the dependencies of this feature, this module will be automatically enabled. And if none of the dependencies of this feature are enabled, then this module will be automatically disabled. Demos Notifications Feature The Notifications Feature provides a way to be able to send notifications to notify users. You could implement a push notification to a mobile phone, you could implement a web notification, you can have an email notification, etc. For right now you can see the implementation of the email notification, and the Email Notifications module is the one that provides you with this feature. Let's enable it! After that, we can edit one of the existing users on the site and say that we want to send email notifications to this user. And if you implement a push notification or a web notification, then you will see a flag for those as well and we can set up what kind of notifications we want to send to the given user. But this might feel incomplete without the Notification Templates feature which provides a way to create notification templates. Let's enable this one as well! And this will mean that now we can create new Notification Template content items. Let's create a new one and call it "Welcome email for new users template". We will send this email any time a new user is created. Here you can select the provider that you want to utilize, let's select the New user notification here. And as you can see, you have a subject and a body. There are also username, password, and email arguments, that we automatically create because this provider is aware of them. It means you can inject these into the subject and the body of the email that you want to send. The idea here is if you create a new user as an admin you might want to send their temporary password in an email. Here you can use Shortcodes and Liquid templates as you can see. So, we mentioned that we have a New user notification provider. If you enable the third notifications-related feature, called Notification Templates for Contents, it will give you more providers to use. So, if we create another Notification Template, now we can select the Content based notification provider too. It provides you with more templates (DisplayText, ContentItemId, ContentType, etc.) because it has more awareness. At the bottom, you can control who should be the person who receives this. But here right now you don't have the way to select that I want to send out this notification when someone publishes the Article content type. So, selecting the content type and the event is not here. To do that, you have to edit the content definition of a given content type. If we select the Blog Post one, for example, you can see a new setting, called Notifications. If you select to send a notification, you can define which event you want to use and the given notification template. This feature is a PoC and if you want to check out the implementation or try it out in your solution, you can find the code in this branch. And if you prefer videos, check out this recording on YouTube to see more about this feature! News from the community Orchard Dojo Newsletter Lombiq's Orchard Dojo Newsletter has 350 subscribers! We have started this newsletter to inform the community around Orchard of the latest news about the platform. By subscribing to this newsletter, you will get an e-mail whenever a new post is 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 Orchard meeting!

Add fallback alternate when a custom stereotype is used, tenant removing - This week in Orchard (16/09/2022)

Add fallback alternate when a custom stereotype is used, validate database connection before allowing a tenant to be added or set up, remove localization workaround in Data Annotation Attributes, and a demo about the upcoming tenant removing feature! Check out our post for the details! Orchard Core updates Add fallback alternate when a custom stereotype is used The idea here is that when you create a stereotype, before this change, you had to create templates for this stereotype if you intended to display or edit items of this stereotype. And now, there is a fallback shape for stereotypes such that if you don't create custom templates, it will use a standard, default template that is valid for any stereotype. How it works is just to let's use the Content shapes for anything when we don't have a custom template. It prevents showing error messages when you create a stereotype and try to create a content item from this stereotype. And you can test this one easily. Just navigate to the admin UI of Orchard Core and head to Content -> Content Definition -> Content Types, where you can find the Create new type button to define your new content type. Add a name to it and hit Create. We will not add any Parts to it right now. Set the Stereotype to Cat and hit Save. Now we can create a new Animal content item by clicking on the New button and selecting Animal under Content -> Content Items. And as you can see, Orchard Core now renders the default Content_Edit template as a fallback instead of throwing an exception. Validate database connection before allowing a tenant to be added or setup When adding a new tenant, we allow the user to set a prefix to the tables to enable reusing the same database for multiple tenets. However, we don't validate that the prefix isn't already used first. The problem with this is that it throws an exception. Let's say we have a tenant with a URL prefix test and we selected the SQLite database. Now let's create another tenant using the same URL Prefix and database preset. As you can see, now we have a validation error. But we also have validation for connection strings as well. Let's say we would like to use SQL Server and provide a connection string that is invalid. In this case, you will face an error like "The provided connection string is invalid or server is unreachable". Remove localization workaround in Data Annotation Attributes Two years ago, when Hisham Bin Ateya started the support data annotations PO localization PR, there was a long discussion to support localization in data annotations. Back in the day, Antoine Griffard did a workaround to achieve the goal by using IValidatableObject, and now it's time to remove this workaround and use the new way of doing this. This means we can remove the need of implementing the IValidatableObject from several ViewModel. And from now, on you can use some attributes which help you print localized error messages. And now there is an attribute for email validation and URL validation as well. Let's see an example quickly! As you can see here, the RegisterViewModel implemented the IValidatableObject to be able to validate the properties inside the class. Now, instead of using the IValidatableObject, we can add attributes to these properties, and here comes the new EmailAddress attribute as well. As you can see from the screen, the new implementation of the ValidationAttribute can be used to validate your model by returning a localizable error message. Demos Tenant Removing The option to be able to remove tenants is a long-requested feature, and for now, we are very close to shipping this feature, thanks to Jean-Thierry Kéchichian. Let's see how it will work! For this demo, we will navigate to GitHub and checkout this branch. Now, let's add some tenants to be able to try out this feature. As you can see, we have added 3 tenants. The Agency and the Blog ones are tenants that we have already set up, but the tenant called test is waiting for setup. Here you can see that we have the Sites folder under App_Data where each of the tenants has its own folder containing the Media files for example. And now we also have a wwwroot folder under OrchardCore.Cms.Web, which contains a folder per tenant like in the previous case. This means now each tenant can manage their own cached files under wwwroot. When we remove a tenant, the logic will also remove the folder of the tenant under the wwwroot and the Sites folders. And now it's time to delete a tenant! To be able to delete a tenant, we should disable it first, which means it will be not served, and we will be able to compose an internal ShellContext with all the features that the tenant has, even if it is installed or not. You can also remove multiple tenants by using bulk actions. And this is just the surface, there are still some things to do. If you would like to see the current state of this feature and do a deep dive under the hood, check out this recording on YouTube! This feature is sponsored by Lombiq. News from the community Orchard Dojo Newsletter Lombiq's Orchard Dojo Newsletter has 347 subscribers! We have started this newsletter to inform the community around Orchard of the latest news about the platform. By subscribing to this newsletter, you will get an e-mail whenever a new post is 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 Orchard meeting!

Content Relationships guide, Orchard Core Commerce Stripe Payment - This week in Orchard (09/09/2022)

It's time to publish the results of the Orchard Core Commerce survey and the topics that made it into the MVP as the short-term goals. And we have just added Stripe payment integration to the checkout process! Check out our post for the details! Orchard Core updates Content Relationships guide How can you relate (connect) content items to other content items in Orchard Core? When would you use each built-in option? This new guide aims to clear up the available options by detailing: Bag Part (BagPart) for Embedding Content Items within a Parent Item Content Picker Field for Many-to-Many Relationships of Specific Items Flow Part (FlowPart) for Building Structured, Responsive Layouts List Part for One-To-Many Hierarchical Relationships Taxonomies for Categorization and Tagging Demos Orchard Core Commerce Stripe Payment Orchard Core Commerce will be an Orchard Core port and partial rewrite of the open-source Nwazet Commerce module that was built for Orchard CMS 1.x. Nwazet Commerce was initially built in 2012 by Bertrand Le Roy, loosely based on a commerce sample by Sipke Shoorstra. The initial goal of Nwazet Commerce was to power the website of the hardware startup Nwazet. While Nwazet is no longer operating, the Nwazet Commerce project went on and was further developed by a group of passionate contributors who are using the platform for their own, and their customer's websites. Like Orchard, Nwazet Commerce was built with extensibility in mind, and as such, it has its own extensions (typical examples include local tax and shipping modules). It's also pure, idiomatic Orchard. Orchard Core represents a major evolution of the Orchard design principles and is sufficiently different that running Nwazet Commerce on it will necessitate significant work. As such, the community decided that starting from a blank slate was the best way to go, so they will port Nwazet Commerce piece by piece, being careful to accurately apply Orchard Core's new design principles. The community also decided to adopt a new name that gets rid of the now obsolete origins and establishes our ambition for the module to become the go-to commerce module for Orchard Core. And at the beginning of May, we published a demo where you could see the current state of the module. This time we will see a demo about the basic implementation of Stripe Payment integration (without taxation, shipping, etc.). Stripe is a payment service provider that business owners can use to accept dozens of payment methods, from credit cards to buy now, pay later services. Stripe Payments handles the steps between a customer providing their card information and learning that their payment has been accepted. You can try out the Orchard Core Commerce solution just by cloning the repository from GitHub, or you can download it as a NuGet package as well from NuGet.org. For this demo, we will set up our site by using the OrchardCore Commerce - Development recipe, which adds some built-in content to our site that we can use during development (and during our demo of course). After, we can head to Configuration -> Features and enable the three commerce-related modules: Orchard Core Commerce: Registers the core components used by the Commerce features. Orchard Core Commerce Session Cart Storage: Registers session-based shopping cart persistence. Orchard Core Commerce Settings Currency Selector: Currency selector that uses display currency configured in settings. Useful for Dev/Test scenarios. Now we can set up the Stripe API (Configuration -> Settings -> Stripe AP) by providing the publishable and the secret key. These keys are publicly available test keys, so feel free to use them for testing and development. The Readme.md file of the Commerce module also contains these keys. Now let's navigate to Content -> Content Items to check our predefined content items. The Product is a content type that can be added to the cart, and users can pay the price of the products. We have one, called TestProduct, let's add another one called Cheese. Here you can see we can set up the name, the SKU, and the base price of the product with the currency used as well. Let's say this Cheese will cost 4.50 USD. Now it's time to add the predefined product and the Cheese to the shopping cart! You can do that by navigating the details page of a product, and after setting up the quantity, you can click on the Add to cart button. Let's say we would like to add one Cheese and one TestProduct to our shopping cart. The shopping cart is available under the /cart URL, but the site will redirect you to this URL too, if you click on the Add to cart button. As you can see here, our cart contains two items: one TestProduct with a price of $5.00 and one Cheese with a price of $4.50, which costs $9.50. It's time to pay by clicking on the Checkout button! On the checkout page, you can set up your billing address and shipping address but let's focus on the credit card field right now, which comes from the Stripe API. You can find some credit cards in the Stripe documentation and in the Orchard Core Commerce Readme that can be used for testing different scenarios. Like handling a card that has insufficient funds or which has expired. But you can also use a card that requires 3D Secure 2 authentication. The 3D Secure standard - often known by its branded names like Visa Secure, Mastercard Identity Check, or American Express SafeKey - aims to reduce fraud and provide added security to online payments. 3D Secure 2 (3DS2) introduces "frictionless authentication" and improves the purchase experience compared to 3D Secure 1. It is the main card authentication method used to meet Strong Customer Authentication (SCA) requirements in Europe and a key mechanism for businesses to request exemptions to SCA. It means you cannot pay right away because you will see Stripe's own 3DS2 authentication panel. In live mode, you can see the bank's authentication panel here. If you click on the Complete button here, you can imitate that the purchase was successful. And in that case, the module will redirect you to a "Thank you for your purchase" page. And after a successful payment, a new Order content item will be created, which you can see on the content items list. Right now, the Order content item contains an automatically generated Order Id, a list with the charges (kind, amount, charge text, etc.), and the status of the order. The order contains the billing address and the shipping address as well. And that's not everything! If you want to know more regarding the current state of the Orchard Core Commerce module, don't hesitate to check out this recording on YouTube! News from the community Orchard Core Commerce survey results and MVP As you may know, Lombiq provides stewardship for the Orchard Core Commerce module. That actually means that we will do code reviews and work on features and fixes. To have that, we started this thread and added an Orchard Core Commerce MVC planning survey. This was about asking the community what the most essential features for you would be in an Orchard Core-based e-commerce solution. And now, we have the results and published an announcement of what will be in the MVP and the short-term vision of the project. Thanks to your feedback, we have a more straightforward impression of the community's priorities, and some new developments are already coming in. Feel free to check it out and join the discussion especially related to the bigger issues like taxation or discounts. Orchard Dojo Newsletter Lombiq's Orchard Dojo Newsletter has 345 subscribers! We have started this newsletter to inform the community around Orchard of the latest news about the platform. By subscribing to this newsletter, you will get an e-mail whenever a new post is 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 Orchard meeting!

Add PagerOptions, Output Caching for ASP.NET Core 6.0 - This week in Orchard (02/09/2022)

Fix the password generator to meet the password requirements, add PagerOptions, and a demo about Output Caching for ASP.NET Core 6.0! Let's get started! Orchard Core updates Fix the password generator to meet the password requirements A few weeks ago, we mentioned that you have the option to generate passwords on the user creation form. But how can you do that? Head to the admin UI of Orchard Core and navigate to Security -> Users. Here you will find the Add User button. Click on it! This will navigate you to the create user page, where you can find this feature, where you can provide a password for the newly created user, and you have the option to generate a random secure password or copy the password to the clipboard. The password generator had an issue which was password randomness occasionally omits a special character or number. Password should include a number, lower and uppercase letter, and special character. Now, this has been fixed, and the generated password meets the requirements described here. Add PagerOptions When you navigate to Configuration > Settings -> General, you have the option to set up the default page size which is the default page size of lists. But you also have the option to define the maximum number of pages that can be paged (MaxPagedCount) and the maximum page size that can be set by a user (MaxPageSize). And from now on, you can define the pager options using appsettings.json as well. Here you can see that you can easily set up the values for all three properties. Demos Output Caching for ASP.NET Core 6.0 Output caching stores the generated output of pages, controls, and HTTP responses in memory. Output caching enables you to cache different versions of content depending on the query string and on form-post parameters to a page, on browser type, or on the language of the user. And now, .NET 7 has an Output caching middleware with a sample that illustrates the usage of ASP.NET Core Output caching middleware. The application sends a Hello World! message and the current time. A different cache entry is created for each variation of the query string. If you open up the Startup.cs file of this sample, you can see how to set up Output caching. You just need to say app.UseOutputCache(); and by using the AddOutputCache, you can use some options as to what to cache and how to cache it. You can cache a given endpoint as well by just saying app.MapGet("/query", Gravatar.WriteGravatar).CacheOutput(p => p.VaryByQuery("culture"));. But it's only available in .NET 7.0 preview and not in .NET 6.0. Sébastien Ros published a custom package to NuGet that copies the code from the ASP.NET Core repository but targets 6.0. It could be done because there is nothing in this feature that requires things from .NET 7.0. And Orchard Core targets .NET 6.0., so you can have Output caching in Orchard Core! But how can you do that? Let's say you add a new module to Orchard Core and reference the Preview.OutputCaching NuGet. Now you have to modify the Startup.cs file of your module. The code is very simple, in the ConfigureServices, we call AddOutputCache, and in the Configure we say UseOutputCache. But there are lots of options to configure policies and roles. So, by default when you use AddOutputCache, it doesn't cache anything until you tell what to cache (like a route, an action, path, etc.). By calling the options.AddBasePolicy(build => { });, it will just enable the default policy on everything, which is to cache everything. But only if it's a GET request and only if the user is unauthenticated. Now let's try out this feature! Open up the homepage of your site and check the Network tab of the DevTools window when using Chrome. Here you can see a new Response Header called age, with a value of 9. The age header contains the time in seconds the object was in a proxy cache. This means this is a response from the cache, and the cached value is from 9 seconds ago. The default cache, in this case, was 1 minute, after 1 minute it got a fresh entry, and by refreshing this page you can see the increasing value of the age header. After it reaches 60, the counter will start from 0 again. Interested in how to customize Output caching or maybe you would like to help the community build a module for Orchard Core that provides Output caching? Then check out this recording on YouTube for more! News from the community Orchard Dojo Newsletter Lombiq's Orchard Dojo Newsletter has 343 subscribers! We have started this newsletter to inform the community around Orchard of the latest news about the platform. By subscribing to this newsletter, you will get an e-mail whenever a new post is 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 Orchard meeting!

Prevent Trumbowyg from converting <div> to <p> element, Elasticsearch feature - This week in Orchard (26/08/2022)

Prevent Trumbowyg from converting <div> to <p> element, reduce memory when reloading settings of a given tenant from the database, and a demo about the upcoming Elasticsearch feature! Let's get started! Orchard Core updates Prevent Trumbowyg from converting <div> to <p> element When using HtmlBodyPart or HTMLField with either WYSIWYG or Trumbowyg, the editor converts <div> elements to <p>. Also, when the user switches into code insert mode, the text area does not take up the full size of the editor. Steps to reproduce the behavior: Add HtmlBodyPart or HtmlField to a content type, and use either WYSIWYG or Trumbowyg editors. Create new or edit an existing content item. Click on <> of the editor to switch into code insert mode and insert the following. The issue is that the Semantic option is enabled by default. By enabling Semantic, it generates a better, more semantic-oriented HTML (i.e. <em> instead of <i>, <strong> instead of <b>, etc.), meaning: $('.trumbowyg').trumbowyg({ semantic: { 'b': 'strong', 'i': 'em', 's': 'del', 'strike': 'del', 'div': 'p' }}); The idea is that the "Wysiwyg" editor option should not alter the "Tryumbowyg" editor default behavior. This is why we have the "Trumbowyg" editor option that allows changing its behavior for your own needs. So, the fix was to set the semantic: false on the Wysiwyg templates and don't change anything on the Trumbowyg templates. Reduce memory when reloading settings of a given tenant from the database There appears to be a memory leak caused by the usage of IConfiguration as the backing for ShellSettings. Memory used by each ShellSettings instance is not being freed for garbage collection due to some fairly crazy gcroots even if you intentionally release the ShellSetting. Most of the memory is being used by Strings related to the DatabaseShellsSettingsSources with the VersionId field being the largest consumer of memory. The problem is that the DatabaseShellsSettingSources contains data for ALL tenants (which can be 2000+ in some cases) even if you're only loading/reloading a single tenant. So, among our tenant config/settings sources, one of them is by default the tenants.json file. In fact, when we reload a given tenant, we don't need all data from this source but only those related to this tenant. When we add this source to the config stack of a given tenant, if we still use builder.AddJsonFile() we have no choice, we can't split this file into smaller parts per tenant. But when this source comes from the database, we do a builder.AddJsonStream() on a MemoryStream that holds all data of this source, so here the idea is to only hold in memory the data related to this tenant. To do so Jean-Thierry Kéchichian added a method to the interface of this source allowing to pass a tenant name. So that when the source comes from the database, each time we reload a specified tenant we still create a MemoryStream but that only holds the data related to this tenant (not all tenants). When calling this new method on the other implementations of this source, they just ignore the provided tenant name by calling the existing method without this parameter. Demos Elasticsearch feature Elasticsearch is a search engine based on the Lucene library. It provides a distributed, multitenant-capable full-text search engine with an HTTP web interface and schema-free JSON documents. This time we will see how you can use Elasticsearch in Orchard Core using the Elasticsearch feature, which can be found in this pull request and will be released soon. The Readme.md file of the module describes how you can use this feature for development and testing purposes by using Docker. We won't go into the details of how to install Docker and use the Docker Compose file, the Readme.md file mentioned has a nice step-by-step tutorial about that part. So, let's say we have a Docker container running the Elasticsearch image on port 9200 (the default one). The Elasticsearch module connection configuration can be set globally in the appsettings.json file or per tenant. The connection types documentation and examples can be found at this URL. To try out this feature, you need to enable the Elasticsearch feature under Configuration -> Features. You can also see a Content Picker for Elasticsearch, just like we have for Lucene, and a Worker. And of course, don't forget to enable the Search module as well, which adds front-end search capabilities. We will use this feature to try out the new Elasticsearch feature. The Elasticsearch module has some settings in the admin, where you can configure the search settings for the module (Search -> Settings -> Elasticsearch), and you can decide which fields you want to use for the search pages. It's quite the same as Lucene's settings, but it's a separate page because you can index different fields for Elasticsearch and Lucene. And for the search form, we can decide which provider we want and it will work at runtime. This means you can seamlessly switch from one indexing provider to another one. You can set this up under Search -> Settings -> Search. If you navigate to the default URL of the search form (/search) you can use this form as you would use it in the case of Lucene. But of course, you need to have an Elasticsearch index that you can use while doing a search and the indices can be set up under Search -> Indexing -> Elasticsearch Indices. As you can see, here we created a new index called default_search and indexed some content types. And now, you can use the search form to return results based on your query. The default_search index contains the Article and the Blog Post content types, so if we use the "man OR about" query, the site will return us two results, the default blog post, and the default article content items. And we are just scratching the surface here. The Readme.md file contains a lot more: how to create an Elasticsearch index during recipe execution, how to create an Elasticsearch query from a Queries recipe step, how to use Web APIs to execute a query, and a lot more! Check out this recording on YouTube if you would like to know more about this upcoming feature! News from the community Orchard Dojo Newsletter Lombiq's Orchard Dojo Newsletter has 341 subscribers! We have started this newsletter to inform the community around Orchard of the latest news about the platform. By subscribing to this newsletter, you will get an e-mail whenever a new post is 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 Orchard meeting!

Allow case-insensitive tenant names in ShellHost, Lombiq PowerShell Analyzers - This week in Orchard (19/08/2022)

A new HttpBackgroundJob helper component, allow case-insensitive tenant names in ShellHost, and a demo about the Lombiq PowerShell Analyzers! Let's get started! Orchard Core updates HttpBackgroundJob helper component The HttpBackgroundJob component allows executing a background job in an isolated ShellScope after the current HTTP request is completed. It allows a controller (or a Razor Page) action to return without waiting for a job to complete, and then, if the job updates some state data, also allows to render the job state. Allow case-insensitive tenant names in ShellHost Let's say you created a page where a user can log in to a specific tenant by providing the tenant's name, username, and password. To identify which tenant the user is trying to access you can use _shellHost.TryGetSettings(tenantName, out settings), which looks up the tenant by name. The issue here is if the user does not provide a case-sensitive tenant name, the ShellHost does not find anything. The solution here is to define case-insensitive dictionaries. Then we would not need any more in some places to do an explicit case insensitive lookup. Check out the _shellContexts and the _shellSettings ConcurrentDictionaries on the screen below. Demos Lombiq PowerShell Analyzers The Lombiq PowerShell Analyzers provide PowerShell static code analysis via PSScriptAnalyzer and Lombiq's recommended configuration for it. Use it from the CLI, in GitHub Actions, or integrated into MSBuild builds. To use the PowerShell Analyzers: You must have PowerShell 7 or greater installed. The PSScriptAnalyzer module must be installed. The script will attempt to auto-install it, however, if this fails (e.g., on Windows PowerShell, you have to be an admin to install modules), follow the steps here. If you have the PSScriptAnalyzer module installed, you can use Lombiq PowerShell Analyzers to have a static analysis of your PowerShell scripts. As you may know, Lombiq's Open-Source Orchard Core Extensions is an Orchard Core CMS Visual Studio solution that contains most of Lombiq's open-source Orchard modules and themes, as well as related utilities and libraries. Please keep in mind that only those extensions included that use the latest released version of Orchard (i.e., the very cutting-edge ones depending on a nightly build are not yet here). This solution contains the Lombiq PowerShell Analyzers as well, so we will use this one for the demo. If the Lombiq PowerShell Analyzers project is included via a submodule, edit the csproj file of your primary project(s) and add the following: <Import Project="path\to\Lombiq.Analyzers.PowerShell\Lombiq.Analyzers.PowerShell.targets" /> This way you associate the analyzer with a .NET project, and MSBuild automatically invokes analysis before building. If the analysis passes, it creates a timestamp and won't perform the analysis again until a new script file has been added or an existing one modified. As you can see, the Lombiq.OSOCE.Web.csproj contains this line by default. You don't need to <ProjectReference> Lombiq.Analyzers.PowerShell.csproj. If you include the project as a NuGet package, it will work as-is. Just clone this repository and try to add some bad PowerShell scripts to it. Our goal here is to have some build errors when building our solution using Visual Studio. Now, it's time to write some bad code! Here we added a Violate-Analyzers.ps1 file to the Lombiq.OSOCE.Web project and built the solution. As you can see, the build failed with errors that say we have some issues in the Violate-Analyzers.ps1 file. And that's just a quick demonstration about how to use the PowerShell Analyzers with MSBuild. You can use it with Visual Studio Code, PowerShell CI, and GitHub Actions as well. If you are interested in how to do that, check out the Readme file of the project or head to YouTube for a recording! News from the community Orchard Dojo Newsletter Lombiq's Orchard Dojo Newsletter has 331 subscribers! We have started this newsletter to inform the community around Orchard of the latest news about the platform. By subscribing to this newsletter, you will get an e-mail whenever a new post is 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 Orchard meeting!

Admin Culture Picker, Enhance BagPart to honor permissions - This week in Orchard (12/08/2022)

Enhance BagPart to honor permissions, add permissions for the Amazon S3 module, improve the workflow function description in the document, and a demo about the Admin Culture Picker! Let's get started! Orchard Core updates Enhance BagPart to honor permissions Let's say you want some users to be able to add content items to a specific bag while others to only be able to view only existing items. Currently, any content item contained in a BagPart is always editable regardless if the contained item is securable or not. In most cases, this is fine. However, this function should also be extended to honor the security rules when the contained item is securable. This means a user with EditContent permission can add/edit items to the BagPart whereas a user with ViewContent permission only should see the content item as a read-only version "like preview" but should not be able to make any change to it. So, this addition is about enhancing the BagPart to honor permissions for the contained content types. To try this one out, set up a site using the Agency recipe which contains the Landing Page content type which has several BagParts attached. Now, let's say that users with the Editor role will not be able to edit the services section of the Landing Page. Meaning the Editor role will not have Edit permission for the Service content items. We have to do things to achieve this: Edit the Service Content Type and put a tick to the Securable check box. This means this content type can have custom permissions. Edit the permissions of the Editor role. First, revoke the Edit content for others permission. Now, make sure that the Editor has no Edit Service for others permission regarding the Service Content Type. Now we set up that users with the Editor role will not be able to edit securable content types. Let's create a user with this role and log in as this new user. Now, we need to find the predefined Landing Page content item and edit it. As you can see, this user cannot add or edit an existing Service content item by using the editor of the BagPart. They can view the content of these items, but that's all. Notice that they can edit the Portfolio content items under the Services one. Add permissions for the Amazon S3 module A few weeks ago, we mentioned the new Amazon S3 module. The Amazon Media Storage feature enables support for storing assets in Amazon S3 Bucket. The feature replaces the default App_Data file-based media store with an Amazon Media Storage Provider. And now, you will see new permissions for that module called View Amazon S3 Media Options. If you have this permission, you can access the page under Configuration -> Media -> Amazon S3 Options which lists the Amazon S3 storage options. Improve the workflow function description in the document The Workflows module provides a way for users to visually implement business rules using flowchart diagrams. Many activities have settings that can contain either JavaScript or Liquid syntax. The fields of these activities allow you to enter Liquid markup, enabling access to system-wide variables and filters, as well as variables from the workflow execution context. And several JavaScript functions are available by default to any activity that supports script expressions. This page of the documentation lists these functions. And now, this table has been updated with some lines about the setProperty, executeQuery, and log functions. Demos Admin Culture Picker Unless you have a language switcher on website pages, you could not switch a language in the admin panel. This demo is about showing you a dropdown button in the admin panel header to switch languages. First of all, open up the admin UI of Orchard and head to Configuration -> Features, and enable the Admin Culture Picker one, which provides a culture picker shape for the admin. Don't forget to enable the Localization feature too, to be able to try out this culture picker. Now you can say that your site supports multiple cultures. Head to Configuration -> Settings -> Localization -> Cultures and have at least two supported cultures. And as you can see, the dropdown now contains all the cultures that the site supports. You can switch between them, and if you choose a given language, the UI of the admin will be shown by using the words of the given language. If you would like to see this picker in action, head to YouTube for a short demo! News from the community Orchard Dojo Newsletter Lombiq's Orchard Dojo Newsletter has 315 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 is 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 Orchard meeting!

Support a read-only behavior in the content management screen, visual verification testing in the Lombiq UI Testing Toolbox - This week in Orchard (05/08/2022)

Add password to the user creation form, support a read-only behavior in the content management screen, and a demo about adding visual verification testing in the Lombiq UI Testing Toolbox! Let's get started! Orchard Core updates Add a password to the user creation form By default, apps use basic authentication to authenticate users into their site including Microsoft Identity-based apps. No user is able to authenticate/login without providing a "username" and "password". Alternatively, an admin could enable some sort of external authentication providers like Azure AD or any other providers to avoid the need to manage the authentication by the app directly. These external providers are optional and not enabled by default in Orchard Core, so creating a user with no password by default adds no value since no the user can't log in without one. Currently, when adding a new user using the admin UI, the admin has to create a user and then go to a second view to set/reset their password. This is a very awkward workflow, especially if you want to add many users. Since username/password are required by default for a user to log in, the admin should be required to provide a password rather than creating a useless user with no password. Note, the point here is that password is required to log in by default without having to enable optional additional authentication providers. Let's try it out quickly! Head to the admin UI of Orchard Core and navigate to Security -> Users. Here you will find the Add User button. Click on it! This will navigate you to the create user page, where you can find some new goodies. First of all, you can provide a password for the newly created user here. But you have the option to generate a random secure password or copy the password to the clipboard. Support a read-only behavior in the content management screen The idea here is that both Admin Menu and Content management screens should be viewable if the user has View own X, View X by others, Preview X by others, or List X content item(s) owner by all users permission. Any of these permissions should be enough to display content. View rules should be implied if one has edit, delete or publish permission; you can't delete, edit or publish if you can't view something. Making this change will easily add view-only support to the contents in the admin. Meaning, that if the user has permission to View Blog, we should list the Blog content items in the Manage Content screen, for example. To try this out, we will modify the permissions of the built-in Editor role (Security -> Roles -> Editor -> Edit). As you can see, the Editor now has no Edit content for others and Edit own content permissions, but we set these edit permissions for the Blog Content Type. Meaning the Editor can only edit the Blog content items but can view every other content item. Now, let's log in with a user with the Editor role and navigate to the Manage content screen. As you can see, this user now can see every content item in this list, but the Edit button is only available near the Blog content items. Meaning this list now shows every content item which can be viewed by this user. Demos Visual verification testing in the Lombiq UI Testing Toolbox Maybe you have already heard about the Lombiq UI Testing Toolbox, our web UI testing toolbox mostly for Orchard Core applications. Everything you need to do UI testing with Selenium for an Orchard app is here. We wrote about it several times here as well, first when we open-sourced it, when we added some Orchard Core Features tests to it, and when we added the automated monkey testing feature to it. This time we will introduce the Basic Visual verification testing in the Lombiq UI Testing Toolbox for Orchard Core. Lombiq's Open-Source Orchard Core Extensions is an Orchard Core CMS Visual Studio solution that contains most of Lombiq's open-source Orchard modules and themes, as well as related utilities and libraries. Please keep in mind that only those extensions included that use the latest released version of Orchard (i.e., the very cutting-edge ones depending on a nightly build are not yet here). This solution contains the Lombiq UI Testing Toolbox as well, so we will use this one for the demo. The BasicVisualVerificationTests.cs contains three different samples about how you can verify the content displayed on your page visually. The first one is about checking the content of the element that has the field-name-blog-image class. The second one is about checking the content of the navbar (the element that has the navbar-brand class), and the third one will check the whole content of the home page. Here you can see the page that we will test. The red texts show you the Navbar and Blog image elements. Let's verify the content of the Navbar! The Navbar contains the site name which we can provide when we set up our site. Let's try to set up our site using a different name than the Lombiq's OSOCE - UI Testing and run the test. Here you can see that the test set up the site using the Lombiq's OSOCE - UI Testing Demo site name, and our visual verification failed since the asserted element looks different from the baseline image. The baseline image was loaded from an embedded resource which you can find in the repository here. If you want a new baseline image, simply delete the existing one, and a new one will be generated on the next run. And that's not all of it! Do you want to know more about this new addition to the Lombiq UI Testing Toolbox for Orchard Core? Then check out the comments of the BasicVisualVerificationTests.cs file and this recording on YouTube! News from the community Orchard Dojo Newsletter Lombiq's Orchard Dojo Newsletter has 309 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 is 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 Orchard meeting!

Change how the permissions are grouped and sorted, provide a way to override YesSql configuration - This week in Orchard (29/07/2022)

Change how the permissions are grouped and sorted, provide a way to override YesSql configuration and additional OpenId Introspection/Revocation endpoints and PKCE to the OpenID Settings and Application UI pages! Check out our current post to read about the details! Orchard Core updates Change how the permissions are grouped and sorted When the permissions are listed during role edit/create, currently we show the feature ID instead of a name. Displaying just the feature ID is not user-friendly. Here the goal is to create a new UI for this and also to order the permissions by Feature Names. Also, for content types, then it would display the content type name instead of its technical value/ID. So, we could display:{ Content Type Display Name } Content Type - { Content Type Technical Name }. In the case of the Blog content type could be My Blog Content Type - Blog. In order to show dynamic permissions as { Content Type Display Name } Content Type - { Content Type Technical Name } we would have to change how the category is set here otherwise we don't have the content type technical name here. But how the new UI looks like now? If you head to the admin UI of Orchard Core and navigate to Security -> Roles and Edit a given role, you will see the new UI. Here you can see we have a feature with the name Media and you can find the feature ID in brackets (they can be defined in the Manifest.cs file of the module). And under the Media (OrchardCore.Media), you can find all of the permissions which were defined in this module. You will find the Page Content Type - Page header at the bottom of this screen. This means the first word here is the Display Name of the Page content type (which is Page) and the last word here is the Technical Name of the Page content type, which is Page. Provide a way to override YesSql configuration Currently, there is no way to change the configuration of YesSql in Orchard Core. From now on you will find a new YesSqlOptions class that provides options to allow one to override the defaults. Added additional OpenId Introspection/Revocation endpoints and PKCE to the OpenID Settings and Application UI pages As a basic authorization server, the OpenID module doesn't use all the features/endpoints offered by OpenIddict, like introspection and revocation. As mentioned in openiddict/openiddict-core#1359 (comment), these features can be configured by amending the OpenIddict settings via a custom plugin, but a simpler story - GUI or recipes-based - may be preferable. To see the new changes, enable the OpenID Authorization Server and the OpenID Client features and after navigate to Security -> OpenID Connect -> Settings -> Authorization server. You will find a new Require Proof Key for Code Exchange checkbox on this page, which is a global setting that applies PKCE to all registered clients whether or not the 'Require PKCE' flag was set in the Application settings page. And you can do the same when adding an OpenID Connect Application. You can add a new application under Security -> OpenID Connect -> Management -> Applications. If you click on the Add an application button and put a tick to the Allow Authorization Code Flow checkbox, you will find the Require Proof Key for Code Exchange checkbox here as well. Note: ensure that the client application and OAuth or OIDC library being used supports PKCE before enabling this option. The documentation has also been updated to show you a sample of the OpenID Connect Settings recipe step and a sample of the OpenID Connect App recipe step. News from the community Lombiq Offline event Sometimes it's not just about work but doing something just for fun. These events are specifically for this: we get together and do something cool like breaking out of an escape room, going for a go-kart ride, or playing paintball. Our latest event took place at Lake Velence. We had a nice cycling tour around Lake Velence, had lunch in a nice restaurant, and had a barbecue together at the accommodation. The next day we went on a kayak trip and did a nice trip together to the nearby hills of the lake. This was a great opportunity to update our group photo on our official website, so head to the About us page where you can see most, but not all of our team as of the summer of 2022. Orchard Dojo Newsletter Lombiq's Orchard Dojo Newsletter has 313 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 is 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 Orchard meeting!