Code Generation Templates for .NET 5, Fluid 2 breaking changes - This week in Orchard (18/04/2021)

Gábor Domonkos's avatar
Announcement, Query, This week in Orchard, Resource manifest

This week we will do some deep dives and take a look at the latest changes of Fluid 2. After, you can see how you can register your custom resources in Orchard Core and how to use the updated code generation templates with .NET 5! Check out our post for more!

Orchard Core updates

Fluid 2 breaking changes and fixes

Let's say you had an expression something like foo != null and foo != "*" in your Liquid code.

There are two things here: the null doesn't exist in Liquid. There is no such thing as null in Liquid. When you write null, it's like typing bread, there's nothing like bread in Liquid. Typing foo != null in this case is just about making sure that foo does really exists. Is it set to something? If you would like to check for null, you have to use nil because in Liquid that's how we check for null values.

And let's say you write foo != "*" and foo =! null, that means you change the order here. Or let's say you have a code in Liquid like a or b and c or d and e. If you do it in C#, if you have an and and the first part of the expression is false, it won't check the value of the other parts, it will return with false. In Liquid, this is the opposite. In C#, the evaluation of this expression will happen from left to right but in Liquid it will happen from right to left. Let's see an example with this expression:

1 == 2 or b == 3

Liquid will start the evaluation of this expression in the following way:

1 == 2 or (b == 3)

1 == (2 or (b == 3))

(1 == (2 or (b == 3)))

So, it will never check that when 1 will be equals to 2 because the evaluation will start from the right.

This has been fixed in this version and Fluid now supports the following processing of the evaluation:

(1 == 2) or (b == 3)

So if you wrote foo != "*" and foo != null it was first checks if the foo is not equal to null. Then it will go to foo != ("*" and (foo != null)).

Let's say you do something in your templates like: {% assign foo = 1 + 2 %}

This is not valid in Liquid. In Liquid, there are no such operators like +, -, *, /. They are don't exist. They are supported in the first version of Fluid but now it has been removed to be close to the specification, so it's now not supported anymore. What you need to do actually is to change your operators in a way like {% assign foo = 1 |plus: 2 %}.

The goal of doing that from the Liquid templating language is to be able to distinguish how to behave in terms of numeric operators and string operators. So if you have the following line of code in Liquid, the result you will get will be 12, not 3.

{% assign foo = 1 |append: 2 %}

If you have operators in your code, don't forget to rewrite them in the mentioned way.

ResourceManifest breaking changes

A resource used to be declared by implementing the IResourceManifestProvider interface that was resolved all the time on every page rendering and this change is about to redefine that. Now it's not using IResourceManifestProvider anymore, there is no such interface. You need to create an IConfigureOptions<ResourceManagementOptions> of a ResourceManagementOptions. The ResourceManagementOptions is just a class that can be resolved everywhere. It can be configured in the startup. And in this case, what we do is that is a static constructor of this class is instantiating one manifest instance, and then when the option is configured for every tenant, it's adding this instance (which is immutable) to the list of resource manifests that is in the ResourceManagementOptions class. Your own configuration can even remove existing manifests from the resource manifest or replace them with something else or add new ones.

So, the two things here are that now we use the Options pattern from ASP.NET which is more standard. It's also better in terms of performance because it's a singleton for all the tenants. And here we are initializing the ResourceManifest instance in a static property. It's done once for all the tenants, even if you have one thousand tenants, there will be one instance of the ResourceManifest.

ResourceManifest breaking changes

Modifying the Lucene API To accept Post Form Data

Now you can invoke Lucene queries with POST and GET requests too. And there are two methods: a route called content to get the content items and a route called documents to get the full JSON document.

Lucene API accept POST form data

Add support for collections to OpenID Tokens

Today all the documents are stored in a table called Documents. YesSql supports the notion of collections, which is a way to store some specific types or classes in different document tables to isolate them. So, instead of having everything in the same Documents table, you can have different document tables. When the content of this table can be isolated from the rest, you should do that. This is the case for the OpenId module.

There are different levels of isolation. You could say every class should have its own document table. You could say also that every module can have its own document table. And then you can say that everything will go to the same document table. In this case, everything related to OpenId will go to the OpenId document table, which means everything in the collection named OpenId. This configuration tells YesSql there is a collection named OpenId.

OpenID support collections

But how can you use that collection when you do queries? In this case, you have to say to query a class in a collection named OpenId. It will request that document table and get all the indexes that all related to this document table. We also do that when one of the classes has lots of items so it can scale better than putting everything in the same table. Like if you have one million content items it will be slow. In that case, it should be in their own custom collection.

Query the OpenID collection

Demos

Code generation templates for .NET 5

If you install the project templates pointing to the preview source, you are able to use new command line commands when generating an Orchard CMS Web Application to use the .NET 5 framework. You can find every information more detailed on this page of the Orchard core documentation. Right now we will just focus on the new stuff.

So, don't forget to install the Orchard CMS templates for creating web applications. You will need to use the latest dev branch of Orchard Core to be able to use .NET 5, so this will be your command:

dotnet new -i OrchardCore.ProjectTemplates::1.0.0-rc2-* --nuget-source https://nuget.cloudsmith.io/orchardcore/preview/v3/index.json

If you do that, you can head to the folder where you would like to create your new solution. The only thing you have to do is to type the following line:

dotnet new occms --framework net5.0

This means the .NET framework 5.0 will be used. If you don't use the --framework or the --fm options, your web application will be using the .NET Core framework 3.1.

A number of predefined projects and item templates are installed with Visual Studio. These templates, such as the ASP.NET Web Application and Class Library templates, are available to choose from when you create a new project. Item templates, such as code files, XML files, HTML pages, and Style Sheets, appear in the Add New Item window.

These templates provide a starting point for users to begin creating projects, or to expand existing projects. Project templates provide the files that are required for a particular project type, include standard assembly references, and set default project properties and compiler options. Item templates can range in complexity from a single empty file that has a certain file extension to multiple source code files with stub code, designer information files, and embedded resources.

You may know that we have some Visual Studio Project Templates for Orchard Core too (we wrote about them in this post). It's still a preview feature in Visual Studio, so, you need to navigate to Tools -> Options -> Environment -> Preview Features and put a tick in the Show all .NET Core templates in the New Project dialog (requires restart) checkbox.

After you can just say I want to create a new project File -> New -> Project and you will be able to select the Orchard Core one as the project type. Let's select the Orchard Core Cms Web App (Orchard Project) one for example. After you can set the name of the project, the location, and the name of your solution. The next, Additional information window will contain the property that we are focusing on right now.

Set the .NET framework version

As you see on the screen, you can select which kind of framework you would like to use for your web application. It can be .NET Core 3.1 and .NET 5.0 as well. The default is .NET Core 3.1 in this case too. Here we are just creating our new solution using the name Test. And if we open up the Test.csproj file, we will see the following content here, where the value of the TargetFramework will be set to net5.0.

Using .NET 5 in your Orchard Core solution

If you would like to know more don't forget to check out a previous This week in Orchard post, where we first wrote about this topic. And as always, here comes the recording of this demo!

News from the community

Orchard Dojo Newsletter

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

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

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

No Comments

Add a Comment