This week in Orchard - 11/23/2018

Gábor Domonkos's avatar
This week in Orchard

Read our post to know the new The Coming Soon Theme, the new Reverse Proxy and CORS module for Orchard Core!

On Orchard Core

Interface for prevent the roundtrip to cast the dynamic JObject to a part and back

When we have a content item, the item has a Content property. This property is a dynamic. We can get the value of the TitlePart's Title by saying:

dynamic content = ContentItem.Content;
content.TitlePart.Title;

This is a dynamic object. What we return from .Content is actually a JObject, a Json.NET type that contains the JSON representation of the data.

To lose the dynamicity and be strongly typed, we do .As. With that will instantiate a new TitlePart object, which will be the deserialization of the JObject property. So, we deserialized the JObject into an instance of TitlePart:

content.As<TitlePart>().Title;

What happens if we want to change the Title of the TitlePart? We could say something like:

content.As<TitlePart>().Title = "Foo";

But what we are doing is we have a new object (TitlePart) and change the property Title, but we didn't change the JObject property that is attached to the content item. So, we changed a clone of the TitlePart. It's a new object we change.

In Orchard Core what we need to do is something like:

var titlePart = content.As<TitlePart>().Title;
titlePart.Title = "Foo";
content.Apply(typeof(TitlePart), titlePart);

The Apply will bind back the TitlePart instance we have to the property named TitlePart of the content item we have.

So, we extract the JObject into a TitlePart instance. We change the instance and we map back the TitlePart instance into the JObject structure of the content item. This is what every driver, every part driver, every field driver is doing when we want to update some data.

You don't see the Apply, because what we do in the driver, we get a part. This part is something that the coordinator (the drivers) will give you from the part definitions. So, it says let me extract the JObject property named for example MenuPart. Let me give you an instance of this class and this is what you have to update. What the coordinator does, it will reapply back the change you did to the JObject.

This is the roundtrip between a JObject and a class. It would be nice if we could just say the following without needing the Apply.

var titlePart = content.As<TitlePart>().Title;
titlePart.Title = "Foo";

It would be great if we can just simply assing the Title to the JString represented in our content here. And it would be technically doable. When we do .As, we return a class inheriting from TitlePart, with all its properties that are proxies to the actual JTokens that are represented in the content item.

So, this is doable by using dynamic proxies. The only issue is that you can only create a dynamic proxy on an interface. Because TitlePart is a class, we can't do that.

One of the biggest advantages of this approach is the performance, because we don't have to convert back and forth the items. We don't have to create new strings and everything. If we want to do that we will need to change the parts (that are classes) into interfaces which should be fine, because all the parts we have only contains properties, without any logic inside. All of them are mostly just data. The logic is extracted into handlers and drivers. So, if we had all the parts being interfaces then we could have this logic automated using dynamic proxy. When we do .As, we actually have a proxy that modifies the inner JObjects or JTokens that correspond to the content item directly without passing an actual instance of the TitlePart that we have to bind back.

That would be a breaking change, but that could be good on a long run. It will change the way we write content parts like we did it in the following example:

Demos

Reverse Proxy module

Reverse Proxy is about when you host your Orchard Core web app or CMS behind a proxy. There will be a new module to Orchard Core called Reverse Proxy Configuration module.

To set up Reverse Proxy, navigate to Configuration -> Settings -> ReverseProxy.

The Coming Soon recipe and The Coming Soon Theme

The new theme, called The Coming Soon Theme is built for SPA sites that are under construction, but the site owner would like to show something instead of a 404 or a static HTML page. Here users can enter their email address and when the site is ready, we can send them an email about the launch of our new site.

In the admin, we could see the only content item is called Coming Soon. It is a Form and also has the FlowPart to contain widgets. The goal of this form on this homepage is that if the user types an email (and have the ReCaptcha validation) then they will receive a mail to verify their address. After they will be registered to the site.

We have one workflow here, called User Registration. This workflow is responsible to validate ReCaptcha, register the user and send an email to them.

The comingsoon.recipe.json is the recipe that contains the User Registration workflow and it's activities.

The form also comes from the recipe which will trigger the workflow. So, this recipe is a great example of how to set up a form to call an action using the recipe.

Cross-Origin Requests (CORS) with Cors Configuration module

The standard behavior of a standard ASP.NET Core website is that to allow single-origin request and reject things that come out from the origin. It could be a problem when you for example host a solution for an OpenID in a different server.

To solve issues like that, a new module will be available for Orchard Core called Cors Configuration. After enabling the module, navigate to Configuration -> Settings -> Cors, where you can add new policies.

Don't forget to watch the whole recording of this week's Orchard meeting!

No Comments

Add a Comment