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

Featured tags

IIS
API
SMS
SEO
All tags >

Statically typed URL creation, fix CSS intermittent encoding issue - This week in Orchard (22/12/2021)

Updating the Correlate Task, fixing CSS intermittent encoding issue and a demo about statically typed URL creation! Do you want to know more? Then check out our last post of this year! Orchard Core updates Fix Correlate Task If you have Workflows enabled in your solution, you have the option to add a Correlate Task to it. The hint is saying that it supports Liquid, but the truth is the parser here supports JavaScript, not Liquid. So, the solution here is to update the wording of the hint. And from now, if you would like to provide the value for your Correlate Task, you can use a Monaco editor here. Fix CSS intermittent encoding issue The cache on the browser was serving the CSS files using differently than UTF-8. When you disabled the cache on the browser it was fine. So, the cache is storing it as ASCII and not UTF-8. If you check out the picture below, you can see some weird characters on the screen. So, the problem here was a charset issue because browsers can handle different charsets if you put the information at the top of the file. But some of the stylesheets of Orchard Core were started with some comments and not with the line which is saying the given charset. And it looks like browsers only include the charset if it's in the first line of the stylesheet. So, the headers for the stylesheets are not injected anymore. Demos Statically typed URL creation The Lombiq Helpful Libraries for Orchard Core contains various libraries that can be handy when developing for Orchard Core CMS, to be used from your own Orchard modules. The Helpful Libraries now has a new class called TypedRoute which provides a strongly typed way to generate local URLs for Orchard Core MVC actions. It uses lambda expressions to select the action and provide arguments. Use TypedRoute.CreateFromExpression<TClass>(...).ToString() or the provided OrchardHelper.Action() and HttpContext.Action() extensions. Let's see this in action! In this demo, we will go with the quicker way and use our Open-Source Orchard Core Extensions full Orchard Core solution that contains that module with a nice sample. If you clone that repository and set up your site using any setup recipe, let's just navigate to the admin UI of Orchard Core, and under Configuration -> Features, enable the Lombiq Helpful Libraries for Orchard Core - Samples feature. Now, head to the /Lombiq.HelpfulLibraries.Samples/TypedRoute/Index URL to see the content of the following Razor file. As you can see, we constructed the first URL by using the anchor tag helper from ASP.NET Core. Here we needed to pass the area, the name of the controller, and the action and put the names of the accepted properties by the controller action by using the asp-route- prefix. If you use the extension, you can statically enter the controller name (TypedRouteController in this case) and using lambda you can select the TypedRouteSample action by passing the values you want. In this way, you can safely rename the controller or the action without breaking any functionality in your Razor file, because Visual Studio and Rider will also be able to find the references in your Razor files too. Do you want to know more and look under the hood of this feature? Well, you just need to check out this short presentation on YouTube! News from the community Christmas in Lombiq Sometimes we do stuff. Together. Not (just) in front of computer screens. These are some usual events in Lombiq that are all announced and arranged in advance. We periodically have an event called RnDay: this is a few hours long event where we share with each other what we recently worked on and what we plan to do. E.g. if we recently finished a project then the project's team members demo what they've done. This week we had our last RnDay for this year but this time (again), we have to make it online. We also named this event The 14th RnDay - Pandemic Edition 2! We also tried to do our best to make a nice group photo, you can see the result down below. :) We would like to thank you all for reading our posts and making the Orchard community stronger together with us! We hope that we could give you valuable news and demos about the happenings around Orchard and Orchard Core from time to time by reading our posts and of course the This week in Orchard newsletter. We would like to wish everyone a Merry Christmas and a Happy New Year! See you next year! Orchard Dojo Newsletter Lombiq's Orchard Dojo Newsletter has 234 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 week's Orchard meeting!

Updates on Fluid, Antebellum, a new site using Orchard Core - This week in Orchard (16/12/2021)

This time we will do a deep dive and will check out some important updates on Fluid. But before doing that, let's see some important changes of Orchard Core like preserving contained content items IDs or using async write/read of the Request.Body. Oh, and did we mention the brand new Orchard Core site, Antebellum? Orchard Core updates Preserve contained content items IDs Orchard Core has a feature to have content item IDs on Bag Parts be persistent (i.e., not change), which was implemented in this pull request. However, there was a bug. The "Bag Part Content Item ID" isn't persisted. And it was easy to reproduce. You just need to make a parent content type with a child content type like so: Then you just need to add in a Parent with a couple of children and publish it to get this result (it is outputting the child content item IDs): But every time you published the Parent Content Item, the child content item IDs changed: The fix was to use a dedicated Content Items array to hold the IDs. It prevents conflicts when removing (or moving to another container), and then adding an item, by computing indexes differently when adding an item, was based on the number of items + 1, now based on the existing max value + 1. And Jean-Thierry Kéchichian also fixes other little issues when dragging between containers more than one level up/down. Async write/read of the Request.Body is mandatory There was an issue in Orchard Core when you are using ReadToEnd() in the Request.Body. Using an async method is mandatory even if we use it synchronously by using GetAwaiter(). This is a behavior from ASP.NET which is toggleable, but we use the default in this case. Updates on Fluid Let's say you have an array and you would like to do a reverse. The following code is not a valid Liquid, that's just to present the given logic. Doing reverse in an array like: [1,2,3] | reverse => [3,2,1] will reverse the array. If you use reverse with a string like "1,2,3" you would expect to get "3,2,1". But what it was giving you is a string, but it should give you an array with ["3", "2", "1"]. So, the reverse has been fixed in two ways. First, fixing the behavior on strings and then also returning an array instead of a string. So, it's not obvious, not expected from that. If you want to suggest Liquid features, you can use LiquidJS.com, and then you can try something like that. The retuning value here 3,2,1 is an array actually (the site serializes it and displays it as a string). Another good tool is .NET Fiddle, where you can reference a NuGet package and can work with Liquid. It requires some more work, so using LiquidJS to try out Liquid is an easier way. Another improvement is there is a new render tag. Usually, you can use the input tag to load an external Liquid file. This input tag has been obsoleted by the Shopify team because it has security issues in a way that when you run a partial template from this input tag, it can access all the variables from the calling templates. The new render tag in Fluid now doesn't have this issue. It works exactly the same as input with the same parameters, but you can only access the properties, that have been set on the tag itself, or the variables that are defined in the global scope. There are actually some interesting ways to use that. You can write {% include 'foo' %}, and it will try to render the foo.liquid file. And when you do that, inside the foo.liquid, the foo property is the global scope. You can also do {% include 'foo' a:1, b:2 %} and than in this case foo.a, foo.b will have the values. You can also write {% include 'foo' as model %} and then the properties will be available under the modal property. Fluid v.2.2.4 is fixing first, last, and size. It means you can do the following that can be seen on the screen below. In Fluid, these properties were implemented specifically in all the values, but you can also use pipes to do the same thing. The issue is there were two different invertations ,but the standard says this should be the same thing. So, calling | first now is equivalent to do .first. This means any of your objects can implement these filters by just intercepting the property name. Fluid v2.2.5 contains the new liquid and echo tags. The echo tag can be used in this way: {% echo "foo" %}. The idea of the echo tag is that it's equivalent to the injection tag like this: {{ "foo" }}. The liquid tag is just to execute liquid. What you can do with that is you can run liquid like: {% liquid for x in 1..10 echo x endfor%} which is equivalent to {% for x in 1..10 %} {{ x }}{% endfor %} but as you can see, the first one is less verbose, you don't have to add all the curly braces and the percentage sign everywhere. It's just one block, and you can also nest them. Demos A new website using Orchard Core: Antebellum Antebellum provides a way for the everyday person to mine crypto, without the need of buying expensive hardware, consuming high electricity, high cost in cooling, maintenance of hardware, and sudden downtime. The site contains several custom pages, like the Sign Up page, which is actually using a workflow to do the user registration that also has an integration with Stripe.js. Stripe.js is a JavaScript library that you can wire into your checkout form to handle the credit card information. When a user signs up using the checkout form, it sends the credit card information directly from the user's browser to Stripe's servers. Just head to YouTube to see how the Sign Up page was built or how can you make a nice custom admin UI like that you can see in the video one in Orchard Core! If you are interested in more websites using Orchard and Orchard Core, don't forget to visit Show Orchard. Show Orchard is a website for showing representative Orchard CMS (and now Orchard Core) websites all around the internet. It was started by Ryan Drew Burnett, but since he doesn't work with Orchard anymore, as announced earlier it is now maintained by our team at Lombiq Technologies. News from the community Orchard Dojo Newsletter Lombiq's Orchard Dojo Newsletter has 234 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 week's Orchard meeting!

Lombiq UI Testing Toolbox - Orchard Core Features tests, disable File Content Definition feature by default - This week in Orchard (10/12/2021)

The HTTP Response Task now supports the text/html content type, disables the File Content Definition feature by default, prevents confusing usage of IRunningShellTable.Match(HttpContext) and demo about the Orchard Core Features tests in the Lombiq UI Testing Toolbox. Do you want to know more? Then don't forget to check out our current post! Orchard Core updates HTTP Response Task supports "text/html" content type If you are using Workflows in your solution, you have the option to use the HTTP Response task, which writes an HTTP response (to use that task, you need to enable the HTTP Workflows Activities feature). If you are in the editor of your Workflow, you just need to click on the Add Task button and select the HTTP Response from the HTTP category. From now, you will see a new text/html content-type option of the response body, which allows workflow submissions to return web content directly. Don't enable the File Content Definition feature by default in the built-in themes From now the File Content Definition feature will not be enabled by default. This feature is replacing the default behavior to store content type definitions in the database with one that stores the content type definitions in a file in the App_Data folder. Most users prefer to store the content type definitions in the database by default. You can still enable this feature if you prefer your content definitions to be file-based, for instance, if you want them in your source control management. But by default, they will be in the database from now. If you have a distributed theme or site, then you might want it to be in the database by default. And the change is just to remove the feature from the recipes. The corresponding page on the Orchard Core documentation is also updated to inform everybody about the changes. Prevent confusing usage of IRunningShellTable.Match(HttpContext) You could use this extension method with an HttpContext, but it didn't actually work anywhere where you can do it from a module. So, from now this RunningShellTableExtensions is an internal class, because as you can see from the comment there: not public because it wouldn't match tenants with an URL prefix later in the request pipeline. Mostly to be used from ModularTenantContainerMiddleware. Demos Lombiq UI Testing Toolbox - Orchard Core Features tests The Lombiq UI Testing Toolbox is a web UI testing toolbox mostly for Orchard Core applications. Everything you need to do UI testing with Selenium for an Orchard app is here. UI Testing here is an automation that clicks through the web application in a browser. One of the most popular frameworks for that is Selenium, which does exactly that. You get an API to instruct a browser, and every major browser is supported. This UI Testing Toolbox provides a lot of features on top of Selenium for Orchard Core. Basically, allowing you to UI test an Orchard Core application in a safe and parallelized way providing a lot of helpers, a lot of higher-level APIs allowing you to test your application with SQLite, with SQL Server with local media storage, or with Azure Blob Storage. And you can have a test e-mail sending with a local SMTP server too. Everything just works. Check out the highlights of the Readme.md file of this repository to see all of the features and this older This week in Orchard post where you could see a demo about the Toolbox. This time we will focus on the Orchard Core Features tests. The idea here is that you have an Orchard Core application, and you want to do some basic smoke testing, like trial the application whether it works at its very basics. Now, for that, we have created a TestBasicOrchardFeatures extension method, which will run through a couple of tests that you can run individually. For example, testing whether the setup works, testing whether the registration works, testing whether the login works, and so on. All of these are features of Orchard Core itself, so not your custom application, but these are also all things that you can break from your custom code. So, we figured that it's useful to check whether these basic Orchard features work all the time. And for example, if you manage to break set up with your recipe or if you manage to break the login or the registration features from your code like even implementing an event handler that throws an exception, well then these tests should catch them. Do you want to see these tests in action? Well, in that case, you just have to click on the following recording on YouTube! News from the community Orchard Dojo Newsletter Lombiq's Orchard Dojo Newsletter has 235 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 week's Orchard meeting!

URI components Liquid accessors, Lombiq JSON Editor - This week in Orchard (15/09/2021)

Add Cc and Bcc to Workflow Email Task, URI components Liquid accessors, Lombiq JSON editor, and many more coming this week! Do you want to know more? Then it's time to check out our current post! Orchard Core updates Add Cc and Bcc to Workflow Email Task If you would like to send an email using Workflows, you can use the Email Task to achieve your goal. Simply navigate to the admin UI of Orchard Core and go to Workflows (don't forget to enable the Workflows and the Email features) to create a new workflow. If you add a new Email Task to your workflow, you will see that this task has now two new fields: the Cc and the Bcc. RegisterUserTask: Subject & Template for confirmation email should not be required if Send Email is unchecked And while we are talking about the workflows, let's check out another workflow task, the Register User Task which registers users from form fields. When adding this task to your workflow, you can easily say that I want to send a confirmation email to the newly registered user with this subject and template. The issue was that the subject and the template for the confirmation email were required even if Send Confirmation Email is not checked. URI components Liquid accessors By default, the Liquid templates have access to a common set of objects. You can easily access the properties of the content item that is currently being rendered, the authenticated user for the current request, the current site settings, and the current request itself of course. Check out this page of the Orchard Core documentation to see all of the available properties on the Request object. If you use the Request object quite often, you will notice that this table now has new properties, like the QueryString, UriQueryString, Path, UriPath, PathBase, UriPathBase, Host, and UriHost. Generate Rule Condition TargetUrl in a correct location The rules module was designed with extensibility in mind; however, there is one line that is in the view for it, setting the TargetUrl property of the modal picker to the layers controller. It needs to be moved out of the view, and into the Layers controller so that the view can be used by other modules, pointing to different controllers. Demos Lombiq JSON Editor The Lombiq JSON Editor is our Orchard Core module for displaying a JSON Editor like on jsoneditoronline.org. You can easily clone or download the module from this GitHub repository. If you want to quickly try out this project and see it in action, check it out in our Open-Source Orchard Core Extensions full Orchard Core solution and also see our other useful Orchard Core-related open-source projects! In this demo, we will go with the quicker way and use our Open-Source Orchard Core Extensions full Orchard Core solution. If you clone that repository and set up your site using any setup recipe, let's just navigate to the admin UI of Orchard Core, and under Configuration -> Recipes, you will find one called Lombiq Open Source Orchard Core Extensions - JSON Editor Sample that is about demoing the Lombiq JSON Editor module. Let's run the recipe! Now let's see the list of the content items where you will find a new one called JSON Example Page. This page has a JSON Field which comes from the Lombiq JSON Editor module. It's using a tree editor by default that you can use to manipulate the content of the JSON inside. But of course, you can have other types of editor for your JSON if you want, like you can have a code editor with numbered lines with syntax highlighting or you can just use a pure text editor and so on. Using a simple json-editor tag helper you can easily render the JSON editor. You can pass a string value to the editor that will contain the JSON itself, pass the JsonEditorOptions class that contains several configuration values like EscapeUnicode, SortObjectKeys, and so on. And you have several other options and use-cases for this JSON field. The JSON Example Page, which comes from the recipe, has a Liquid Part too that reads the values from the JSON field and prints the values in a simple list by using Liquid and JavaScript. Here is the display view of the JSON Example Page. If you would like to know more about this new field, head to YouTube for a recording! News from the community New GraphQL 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 GraphQL sample! Check it out if you would like to know more about Orchard Core's GraphQL module and learn how to extend the Orchard GraphQL APIs! Orchard Dojo Newsletter Lombiq's Orchard Dojo Newsletter has 226 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 week's Orchard meeting!

Google Tag Manager, User Approval feature - This week in Orchard (06/08/2021)

We promised that we will continue showing you the newest features and additions of Orchard Core 1.0 this week too! Well, we still have a lot to write about, so without any further ado, let's get started! Orchard Core updates Add user approval feature The user registration process, whether from the Registration controller, or via an ExternalLoginProvider had no features to moderate a user. In Orchard 1 we could moderate users, through an approval process. A new user registering when moderation was required, would not be logged in to the site, but redirected to the registration pending page, (and workflows invoked, to start the moderation process). We already have the IsEnabled bool, but no way to control both local registration and external registration. This change adds a UsersAreModerated setting to the user registration feature. When set true all users, whether registering via an external provider, or direct through the registration controller, will require approval, i.e., their account set IsEnabled = true before they are logged into the site. It also prevents external users from being automatically logged in if they have not confirmed their email address (if the confirmation email setting is set to true). Register user workflow updated to support the feature as well. Let's see this one quickly in action! First of all, you need to enable the Users Registration feature that allows external users to sign up to the site and ask to confirm their email. Now you can head to Security -> Settings -> User Registration, where you will see a new option: Users must be approved before they can log in. Put a tick in this checkbox and, don't forget to select the AllowRegistration option from the select list. Now, let's register with a new user! If you create a new account and hit the Register button, you will find the following screen meaning that an admin needs to approve your account before it can be used. Let's see how you can use this one in workflows! Navigate to Workflows -> Create Workflow, and after you add a name to your workflow, hit the Add Task button. Find the Register User task from the list, and the editor of this task will contain a Users must be approved before they can log in checkbox. Now let's see how we can approve the newly registered users! If you navigate to Security -> Users on the admin UI, you will see a list that contains all the available users in the system, and you will also find a red badge with a Disabled text near the users who are not enabled yet. If you click on the Edit button near a disabled user, you can simply use the Is enabled? switch to enable the given user. After that, the user with the user name: newuser now can log in. OpenID Client parameters The OpenIdConnectOptions support an OnRedirectToIdentityProvider event feature which allows the setting of custom parameters on the protocol message when generating an OpenIdConnectMessage to an external provider. Sometimes you need to be able to send some custom parameters to some of your tenant's AzureB2C auth servers (but not all, and it varies per tenant). options.Events.OnRedirectToIdentityProvider = (context) =>{ context.ProtocolMessage.SetParameter("foo", "bar"); return Task.CompletedTask;}; The solution here would be to have editable parameter (kvp) options on the OpenIdConnectSettings so you can configure different tenants to use different custom parameters. To test this out, you need to enable the OpenID Client feature under Configuration -> Features. After, head to Security -> OpenID Connect -> Authentication client, where you will see the new table called Advanced Parameters. Google Tag Manager Google describes its Tag Manager product as a 'Tag Management System' (TMS). That’s an excellent way to think about it. It does for a website’s tags what a Content Management System (CMS) does for its content. The service provides an interface through which to create and track all the tags your site needs. You no longer have to code each tag manually. Instead, you can create all your tags through the interface. Tag Manager will then implement them for your site. That is if you’ve embedded a straightforward piece of Tag Manager code into each page of the website. The Google Tag Manager container snippet is a small piece of JavaScript and non-JavaScript code that you paste into your pages. It enables Tag Manager to fire tags by inserting gtm.js into the page (or through the use of an iframe when JavaScript isn't available). But how can we use Google Tag Manager in our Orchard Core site? Well, first of all, you have to navigate to the Google Tag Manager portal and create a Tag Manager account. This will give you a generated Container ID for you to use on your website. Copy this ID, we will need it later! Now, enable the Google Tag Manager feature on your Orchard Core site and head to Configuration -> Google Tag Manager. Paste the Container ID here and hit Save. This will mean that the required JavaScript code for Google Tag Manager will be registered for every page on the front-end. News from the community Updated Orchard Core sites OrchardCore.net is the official website for Orchard Core. Try Orchard Core is the place where you can easily set up an Orchard Core site within a few minutes and try out the features of Orchard Core. Both of these sites have been updated to Orchard Core 1.0! Head to Try Orchard Core to try out Orchard Core 1.0 now! The OrchardCore.Samples repository contains a sample Multi-tenant application and a Modular application demonstrating how to build a Modular and a Multi-Tenant ASP.NET Core application using the Orchard Core Framework. This solution is also using Orchard Core 1.0 now, you should check out this solution to see some nice code examples! DotNest Core DotNest Core is a complete redevelopment of the DotNest platform, all on the latest version of Orchard Core. We've been running it with a couple of select few customers for a while now, and it's time to open it up a bit more. While you can't yet just simply create an Orchard Core-based DotNest site, you can sign up for our limited beta here. You'll soon be able to get a fully functional, reliably hosted Orchard Core site on DotNest where you can build your personal website or something to showcase your Orchard skills with. Orchard Dojo Newsletter Lombiq's Orchard Dojo Newsletter has 214 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!

Support multipart content type with email service, UNION and UNION ALL clause support - This week in Orchard (20/07/2021)

A new OrchardCore.Email.Core project, support multipart content type with email service, a brand new Orchard Core site using Stripe.Js and Azure Functions and many more are waiting for you in our upcoming post! Orchard Core updates New OrchardCore.Email.Core project We don't have an OrchardCore.Email.Core project that is something similar to feeds and other functionality. Now the default implementation of the ISmtpService is in its own project, that is the OrchardCore.Email.Core one. Support multipart content type with email service Right now when we send an email as HTML by checking the Does the Body contain HTML checkbox option on the email task it will be sent only in HTML. Some email software will often transfer these emails as plain text so we should provide also a plain-text version of the email for the email software to be able to use. This way, we can provide two different Body versions of the email. The solution could be that when the Does the Body contain HTML checkbox is checked we should have a second Body (plain-text) text field to provide the email as plain text. Check out the following email example below to see that the email now could contain an HTML version of the body and a plain text version of the body too. From: [email protected]: Fri, 25 Jun 2021 17:34:43 -0400Subject: TestMessage-Id: <OUJBALN63EU4.IS3IGSIZUPB3@skrypt>Sender: [email protected]: [email protected]: [email protected]: 1.0Content-Type: multipart/alternative; boundary="=-9nfRnDakF+Ib69kpAIdY3A=="--=-9nfRnDakF+Ib69kpAIdY3A==Content-Type: text/plain; charset=utf-8Test text--=-9nfRnDakF+Ib69kpAIdY3A==Content-Type: text/html; charset=utf-8<p>Test html</p>--=-9nfRnDakF+Ib69kpAIdY3A==-- You can achieve this by creating a new Email task in your workflow, put a tick in these two checkboxes and provide the body texts of the email message. Refactoring SelectPart Vue to make it reusable If you have multiple SelectParts on a page, (e.g. a Form FlowPart with multiple Select widgets), then only the first one will actually have a working editor in the edit page or will render options correctly on the display. It has to do with each of the generated SelectOptionsTable/Modal Vue components relying on the same template ID regardless of which widget content item ID they actually correspond to. And it wasn't a huge deal to reproduce this bug. You just needed to run the Blog recipe and turn on the Forms feature. This allows you to add multiple Select widgets to a form's FlowPart. Now, this issue has been fixed. UNION and UNION ALL clause support Now you have support for UNION and UNION ALL clauses in SQL queries. It's not the first time when we have new SQL contracts in the SQL parser. And the ShouldParseUnionClause test in the SqlParserTests.cs file is just about checking that the dialect is generated the correct UNION and UNION ALL which is common to every dialect we use. Demos Using Stripe.Js + Azure Functions with Orchard Core Real Estate end Development is a site that chooses Orchard Core to implement its web appearance. You can register and have a subscription and can also purchase some magazines. The site uses Azure Functions and Stripe.Js to create customers for example with all the necessary inputs. And the flow continues to create a new subscription to that user and so on. If you would like to see the site in action, check out the following demo on YouTube! News from the community Orchard Core articles on .NET Thailand .NET Thailand houses several articles regarding several topics around .NET. Here you can see nice articles about how can debug your code using Chrome DevTool, Visual Studio, or VS Code, or how you can work Docker. And the site also contains some articles about Orchard Core too! For example, you can read a nice one here about how to create a content type and a content item programmatically or how to create a custom Orchard Core module from scratch. Lombiq Helpful Libraries: ContentVersionNumberService The Lombiq Helpful Libraries consist of several various libraries that can be handy when developing for Orchard Core CMS, to be used from your own Orchard modules. This time we will see some helpful services and extensions regarding content item version numbers. Sometimes you may want to know the latest or the current version number of a given content item. To get the version ID, you need to create a new query and query the content items using the ContentItemIndex table and get the value of the ContentItemVersionId column from there. Using our GetLatestVersionNumberAsync and GetCurrentVersionNumberAsync methods from the default implementation of the IContentVersionNumberService interface, you can easily get the version IDs just by injecting this to your code and provide the ID of a content item. Or use the extension methods where you can get the version ID by providing an IContent. Orchard Dojo Newsletter Lombiq's Orchard Dojo Newsletter has 209 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!

Client-side validation of the form elements, fix content item shape usage in Liquid - This week in Orchard (26/05/2021)

Documentation updates, fixes for the content item shape when calling it using Liquid, a new extension method for the IContentManager, and a demo about client-side validation of the form elements. These are the main topics for our current blog post! Orchard Core updates Adding docs on the Recipes recipe step A recipe is a JSON file used to execute different import and configuration steps. You can add it in a Recipes folder with a name like this {RecipeName}.recipe.json, and it will be available in the Configuration > Recipes admin page. A recipe can execute multiple steps. In order to create a new Recipe step, you need to implement the IRecipeStepHandler interface and the ExecuteAsync method: public async Task ExecuteAsync(RecipeExecutionContext context). This page of the documentation mentions the available recipe steps, but the Recipes Step is missing from the list. Now you can read about what is the Recipes Step exactly and how you can add them to your recipe file! Fix content item shape usage in Liquid There was some confusion about the difference between alias and handle when using the content item shape in Liquid. The handle is the way you can reference content items with logical names and not physical IDs. In this case, you can reference a content item by its alias, which is the test here, or by its slug, which can be blogpost1. But if you type the alias here, it will still work because some code falls back to that. The Detail display type is the default one, so you don't have to specify it in the helper. But rendering the given display type here didn't work because there was an issue in the ShapeTag.cs code. As you can see, there was an argument.Name.ToPascalCaseDash() call for each argument. But the right method to use here is the ToPascalCaseUnderscore(), which takes display_type and converts it to DisplayType. Load items in Admin List Now you can find tons of new extension methods on the IContentManager to call LoadAsync. When you call this new ListAsync extension method, it will call the LoadAsync too, which will invoke the LoadingAsync and LoadedAsync events to acquire state or at least establish lazy loading callbacks. Don't allocate for page output writing in LiquidViewTemplate When we have the RazorPage class in ASP.NET Core, it has an Output property, which is about getting the TextWriter that the page is writing output to. We use that to render out our Liquid Templates. But when we do that, the output object is actually a buffered writer that will take whatever we write to it and buffer it and write it again to the actual results at some point. But what happens here is Liquid will write every snippet of data, every fragment to this writer, which will be duplicated in memory because it doesn't know that it can reuse it or who owns the data. Knowing that if we look at the implementation of ASP.NET, there is a class named ViewBufferTextWriter, that has a custom Write(IHtmlContent) implementation that would check if the object we pass is an HTML content. And if it's HTML content, then it won't try to allocate anything, it will just keep a reference to it. So, by doing page.Output.Write(content) it's now invoking ViewBufferTextWriter.Write(IHtmlContent) which doesn't allocate anything. And then, when the IHtmlContent is used, it should write directly to the response buffer. Demos Client-side validation of the form elements This demo is about form element validation. There is an in-progress pull request by Spike where you can find the complete form validation implementation using the Validator.js library, which is a library of string validators and sanitizers. We can use this to have validation for form elements with one rule both on the client-side and on the server-side in a user-configurable way. We set up our site using the Blog recipe and created a Page content item that contains a Form in its FlowPart and posts its input elements to a Workflow. The input elements are just about to demonstrate some validation rules. If you add a new Input, you can see some new fields, like the Validation Type, the Validation Options, and the Validation Message. As you will see from the Readme.md file of the Forms module, there is a high variety of functions that are implemented and can be used as the Validation Type. Now let's try out the Contains Validation Type! Let's say we have a rule that the textbox should contain the 'think' word. To do that, we simply write the 'think' word in the Validation Options textbox and also added a nice error message. But as you can see, there are lot more options that you can choose from to validate the inputs of your form, which works the same way. And here comes the workflow that we are using to submit the form. The FormRequest one is just a simple HTTP Request event followed by the Validate Form one, which checks whether the submitted form contains any validation errors. And if there were no validation errors, we redirect the user to the /Success URL, otherwise, the user will be navigated to the /Error URL. But that's not all of it! Head to YouTube now to check out the recording about this very useful upcoming feature! News from the community Orchard Dojo Newsletter Lombiq's Orchard Dojo Newsletter has 199 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 week's Orchard meeting!

Parlot, Make deployment steps orderable - This week in Orchard (07/03/2021)

This week you can meet with Parlot, which is a fast, lightweight, and simple to use .NET parser combinator! Check out our post for the orderable deployment steps, the improvements of the Kast platform, and many more! Orchard Core updates Make deployment steps orderable This is about making deployment steps orderable in the UI, to allow drag and drop to get steps where you want them to be. UI only, as the choice to when steps run should be up to the user. Let's say you have plenty of plans where features don't want to be first - more common when deploying to existing sites, rather than building up recipes, but steps are for both. And now you can also find hints to the important steps that suggest they should go first, like "Content Definitions should be placed before any content steps." Update from node-sass to dart-sass This is about replacing gulp-sass with its newer gulp-dart-sass because node-saas is now deprecated and the latest node-sass doesn't compile on the latest NodeJS anymore. So, it's recommended on the gulp-sass repository be upgraded to gulp-dart-sass as node-sass is deprecated. You can read more about it in this article. Fix WorkflowBlockingActivitiesIndex table indices name length for PostgreSQL This is an interesting one, so we think this should deserve a few lines. Check out the Migrations file in the OrchardCore.Workflows module where you can see the creation of two different indices: IDX_WorkflowBlockingActivitiesIndex_DocumentId_ActivityId and IDX_WorkflowBlockingActivitiesIndex_DocumentId_ActivityName. Because of the PostgreSQL name length limit, it uses only IDX_WorkflowBlockingActivitiesIndex_DocumentId_Activity for both which causes an exception. The fix is just to reduce the length of these indices. Add Properties to SetupContext There is a SetupContext class that had some properties like SiteName, AdminUserName, AdminUserId, etc. This SetupContext class will be prepopulated by the setup screen and then passed to ISetupHandler. But now the ISetupHandler accepts an IDictionary to work with these properties. But why is it useful? When setting up a tenant or site sometimes you need to pass in some custom data and use it in your setup recipes. Like when a user registers on a site and he submits a form with firstname, lastname, etc. We then call a workflow that creates the tenant and executes a setup recipe. In this setup recipe, we could create a landing page and we want to assign the firstname, lastname to be set as the displaytext of the landing page content item. Or another use case would be to populate the custom user profile settings during setup. So, from now, the developers can populate the Properties bag from his workflow task or a custom setup screen if they would like to. You can see a good example in the ExecuteAsync method of the SetupTenantTask. Demos Parlot The Shortcodes repository by Sébastien Ros contains a Shortcodes processor for .NET with a focus on performance and simplicity. And now that Shortcodes processor is updated to use a new parser called Parlot. Parlot is a French pronunciation of the word like chat or someone who talks a lot. In French, you write it parlotte. Parlot is a hand-written parser for Shortcodes and that parser is now extracted to make it reusable. You can find adding and using Parlot in the Shortcodes module in this PR. If you check out that pull request, you will see that before this PR we had the Character.cs, Cursor.cs classes. Now they aren't here anymore, they are in the package. The code is almost the same. Now we have a ShortcodesParser.cs that is using Parlot. And in this file, you can find the grammar of Shortcodes. A text is based on shortcode and TEXT nodes. A Shortcode can have an identifier and arguments. An argument is like identifier equals value. It's actually could be just a value if you want. And a value is either a string or a number. This class contains a bunch of first-level methods like ParseNode, ParseRawText, and so on. If you check out the JSON benchmarks of Parlot, you will see a nice table about the performance of Parlot. And in that table, you can see the performance of parsing JSON documents. As you can see, it is ten times faster than something like Sprache, which is a famous parser. Pidgin has been created to be faster than Sprache and now Parlot is faster than Pidgins. If you take a look at the allocations, you can see that they are equal because it's just about allocating JSON. This benchmark creates an expression tree (AST) representing mathematical expressions with operator precedence and grouping. Same thing here. This table is about comparing the low level, the fluent API, and Piding. Even the Fluent API is five times faster than Pidgin. And in terms of allocation, it's a little bit better than Pidgin. Here you can see a demo video about Parlot and a lot more than that! Like stories about the NCalc library that is created by Sébastien Ros 10 years ago. NCalc is a mathematical expressions evaluator in .NET. NCalc can parse any expression and evaluate the result, including static or dynamic parameters and custom functions. And that library is used by the Sprache.Calc library. Sprache.Calc provides easy to use extensible expression evaluator based on the LinqyCalculator sample. The evaluator supports arithmetic operations, custom functions, and parameters. It takes a string representation of an expression and converts it to a structured LINQ expression instance which can easily be compiled to an executable delegate. In contrast with interpreted expression evaluators such as NCalc, compiled expressions perform just as fast as native C# methods. We can fill up the whole This week in Orchard post just by these libraries and the story behind Parlot. Or we can start to describe how the parser works and how you can extend it with your own implementations, but this may no longer be closely related to the topic of this series. So, as we just mentioned before: if you are interested in these topics, this will be your presentation! Resource Zones, Resource Layers, Resource Widgets Kast is an Australian company and one of their primary goals is to implement the Kast platform with the Kast Group Finder component. We worked together with Seth Cleaver (Co-founder and Director of Kast) on this tool to be able to create an intuitive self-service process that enables people within a church to easily find a suitable group to attend, simplify the administrative processes required for getting people into groups, and provide information to the group co-ordinators that might assist in planning and measuring effectiveness. Check out this case study about how we've developed this multi-tenant social group management platform for churches! The Kast platform is growing from time to time and this time you could see an improvement from Dean Marcussen which is about providing ways to edit static resources (like JavaScript and CSS) using the admin UI. The exact issue in GitHub is opened by Dody Gunawinata a while ago about the downside of the current theme system is that to change anything will require deployment. The way around is to include the JS/CSS in a template and include them in every other template. Check out the following recording for a possible solution! It didn't seem like the design was wanted for Orchard Core itself, so it will probably remain private at this stage. But if the people wanted it, it might be possible to make it available at some point as a contribution module. News from the community Orchard Dojo Newsletter Lombiq's Orchard Dojo Newsletter has 190 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!

Workflows atomicity, Inline scripts and style sheets - This week in Orchard (07/02/2021)

Workflows atomicity, support inline scripts and style sheets, admin UI sticky buttons, filter and search feature for List Part too. Do we need to tell more about the content of our current post? Let's jump into the recent news of Orchard Core! Orchard Core updates Support Inline location for styles and scripts You can specify several options when working with commonly used resources like JavaScript libraries and CSS files like using a configured CDN or appending a version hash to all local scripts and style sheets. You can also specify a location the script should load, for example, you can say that I would like to render my style sheet in the HEAD of my page. If the location is not specified or specified as Inline, the script will be inserted wherever it is placed (inline). Let's say we have a site set up using the Agency recipe. Then let's navigate to Design -> Templates on the admin UI and find the predefined Content__LandingPage template. Here we can try out the new Inline mode using Liquid helpers! Try to inject the jQuery named script inline before we render the Portfolio content items. To do that we just need to add the following line: {% script name:"jQuery", at:"Inline" %}. And as you can see in the code, there is the script HTML tag right after the jQuery script text. Filter/search feature for List Part too If you navigate to the content items list of your site (Content -> Content Items) you can use a nice search feature that you can use to filter your content items by the display text values. You can also use the quick filters to see only the draft/published items or the ones that owned by you. But you can't use this filter for the List Part lists. Until now! If you have a site with a Blog recipe, head to the Blog option on the admin UI and check out the new UI. You will see the exact same filter and search here as we have seen on the content items list. New IUserClaimsProvider interface This is about the extensibility of the ClaimsProviders. You used to have to inherit from the DefaultUserClaimsPrincipalFactory to provide all the claims but now you have a new IUserClaimsProvider interface that you can implement. There are some default ones like the EmailClaimsProvider. Workaround for DateTimeOffset in indexes The OpenIdAuthorizationIndex hasn't been sent to Dapper by YesSql correctly. Here the DateTimeOffset? hasn't been handled correctly and the workaround is to use DateTime?. So, for now, the local fix is to use DateTime? instead of DateTimeOffset? in the index provider and DateTime instead of DateTimeOffset in the migrations. Demos Sticky action buttons on the admin UI The problem is that you have to do a lot of scrolling to find the action buttons to save, publish or preview your content item. There could be several options to solve this issue but now to experiment how easy to use the implemented solution, this one only affects the Templates page right now. The idea that has been implemented is to have sticky action buttons on the top of the page instead of showing them at the bottom of the screen. If you set up your site using the Agency recipe and open the predefined template (Design -> Templates) and scroll down a little bit you will see the same screen as we show here. If you would like to see the sticky buttons in action too, head to YouTube and check out this recording. And as always, if you have any feedback or suggestion on how to solve the issue of needing to scroll down a lot to reach the action buttons, don't hesitate to share your ideas on GitHub! Workflows atomicity In this demo, you could see a workflow that has a starting activity that is about to handle an incoming HTTP GET request. This workflow will call an endpoint using an HTTP GET request 30 times using a For Loop activity. After that 30 actions finished, the workflow will publish a new content item and display a simple success notification. You could ask that what is the goal to call a given endpoint 30 times and you are right. But for this time the goal of this workflow is to demonstrate that we have a long-running workflow and this process can perfectly demonstrate that. Make sure you can only have one instance of this workflow type at the same time by putting a tick in the Single instance checkbox. Because it's a single instance if you call this workflow again without the first one has been successfully finished, the execution will wait for the first one to be finished. So, the system will only start to execute the second call after the first execution was finished with or without an error. In this demo, you can see what will happen if you do 10 concurrent requests to start this workflow. You will see 10 workflow instances instead of 1. But why? It's a singleton, you should see only one instance, right? Let's navigate to the properties of the given workflow where you will see two new options: Lock timeout and Lock expiration and give them a value in ms like 10000. Now let's try to call this workflow again using 10 concurrent requests. What will happen that now if you check out the instances of the given workflow, you will find only one item there. Check out the recording to see what are these new options exactly and how to use them correctly! News from the community Work with us! You've completed the Dojo Course, congratulations! You’re now officially an Orchard Core developer. Would you like to work on a variety of challenging Orchard Core projects with the biggest Orchard team in the world? Work with us! Just send us an e-mail to crew at lombiq.com. Please include what you’re most interested in professionally and attach around 100 lines of any kind of code that you’re especially proud of or just link to the favorite open-source project of your own on GitHub or else. Orchard Dojo Newsletter Lombiq's Orchard Dojo Newsletter has 191 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!

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!