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

Content Tree Module, Orchard Core Admin UI experience renewal survey - This week in Orchard (06/06/2025)

This time, you can see a fascinating demo of the Content Tree Module! But first, let's look at our other topics, like adding GraphQL support for querying content items by status from the Content Picker Field, fixing binding form input in the Coming Soon theme, and improving the Register User Task. Don't forget to fill out our Orchard Core Admin UI experience renewal survey to help shape the future of Orchard Core!

Featured tags

IIS
API
SMS
SEO
MCP
All tags >

Why is my content part not recognized in Orchard Core? - Orchard Core Nuggets

You have implemented your MyAwesomePart but you cannot attach it to your content type using the dashboard because it's not showing in the Content Parts list (Content -> Content Definition -> Content Parts)?The most possible reason for this that you haven't registered your implementation in the service container. To register your class in the service container head to the Startup.cs file of your module and in the ConfigureServices method add the following line: services.AddSingleton<ContentPart, MyAwesomePart>();But if you are using the RC1 version of Orchard Core or newer you can use the AddContentPart extension method, where you just only need to provide your content part: services.AddContentPart<MyAwesomePart>();. The AddContentPart and the AddContentField (that you can use to register your fields) can be found in the OrchardCore.ContentManagement namespace.Another recommendation is to use the Part suffix when naming your class or cs file that contains your custom part. Don't forget to put it in a Models folder to follow the recommendation of the MVC (model-view-controller) software design pattern.For more information about registering your Part check out the Startup.cs file of our Orchard Core Training Demo module, where we registered the PersonPart in the service container. We also mentioned the new way of registering ContentParts and ContentFields in this post of our This week in Orchard series. Did you like this post? It's part of our Orchard Core Nuggets series where we answer common Orchard questions, be it about user-facing features or developer-level issues. Check out the other posts for more such bite-sized Orchard Core tips and let us know if you have another question!

This week in Orchard - 12/06/2019

New domain for the home page and the documentation of Orchard Core! New list query helpers, updated documentation, designing the admin UI of Orchard Core and many more are waiting for you in our upcoming post! On Orchard Core Potential fix for disabling core modules There were some modules in Orchard Core that if you disable you break your site. For example, if you disable the OrchardCore.Recipes module, you will face with a message:InvalidOperationException: Unable to resolve service for type 'OrchardCore.Recipes.Services.IRecipeMigrator' while attempting to activate 'OrchardCore.Menu.Migrations'. But you will see errors if you disable the OrchardCore.Settings, OrchardCore.Features or OrchardCore.Scripting modules too. From now you can set the IsAlwaysRunning property to true in your FeatureAttribute or ModuleAttribute to make sure your feature can't be disabled. Let's see the content of the Manifest.cs file of the OrchardCore.Features module, where you will see the new IsAlwaysEnabled boolean. [assembly: Feature( Id = "OrchardCore.Features", Name = "Features", Description = "The Features module enables the administrator of the site to manage the installed modules as well as activate and de-activate features.", Dependencies = new [] { "OrchardCore.Resources" }, Category = "Infrastructure", IsAlwaysEnabled = true)] Now if you head to Configuration -> Features and search for a module that is not allowed to disable, you will see that the red Disable button is missing near that module. New list query helpers There are two new helpers and filters to list the items of a List Part. The two news Orchard helpers are: QueryListItemsAsync: returns the enumerable of list items satisfying given predicate. QueryListItemsCountAsync: returns the number of list items satisfying given predicate. These helpers have their corresponding Liquid Tags as well, which are the following: list_items: the list_items filter loads published list content items for given ContentItem object or explicit ContentItem ID given as a string. list_count: the list_count filter counts published list content items for given ContentItem object or explicit ContentItem ID given as a string. Including Azure Active Directory recipe step and updating the documentation When you are using the Azure Active Directory, you have to set up several things, like the Application ID or the Callback Path. Now you can set those with several other ones during recipes using the settings step. In the documentation, you will find a sample of how you can do that. New UI for queries, admin templates, and templates The work continues on unifying the admin UIs of the admin pages of Orchard Core. This week Antoine Griffard designed the queries, templates, and admin templates pages to have a consistent look. The queries page has no select all option because there are no bulk actions on that one yet. Naming convention on NuGet.org When you create your own third party package for Orchard Core you can publish it to NuGet.org anytime you want. When uploading your package you have to give it a speakable name. Users probably will type the Orchard Core keywords to find packages that contain modules or themes that can be used with Orchard Core, so that could be a good way to include the OrchardCore word in the title of your package. But if you name your package OrchardCore.MyAwesomeFeature how would the users know that which packages are the official ones for Orchard Core and which are the modules that are provided by other developers? To solve this problem Sébastien Ros reserved the OrchardCore ID prefix. So when you navigate to NuGet.org and search for OrchardCore, you will find a blue tick near some packages. These packages are the official ones with the hover text: "The ID prefix of this package has been reserved for one of the owners of this package by NuGet.org.". The recommendation is to suffix your package with OrchardCore. For example, the name of the Disqus module in NuGet is Disqus.OrchardCore. You can also have a tag containing Orchard Core to add to your package. There could be documentation about how to create and publish your own module to NuGet.org. This documentation could contain the naming convention too, therefore the packages in the future could have the convention mentioned above and be consistent across NuGet.org and can be easily identified as a third-party module. New orchardcore.net domain You can reach the Orchard Core Documentation under the https://orchardcore.readthedocs.io URL and the official website of Orchard Core under the https://orchardproject.net address. The goal is to have a more unified experience for the users when they are meeting with Orchard Core browsing the online space. Therefore the community has bought a new domain for every content related to Orchard Core. First of all, the official website of Orchard Core is now accessible under the http://www.orchardcore.net address. But that's not everything! This site was a simple static site, but from now this site is powered by Orchard Core! This comes with a whole lot of new opportunities, for example, to fill the site with additional content like blog posts and other news around Orchard Core. And if there is a new domain let's use it for other purposes too! Now you can also reach the documentation of Orchard Core by visiting the http://docs.orchardcore.net URL. This site has the same content as https://orchardcore.readthedocs.io, but it's easier to remember and placed under the orchardcore.net domain. On Lombiq Extended title for This week in Orchard One of the main goals of This week in Orchard posts to give you updates and news about the different kinds of features and improvements of Orchard 1.x and Orchard Core. For now, we have more than 60 posts containing useful information that could be helpful (we hope so) for the developers and any others who are interested in working and using Orchard in the future. To find the information you need you to have to search for different keywords. That's why we are thinking about changing the titles of our This week in Orchard series by adding some keywords about highlights in the title of the posts and newsletter subjects. What do you think about that? Could it be helpful for you in the future? Please help us and tell your opinion on this Twitter poll! Orchard Dojo Newsletter Now we have 106 subscribers of the Lombiq's Orchard Dojo Newsletter! We have started this newsletter to inform the community around Orchard with the latest news about the platform. By subscribing to this newsletter, you will get an e-mail whenever a new post published to Orchard Dojo, including This week in Orchard of course. Do you know of other Orchard enthusiasts who you think would like to read our weekly articles? Tell them to subscribe here! If you are interested in more news around Orchard and the details of the topics above, don't forget to check out the recording of this week's Orchard meeting!

This week in Orchard - 11/30/2019

Fixing and improving Orchard Core for the upcoming 1.0 release. One of the main focuses is on every admin page that has a list with filters and/or bulk actions, use the same UI. With that, the users will get a better user experience by the unified UI. And don't forget to check out the Swagger demo! On Orchard 1.x Cannot insert duplicate key in object dbo.Settings_ShellFeatureStateRecord The feature names are compared without ignoring the case in EnableFeatures (with 's') and DisabledFeatures (with 's'). It causes Violation of UNIQUE KEY constraint 'UC_SFSR_SSRId_Name'. Cannot insert duplicate key in object 'dbo.Settings_ShellFeatureStateRecord' error when there is a module that has the same name but lower case in Settings_ShellFeatureStateRecord table and/or Settings_ShellFeatureRecord. featureState.Key.Id.Equals(fId, StringComparison.OrdinalIgnoreCase) has been used in the EnableFeature (without 's') so the fix is to use the same code for EnableFeatures and DisabledFeatures. On Orchard Core Register content definition models for Liquid When using Liquid, you could do something like this: class="tags {{ Model.PartFieldDefinition.Name | html_class }}" But this returns nothing because the ContentPartFieldDefinition and other associated models haven't been registered for use with Liquid. The fix is to just register the missing models in the Startup.cs file of the OrchardCore.Liquid module. Discarding the draft of a content item removes the published one from the indexes We had a weird error in Orchard Core. Let's say you add and publish a blog post. Now edit and save it to have a published and a draft version too. Then do a DiscardDraft on it, so we only have the published version left. Now if you run the BlogPostsQuery (that comes from the Blog recipe) we can see that it is no more indexed. To fix this try to rebuild the index, but the blog post is still not indexed. The reason is that because when discarding a draft we trigger a removed event then if there is a published version we set it to be the latest and we set the context.NoActiveVersionLeft to false. Now it has been fixed. Register missing Steps in Startup You have to implement the IRecipeStepHandler interface if you want your recipe step to be processed. Each implementation is responsible for processing only the steps that it targets. After you can use the AddRecipeExecutionStep extension method to register your implementation to the DI. We have recipe steps for the GitHub authentication settings, Facebook, Twitter and Microsoft Account settings too. These interfaces haven't registered to DI, so now, if you check one of the startup files, you will see the new lines in each file. New Indices UI If you have the OrchardCore.Lucene feature enabled, you can head to Search -> Indexing -> Lucene Indices page, where you will meet with a brand new UI for indices. New Users UI Now the Users page also supports bulk actions. Here you can see that you can select multiple users at a time and approve or delete them in a bulk. Workflows UI and Bulk Actions As you can see, the goal is to unify the admin pages in Orchard Core. In the Workflows page you can now also have the ability to do bulk actions: select two or more workflows then delete them in just one click using the Actions dropdown! Elsa Workflows 1.1.3 released Elsa Core is a workflows library that enables workflow execution in any .NET Core application. Workflows can be defined not only using code but also as JSON, YAML or XML. Last week Elsa Core 1.1.3 released including the classical MassTransit ShoppingCart example, implemented as an Elsa Workflow (with MT activities). Both Orchard and Orchard Core ship with a powerful workflow module and both are awesome. In fact, Elsa Workflows is taken & adapted from Orchard Core's Workflows module. Elsa uses a similar model, but there are some differences: Elsa Workflows is completely decoupled from the web, whereas Orchard Core Workflows is coupled to not only the web but also the Orchard Core Framework itself. Elsa Workflows can execute in any .NET Core application without taking a dependency on any Orchard Core packages. Demos Swagger module for Orchard Core When you navigate to Configuration -> Features you will see two new modules: OrchardCore OpenApi documentation generation: enables OpenApi documentation generation of the OrchardCore APIs. Swagger OpenApi documentation: enables the Swagger endpoint for displaying OpenApi documentation. When you enable the first one you will have the OpenApi documentation generation for the APIs of Orchard Core. Swagger is a set of open-source tools built around the OpenAPI Specification that can help you design, build, document and consume REST APIs. If you enable the second module too, you could Swagger by just simply using the /swagger URL in your Orchard Core site. If you want to see the full demo about how to use Swagger with Orchard Core check out the video too! This feature is under development and you can see the current state of the module if you check out on this branch. On Lombiq Orchard Dojo Newsletter Now we have 106 subscribers of the Lombiq's Orchard Dojo Newsletter! We have started this newsletter to inform the community around Orchard with the latest news about the platform. By subscribing to this newsletter, you will get an e-mail whenever a new post published to Orchard Dojo, including This week in Orchard of course. Do you know of other Orchard enthusiasts who you think would like to read our weekly articles? Tell them to subscribe here! If you are interested in more news around Orchard and the details of the topics above, don't forget to check out the recording of this week's Orchard meeting!

This week in Orchard - 11/22/2019

This week the community behind Orchard Core was soo productive again, that means we can ship you a lot of news around the CMS. You could read about the new UI for tenants, an updated Trumbowyg editor, updated script and style tag helpers and a nice demo about how to add tags using taxonomies! On Orchard Core Insert image in HTML instead of Liquid in the WYSIWYG editor In the past, when you insert an image using the HTML editor, it adds Liquid code. It can be a bit weird for some users that they would expect to be able to see the image in the WYSIWYG editor. The only advantage seems to be that it will resize the image to the expected size, but we are losing something important for "standard" users. A relatively low-risk option would be to render the media URL with the prefix only. The only case it would break the site is if the production instance uses a different prefix. The best solution would be to add a setting in the editor to either render media as img tags or Liquid tags. This way the end-user won't have to make the decision, and the admin knows how the site is published. To show you how this setting works, let's set up a site with the Blog recipe and edit the Blog Post content type. Add two new HTML Fields to it with the Trumbowyg editor type. For the second one, put a tick in the Insert Media with URL checkbox. Now upload an image to the Media Library then create a new Blog Post. Insert the same media item to both HTML fields and view the HTML of the fields. You could see that by default the Liquid tag is used to insert the image. In the case of the second HTML Field, you could see the img tag is used and when editing the content of the field, you could see the rendered image. Add view button to media app grid and field container The media app always appends ? to the query string, when building resized thumbnail URLs. With a custom secured blob media file store, in a project, this causes the query string to be built badly. This means the attached media field thinks the file doesn't exist, so tries to delete it every time. Dean Marcussen removed the cache busting support, but kept the check for an existing query string in the media app, this check fixes an issue using a custom secure Azure Blob implementation that appends a blob secure access key to the media URL. And there is a new View button to the media grid to each media library item in order to preview the file and easily copy the URL. Tenants new UI The Tenants page has a new UI based on the content items UI. You have quick filters to show only the running tenants, only the disabled tenants or only the uninitialized tenants. You can filter the tenants by the state or sort them by name or state. You can also disable or enable multiple tenants in a row. Prevent ConnectionResetException on SelectedContentType change Sometimes there was a ConnectionResetException when changing the content type selection under the content items index page. It doesn't stop the app but errors are logged. Microsoft.AspNetCore.Connections.ConnectionResetException: 'The client has disconnected'0x800704CD "An operation was attempted on a nonexistent network connection." It was first failing in FormValueRequiredMatcherPolicy and Jean-Thierry Kéchichian could fix it by checking httpContext.IsRequestAborted but then it was failing elsewhere in Asp.NET Core. We need to commit the following changes to fix the issue: Removed an event that seems to be never triggered. Then, when changing the content type selection, he kept the update of the action attribute but he removed the form submission that seems to be done in the following event. So he thinks the form was submitted twice and we were processing the second one while the page was refreshing on the client-side. Allow script/style tag helpers to add dependencies Now you have the ability for the script and style tag helpers to add to the dependencies defined on a ResourceManifest. A lot of the script tags uses depends-on="admin" for no good reason. However, that doesn't work when the resource is registered with a ResourceManifest. A ResourceManifest can set its own dependencies, but until now a script tag helper cannot add to them. It makes sense that a resource manifest entry should define its own dependencies, however not being able to add to them is confusing (and has led to some 30-40 entries using depends-on="admin" in the Orchard Core Razor code, that are useless currently). The best actual use case for wanting to add to dependencies on the fly is for the bootstrap-select. It's manifest depends on jQuery which is good, but it also needs Bootstrap. But Bootstrap is compiled into the admin.js. So the manifest can't refer to that, or it will fail when used elsewhere without the admin. So it makes sense to define the admin dependency on the fly. Noting that it currently works, in the correct order, because the jQuery dependency also exists in the admin, and it gets lucky. Demos Tags using taxonomies We don't have a tags module in Orchard Core that is using taxonomies. The decision has been made that the community wants to have a tags module that will use taxonomies. The idea is to use taxonomies in a way to create a custom editor for the taxonomy that would just reflect something like a tags editor and store the taxonomy terms as any other taxonomy fields. There are pros and cons for both solutions using taxonomies for tags and not using taxonomies for tags. Pro: Reusing what we already have. Con: Might be the performance, because we store term IDs, instead of storing the data, but there are ways to optimize that by also storing the data we want as a tag. Let's set up a site using the Blog recipe. Head to Configuration -> Features and enable the Taxonomies module. Then create a new content type and call it Site Tags. For now, only add the Title Part for this content type. Go ahead and create a new Taxonomy called Site tags and select the previously created content type as the term content type. Finally, add some sample term content types to this taxonomy. Now edit the definition of the Blog Post content type and add a Taxonomy Field to it. Edit that field and see that here you can select the Tags editor type to use. Now create a new blog post or edit an existing one. Here you can see that we added two taxonomy fields to the blog post, one with the standard editor (called Taxonomy) and one with the tags editor (called Tags). When adding tags, the green background shows that the selected tag hasn't been selected yet and the red background shows that the tag has been already added to the list. If you type something you can create a new tag that will be added to the list of tags (under development, but will be available soon). This feature is still under development, but you can check the progress in this branch. And if you checkout to the latest commit of this branch and set up your site using the Blog recipe you will find that the blog posts have a taxonomy field attached with the tags editor using some sample tags. Furthermore, the styling of the tags has been added too! It's a great sample for you to show how to add styling to your tags! If you want to see the full demo of using tags check out the video too! On Lombiq Poll to upload recordings of demos in separate videos as well Last week we created a poll on Twitter about uploading the recordings of demos from the weekly meeting in separate videos as well, so they can be found easier. We had 24 votes and everyone said that you want us to upload these demos separately. :) So from now, if you check the playlists of the YouTube channel of Lombiq you will find a new one, called Orchard Core Demos. Every new demo will be added to this playlist and the name of the video will be {name of the demo} - Orchard Core Demo. And (as you could see) from now we embed the recordings of the demos in our This week in Orchard posts too. Searching for performance-intensive codes Do you write a performance-intensive code? Then help us build the nerdiest .NET thing! Drop us a line to [email protected] and we'll ask a few questions about the challenges you encounter, and in exchange, we'll show you how to make a chip out of your programs! Orchard Dojo Newsletter Now we have 103 subscribers of the Lombiq's Orchard Dojo Newsletter! We have started this newsletter to inform the community around Orchard with the latest news about the platform. By subscribing to this newsletter, you will get an e-mail whenever a new post published to Orchard Dojo, including This week in Orchard of course. Do you know of other Orchard enthusiasts who you think would like to read our weekly articles? Tell them to subscribe here! If you are interested in more news around Orchard and the details of the topics above, don't forget to check out the recording of this week's Orchard meeting!

This week in Orchard - 11/15/2019

This week we would like to show you two demos about the newest features of Orchard Core. First, you can take a look at the brand new content items UI, then we will dive a bit deeper and try out the new Trumbowyg editor for the Text Field and the HtmlBody Part. And of course, the discussion continues about the next Harvest! On Orchard Core Filter Features dependencies When you navigate to Configuration -> Features you have the ability to enable or disable the different features. To find the feature you want easier you can use a filter here and can type the name of the module. This filter only sort by the name of the feature. From now this filter checks for the different dependencies too! For example, if you type localization, you could see the Content Culture Picker in the list, because this module has dependencies with names like Content Localization or Localization. Harvest Core 2020 Sipke Schoorstra has connections in Nice and Miami, so that would be easier to organize the next Harvest one of these cities. Nice is in Europe, but Miami is warmer and easier to travel there from Europe because it's on the East Coast. The two possible dates are February and April, but the weather is not the same in these cities. If we do it in April, Nice would be the better option because of the weather. Miami is warmer in both months, so that wouldn't be an issue. Stay tuned for more information about the next Harvest! Demos New content items UI Now when you enter the admin site and go to Content -> Content Items, you will see a brand new UI. Under the Content Type dropdown, you can filter the items based on the selected or the typed type. You can filter the items by their status using the Show dropdown. And lastly the Sort dropdown is responsible to order the items by title, recently created, recently modified or published. If you select more than 1 item, you will see a new dropdown, called Actions, instead of the dropdowns we mentioned above. By using the Actions, you can publish, unpublish or delete the selected items. Lastly, we would like to mention the Filters dropdown near the textbox that has the Search all content items placeholder text. By using this you can filter the list by showing only the draft items, only the published items or the items owned by the logged-in user. Adding Trumbowyg editor for TextField and HtmlBody Let's set up a site using the Blog recipe. This recipe contains an Article content type. If you edit the definition of the Article under Content -> Content Definition -> Content Types you will see the attached HtmlBody Part. Hit Edit near it and select that you would like to use the Trumbowyg editor type. Under the editor options you can explicitly set the config you want to use, for example, which button you want to add to the toolbar. If you navigate to the OrchardCore.Resources module and check the content of the Assets folder, you will see the files that needed for the Trumbowyg plugins to work. Therefore you can use every existing plugin that is described on this page. Trumbowyg has a lot of plugins that you can use to customize your editor. Now let's add some new buttons to the editor! We will use the emoji, the giphy, and the font family plugin. All you need to do is to extend the btns section of the editor options like this: btns: [ ["viewHTML"], ['emoji', 'giphy', 'fontfamily'], ["undo", "redo"], ["formatting"], ["strong", "em", "del"], ["foreColor", "backColor"], ["superscript", "subscript"], ["link"], ["image"], ["align"], ["unorderedList", "orderedList"], ["horizontalRule"], ["removeformat"], ["fullscreen"]], plugins : { giphy: { apiKey: 'N5OwBrzBjP8nXXaFdv1TvVwZ82DWNUSz' }} Here you can see that the three new buttons will be placed after the View HTML button and will be near each other without a separator. The buttons you define in the same square brackets will be in one group. You could also see that we added a new section here, called plugins. Here you can define the options that needed for the different plugins. For example, to use giphy, you need to have an API key that will communicate with GIPHY. If you navigate to the Dashboard on the GIPHY Developers page you can create a new one by clicking on the Create an App button. Now you have successfully set up the editor options. It's time to create a new Article! Notice the three new dropdown buttons near the View HTML button and use them to create your awesome article! Another nice stuff is the template plugin, that manages a set of HTML templates to insert fast. In these options we only define the templates plugin with two options: { btns: [ ["template"] ], plugins: { templates: [ { name: 'Lorem ipsum', html: '<p>I am a Lorem ipsum template</p>' }, { name: 'Lorem ipsum 2', html: '<p>Another Lorem ipsum template</p>' } ] }} In this case, the editor will look like the following, where if we select the Lorem ipsum 2 option, the following HTML content will be injected to the editor. The same works for HTML Field too. If you add a new HTML Field to your content type and set the editor to Trumbowyg editor, you can define the editor options and you will get a customized Trumbowyg editor. On Lombiq Upload recordings of demos from the weekly meeting in separate videos We have an idea to upload recordings of demos from the weekly meeting in separate videos as well, so they can be found easier. To help us decide please visit our Tweet and choose from the following options: Good, I look for demos! Good, but don't need it. Bad, why more videos? Another idea, see reply! Searching for performance-intensive codes Do you write a performance-intensive code? Then help us build the nerdiest .NET thing! Drop us a line to [email protected] and we'll ask a few questions about the challenges you encounter, and in exchange, we'll show you how to make a chip out of your programs! Orchard Dojo Newsletter Now we have 102 subscribers of the Lombiq's Orchard Dojo Newsletter! We have started this newsletter to inform the community around Orchard with the latest news about the platform. By subscribing to this newsletter, you will get an e-mail whenever a new post published to Orchard Dojo, including This week in Orchard of course. Do you know of other Orchard enthusiasts who you think would like to read our weekly articles? Tell them to subscribe here! If you are interested in more news around Orchard and the details of the topics above, don't forget to check out the recording of this week's Orchard meeting!

This week in Orchard - 11/08/2019

Orchard Core has a brand new redesigned admin menu to help you find the settings you want easier. The CMS gets a lot of new improvements and fixes from time to time and it's time to start a discussion about releasing version 1.0. And now it's time to organize the next Orchard Harvest! Would like to know more? Then don't hesitate, check out our latest post with this week's news! On Orchard Core Add UI for PageSize You can edit the setting named PageSize that exists for a time ago, but there was no UI for it. This setting should be used when using pagers so that users can define how many items they want to see on the page. Rename Default into Current in Themes It could be quite confusing that the currently active theme is called Default on the admin UI. It's not something that would be enabled by default (since setup recipes decide this) and it's not a fallback in case of no other theme either since that's the Safe Mode Theme. So from now the new name of the Default theme is Current theme. Just head to Design -> Themes to see the changed interface. Adding token expiry for GlobalMethod and documenting scripts There was an issue with the lifetime of the workflow token. Now when you don't specify the lifetime of the workflow token you will get the value of the NoExpiryTokenLifespan variable in days, which is 100 years. Here you can see the updated code using the mentioned NoExpiryTokenLifespan variable. public class TokenMethodProvider : IGlobalMethodProvider{ private readonly GlobalMethod _createWorkflowToken; public TokenMethodProvider() { createWorkflowToken = new GlobalMethod { Name = "createWorkflowToken", Method = serviceProvider => (Func<string, string, int, string>)((workflowTypeId, activityId, days) => { var securityTokenService = serviceProvider.GetRequiredService<ISecurityTokenService>(); var payload = new WorkflowPayload(workflowTypeId, activityId); if (days == 0) { days = HttpWorkflowController.NoExpiryTokenLifespan; } return securityTokenService.CreateToken(payload, TimeSpan.FromDays(days)); }) }; } public IEnumerable<GlobalMethod> GetMethods() { return new[] { _createWorkflowToken }; }} And now you can find documentation for the javascript methods that are available in workflows for instance. When to ship Orchard Core 1.0? If you check the .NET Core Roadmap, you could see that the release of .NET Core 3.1 is scheduled for December 2019. The suggestion is to ship Orchard Core 1.0 with this version of .NET Core because there won't be any update until the .NET 5.0 and this way the community could align the same way as did when released Orchard Core RC. It gives the community one month to polish and merge missing PRs. This way there will be no need to reupdate when 3.1 is released. Starting the discussion about the next Orchard Harvest We will have a 1.0 soon and we already have the RC of Orchard Core. The community decided to organize the next Harvest if Orchard Core reaches a state that we can show at the conference. Now it's time to show the new framework by workshops too to learn the features of the new version. The suggestion is to make it happen in February or April of 2020. Let's do it probably in Europe because the last time it was in the United States. There are some options like Hungary, Italy, Greece, Spain or England. So, let's come back to this topic later and keep up the discussion! Building Workflow Driven .NET Core Applications with Elsa Sipke Schoorstra decided it was about time to take Orchard Core’s workflow engine and philosophies and turn it into a reusable, .NET Standard library, enabling any .NET application to enjoy the power of workflow. In this huge and informative post, he introduces Elsa, an open source suite of .NET Standard libraries and tools that enable developers to implement long-running workflows. The core philosophy of Elsa is to be able to connect small executable units with one another, allowing you to orchestrate real business processes such as document approval, customer on-boarding and order fulfillment processes. Following the guide "Creating a new decoupled CMS Website" live on Twitch Davin Davies a.k.a. copperbeardy decided to follow the guide called Creating a new decoupled CMS Website and broadcasting it using a live stream in Twitch. He tried to follow it once at the end of October, that session was very useful to fix and update the documentation and in some cases the code to be able to follow that with the latest changes of Orchard Core. Check out his second stream about following that guide again to create a decoupled site! Demos New Admin menu Here you can see the admin menu of Orchard Core if you enable every feature. Some of them don't have many sub-items, for example, the Content has only two (Content Items and Assets), and some of them have quite a lot. If you check the Configuration option, there are 13 sub-items. And at the bottom of the screen, you could see that every authentication provider has its own entry instead of grouping them in a section something like Authentication. There was a suggestion to reorganize the admin menu to make it cleaner that could make it easier to find the options you want. That could be a good point for the new structure to use the same setup as we used when updating the documentation. If you open the docs and click on the Key Topics, you could see a menu in the left with the following points: Manage your Content Customize the Display Localize your site Handle the Media Navigate between pages Query and Search data Secure your application Workflows When you update to the dev branch of Orchard Core you will face with the new, redesigned admin menu. Let's see what will you see if you enable every feature that is available right now. As you can see, the Content menu has everything you need to define your content types and manage your content items dynamically. Under Design, you could see everything related to the look and feel of your site. Here you can define templates, change the themes, etc. Widgets is a new option where you can edit the widgets and layers. That option was called Layers in the previous structure. Under Security, you will find the settings of the third-party authentication providers, can manage the users and the roles, and of course the OpenID settings. But that's enough talk for now, check out to the dev branch of Orchard Core and try the new admin menu now! On Lombiq Searching for performance-intensive codes Do you write a performance-intensive code? Then help us build the nerdiest .NET thing! Drop us a line to [email protected] and we'll ask a few questions about the challenges you encounter, and in exchange, we'll show you how to make a chip out of your programs! Orchard Dojo Newsletter Now we have 100 subscribers of the Lombiq's Orchard Dojo Newsletter! We have started this newsletter to inform the community around Orchard with the latest news about the platform. By subscribing to this newsletter, you will get an e-mail whenever a new post published to Orchard Dojo, including This week in Orchard of course. Do you know of other Orchard enthusiasts who you think would like to read our weekly articles? Tell them to subscribe here! If you are interested in more news around Orchard and the details of the topics above, don't forget to check out the recording of this week's Orchard meeting!

This week in Orchard - 11/01/2019

Do you remember the Nwazet Commerce module for Orchard 1.x? Orchard Core Commerce will be the Orchard Core port of that module and this week we will see the current state of this module! But first, take a look at the new structure for the documentation and the other improvements of Orchard Core! On Orchard Core The new structure for documentation When you navigate to the Read The Docs site to check the documentation of Orchard Core, you will meet with a brand new structure. All the previous docs are under the Reference menu on the top. Here you can see all the modules and their reference documentation. The Key Topics are just explaining core concepts. Explore the new documentation now! Add culture argument to localization_set filter This adds an argument for culture in the localization_set filter and defaults to current culture if there are no arguments. {{ Model.ContentItem.Content.LocalizationPart.LocalizationSet | localization_set: "en" }} New ContentCard Shape to make Flow Editor extensible Now the ContentCard shapes have been merged to the dev branch of Orchard Core, so you can use this awesome feature! But why ContentCard Shape Needed? Every widget within FlowPart, BagPart, and WidgetsListPart has Bootstrap card with similar UI which can be dragged or deleted. Unfortunately, these parts add hard-coded alternate for widget editor Widget_Edit__Flow, Widget_Edit__Bag, and Widget_Edit__List just before DisplayAsync hence - none of the custom alternate defined in admin theme for the widget is applied i.e. Widget-WeatherWidget.Edit.liquid (Widget_Edit__WeatherWidget). Due to hard-coded alternates, none of the placement customizations on Content_Edit applies to Flow editor. i.e. having AdminTab in Flow editor. All widgets are framed with a <div> tag, with no ability to customize. This limits the usability of the Form module and makes very cumbersome to create complex forms. FlowPart, BagPart, WidgetsListPart has the advantage of the free flow page but did not come even close to the usability of Layout in Orchard 1.x and Layout Template. Orchard DisplayMangement is powerful but FlowPart, BagPart, WidgetsListPart not utilizing it to make it extensible. These parts render cards using a hard-coded widget template in javascript, which doesn't honor shape alternates. How ContentCard Shape Helps? Doesn't add any alternates to Content Editor, hence any edit alternates defined for a widget will be displayed in Flow editor. Because it's using Orchard DisplayMangement, that means all placement details are applied including Admin Tabs within Flow editor. Defines ContentCard_Frame shape and list of alternates that module developers can override in Module or Admin Theme. Ability to disable, move or delete the Widgets to create Orchard 1.x like Layout Template. Ability to control, expand or collapse by a developer in Module/Admin Theme. Rendered 100% from a shape, not using an HTML template inside Javascript. Uses ShapeTableProvider to define alternates. Orchard 1.x layout like UI created with ContentCard shape, using some ContentTypes in BagPart and creating alternates only for ContentCard_Frame shape. Just check out to the dev branch to try out the new editing experience right now! Add configuration section to setup docs You can set up your site by providing the configuration parameters via the appsettings.json file. The documentation has been improved with the correct way you can do that. Default pattern for autoroute and alias When we add an Alias Part or an Autoroute Part, we don't have to go to the Settings, it will now use a standard pattern. public class AliasPartSettings{ [DefaultValue("{{ ContentItem.DisplayText | slugify }}")] public string Pattern { get; set; } = "{{ ContentItem.DisplayText | slugify }}";} Demos Orchard Core Commerce module Orchard Core Commerce will be an Orchard Core port and partial rewrite of the open source Nwazet Commerce module that was built for Orchard 1.x. Nwazet Commerce was initially built in 2012 by Bertrand Le Roy, loosely based on a commerce sample by Sipke Shoorstra. Now let's see the current state of this module because there are features that you can already try out! First, set up your dev environment: Download/clone the module from GitHub. Place it under the src/OrchardCore.Modules folder. Add the existing project to the solution under src/OrchardCore.Modules in the solution explorer if you're using Visual Studio. Add a reference to the module from the OrchardCore.Cms.Web project. If you are ready, build and run the solution. We set up the site using the Agency recipe for this demo. Now head to Configuration/Features in the admin, where you have to see the following modules. Enable both of them! Orchard Core Commerce: Registers the core components used by the Commerce features. Orchard Core Commerce Session Cart Storage: Registers session-based shopping cart persistence. In OrchardCore.Commerce any content type can be a product. It's just the manner of having the Product Part attached to your content type. This part identifies any content item as a product, by its mere presence. It has only an SKU, that describes the most basic product attribute, which can also be used as an alias for the item. You will also find a new Price Part, that just a simple product price that stores the price of the product. There is also the notion of Product Attribute Field, which adds the ability for a product to be modified with a set of attributes, in particular when added to a shopping cart. Examples of attributes can be shirt sizes (S, M, L, XL), dimensions, etc. Now let's try these out! Let's say we would like to sell T-shirts in our shop. Create a new content type called T-shirt and add the Title, Common, HtmlBody, Product and Price parts to it. Every product could have different fields, in our case, we will need a size, a message printed on the T-shirt and the color of the T-shirt. Let's add these fields to our content type using the Text Product Attribute Field type. You can add some predefined values to size and to colors and restrict them. Now let's create a new T-shirt, give it a name and some description and hit Preview. Here you can see that the users can customize their product using our fields. They can set the size, the quantity, the message, and the color. And at the bottom of the screen, you could see an Add to cart button. Let's fill out these fields and click on this button! We selected one black T-shirt with a size L and with a custom message. You can update the quantity here that will update the price if you click on the Update button or remove the product from the cart with the Remove button. So, for now, the following features are done: Product, price, and inventory parts and/or fields (those were a single part in Nwazet) Note: not all products have a price Shopping cart To do: Checkout (probably redesigned around Orchard Workflows) Base infrastructure for payment, plus one implementation (Stripe) Order content type and management screens (including a redesign and refactoring of the order part) Workflow activities On Lombiq Searching for performance-intensive codes Do you write a performance-intensive code? Then help us build the nerdiest .NET thing! Drop us a line to [email protected] and we'll ask a few questions about the challenges you encounter, and in exchange, we'll show you how to make a chip out of your programs! Orchard in Open Academy There will be the free Open Academy in Budapest on 22 November for all life long learning developers with no-BS tech talks, where Zoltán Lehóczky, the Co-founder and managing director of Lombiq Technologies Ltd. will talk about Orchard. Come and join the conference if you will be nearby! This week in Orchard in LinkedIn From now you could find our This week in Orchard series on LinkedIn, under the Lombiq Technologies Ltd. company account! Share and like these posts there too if you are learning something new reading our weekly recaps! Orchard Dojo Newsletter Now we have 101 subscribers of the Lombiq's Orchard Dojo Newsletter! We have started this newsletter to inform the community around Orchard with the latest news about the platform. By subscribing to this newsletter, you will get an e-mail whenever a new post published to Orchard Dojo, including This week in Orchard of course. Do you know of other Orchard enthusiasts who you think would like to read our weekly articles? Tell them to subscribe here! If you are interested in more news around Orchard and the details of the topics above, don't forget to check out the recording of this week's Orchard meeting!

This week in Orchard - 10/25/2019

This week we are coming with a cool demo of presenting the newest improvements of an upcoming Orchard Core module that will add sitemaps to your site! But first, don't forget to check the documentation of Orchard Core, we have a lot of additional lines here! On Orchard Core Updating OpenId docs about how to use the certificate on Azure When you would like to enable authentication of external applications using the OpenID Connect/OAuth 2.0 standards, you have to configure the certificates too. You can generate and store your certificate on Windows and/or IIS, but you can also upload the certificate on an Azure hosted site. This little addition to the docs will help you with that. CommitTransactionTask workflow activity When you have two concurrent updates that depend on each other, you need to commit the previous transaction, that you can follow up with the next one and the first one can continue and get another one. So, when you have two nested transactions to each other, you could create a deadlock, that is very specific to SQLite. Now there is a new Task available when you are creating workflows. The CommitTransaction activity is about committing the current transaction by calling the CommitAsync method of the ISession implementation. Add OrchardCore.Email docs We have the OrchardCore.Email module, that allows you to send emails using SMTP. You can configure the settings for this module by using the appsettings.json file. Now you will find documentation about how you need to fill this JSON file and also with some description about the meaning of the values. Add role description Now you can provide a description of a role when you are creating a new one or editing an existing one. It will make your life easier in the future if you have more roles and want to stores what are the current roles used for. Now we have documentation about what are the predefined roles used for and how to configure the roles through a recipe step. Four Orchard Core samples for Orchard Core Dody Gunawinata maintains a repository in GitHub that contains 305 samples for ASP.NET Core with projects about how to use Blazor, foundational ASP.NET Core samples and so on. This repository also contains 4 samples that show the different capabilities of Orchard Core. These are: Routing - MVC: This sample shows how routing works in an Orchard Core Framework app. Routing - Razor Pages: This sample shows how routing works in an Orchard Core Framework app when you are using Razor Pages. Static files: This sample shows how to use static files in the module. Multi tenant: This sample shows how Orchard Core Framework handles multi tenancy and how each tenant has its own configuration file. If you are interested in these samples or other ASP.NET Core samples you should definitely check this great and huge collection to learn something new! Scanning the code of Orchard Core for bugs PVS-Studio performs static code analysis and generates a report that helps a programmer find and fix bugs. PVS-Studio performs a wide range of code checks, and it is also useful in finding misprints and Copy-Paste errors. The authors of this project published an article about reviewing the results of a second check of the Orchard Core with this static analyzer. The current version of Orchard Core is made up of 2,767 .cs files, i.e. it's about one thousand files smaller. The downsizing and renaming of the repository suggest that the developers have isolated the project's core (commit 966), which is 108,287 LOC long. The analyzer issued 153 warnings: 33 first-level and 70 second-level ones. You should definitely check this article, you can learn a lot and write better code! Do you write a performance-intensive code? Then help us build the nerdiest .NET thing! Drop us a line to [email protected] and we'll ask a few questions about the challenges you encounter, and in exchange, we'll show you how to make a chip out of your programs. Demos Sitemaps module A few weeks ago we wrote about an upcoming module for Orchard Core: the Sitemaps module. Since then this feature improved a lot and will be released soon. Let's recap the latest changes of the module! First of all, when you navigate to the Configuration/Features on the admin site, you will see that there are three different Sitemaps modules: Sitemaps: Provides dynamic sitemap generation services. Sitemaps for Decoupled Razor Pages: Provides decoupled razor pages support for dynamic sitemap generation. Localized Content Item Sitemaps: Provides support for localized content item sitemaps. Let's check them one by one with a site that we set up using the Blog recipe. When you enable the Sitemaps module you can head to Configuration/Sitemaps and click on the Add Sitemap button. Here you will see two notions: the Sitemap Content Types, that add sitemap entries for each one of the selected content types and the Sitemap Index, which adds a sitemap index that acts as a container for other sitemaps. You can create a new Sitemap Content Type, that will lead you to a familiar page where you can select which content type you want to include in the index, among with the change frequency, priority and the number of content items to include. The other is called Sitemap Index. In the editor of the Sitemap Index, you can select which sitemap will this index contains. Because for now we have only one (called My Blog Posts) select this one. Hit Save and View this Sitemap Index. You can see that this index contains our only one sitemap with the last modified date of it and the location. By using sitemap indexes, you can provide a collection of sitemaps to search engines. For example, when using Google, all formats limit a single sitemap to 50MB (uncompressed) and 50,000 URLs. If you have more than 50,000 blog posts, you have to create two Sitemap Content Types. The first one will take the first 50,000 one and the second one is the rest. And your Sitemap Index will include these two Sitemap Content Types. Now let's move on and enable the Localized Content Item Sitemaps. To test this, first, attach the Localization Part to our Blog Post content type and create two blog posts, one in Hungarian and one in English. Now head back to the admin of the Sitemaps module and View our My Blog Posts Sitemap Content Type. You see that our sitemap provides more information to search engines. First of all, you can see that both the English and Hungarian versions of our blog post have been included in the sitemap. These come with the hreflang attribute. If you have multiple versions of a page for different languages or regions, tell Google about these different variations using the hreflang attribute. The loc is still used and that points to the version of the content item that was created using the default culture. Finally, enable the Sitemaps for Decoupled Razor Pages feature. For this, we will add a new content type, called DecoupledBlogPost. This content type will not have any parts or fields attached. To be able to provide a sitemap for decoupled Razor pages, first, configure the SitemapsRazorPagesOptions for our content type in the Startup.cs file of our module. services.Configure<SitemapsRazorPagesOptions>(options =>{ options.ConfigureContentType("DecoupledBlogPost", typeOptions => { typeOptions.PageName = "DBlogPost"; typeOptions.RouteValues = (contentItem) => { return new { area = "OrchardCore.Sitemaps", slug = contentItem.ContentItemId }; }; });}); Here you can see that a DBlogPost.cshtml file sits in the Pages folder and we just simply put this into the OrchardCore.Sitemaps module. We will pass the ContentItemId as a slug for our page. Now let's see the content of the Razor page: @page "/blogpost/{slug}"<h1>This is the blog post.</h1><h2>Slug: @Slug</h2>@functions{ [FromRoute] public string Slug { get; set; }} Now head back to the admin and create two new Decoupled Blog Post. After let's create a new Sitemap Content Type, called Decoupled Blog Posts, that will (surprisingly) index the Decoupled Blog Post content types. After you saved this sitemap, hit View! Here we are with the two Decoupled Blog Posts that have the ContentItemId in the URL. We haven't attached the Localization Part to this one, so the hreflang attribute will not be used here. Now open one of those blog posts! And here comes our decoupled blog post that is using The Blog Theme for rendering the content of this item. This feature is still under development and can be found in this branch. Big thanks again to Dean Marcussen for this great contribution! On Lombiq Lombiq Orchard Visual Studio Extension updated The Lombiq Orchard Visual Studion Extension just got some VS 2019 compatibility updates. There was a warning message that said One or more extensions were loaded using deprecated APIs. Check it out if you aren't using it already, you're missing out on quite some productivity boost! Orchard Dojo Newsletter Now we have 100 subscribers of the Lombiq's Orchard Dojo Newsletter! We have started this newsletter to inform the community around Orchard with the latest news about the platform. By subscribing to this newsletter, you will get an e-mail whenever a new post published to Orchard Dojo, including This week in Orchard of course. Do you know of other Orchard enthusiasts who you think would like to read our weekly articles? Tell them to subscribe here! If you are interested in more news around Orchard and the details of the topics above, don't forget to check out the recording of this week's Orchard meeting!

This week in Orchard - 10/18/2019

This week we are coming with a cool demo of using Statiq with custom GraphQL and Liquid modules to render static content for Orchard Core as a headless CMS! But before jumping to that don't forget to check out the other news around Orchard Core and another demo about adding the ability to generate DisplayText with a pattern! On Orchard Core Avoid slash in the role name The slash will add another segment that prevents to use from editing or deleting the role. Now we are checking that if the name of the role is containing a slash or not. If yes, you will see an error message. Decoupled CMS guide When you navigate to the Orchard Core Documentation page and hit the Index under the Guides in the left, you will see that we have a new tutorial here, called Building a decoupled website with Razor Pages. By following this step-by-step tutorial you can easily develop your own decoupled CMS site from the scratch. In this tutorial we learn how to: Start a new Orchard Core CMS project Create custom content types Edit content items Create Razor Pages with custom routes to render the content Load content items with different identifiers Render WYSIWYG preview screens while editing the content Add Breadcrumbs zone There is a new zone called Breadcrumbs in the layout of the admin. With that zone, we can inject breadcrumbs. Anywhere, where the breadcrumbs were used they are now using this zone, for example on the workflows page. There is a zone tag, so everything that is inside this zone tag will be injected inside the Breadcrumbs section. And here you can see the RenderSectionAsync call in the Layout.cshtml of TheAdmin theme. Updating themes All the themes that are using Bootstrap now have been updated to use the latest version. The main change is that all the static assets now are included in the themes, which means they can now be served by the Orchard instance and not just the CDN. And now each theme has a ResourceManifest, that defines all the assets that each theme is using, like jQuery, Bootstrap, Bootstrap bundle and so on. The local version and the CDN is also defined here, that allows these themes to reuse the settings that we set in the admin to select which version of the resources we want to use either local or CDN or based on the environment (meaning development will use local, production will use CDN). You can see a vendor- prefix in the names, it is to prevent conflicts with the resource names that we have defined in the OrchardCore.Resources module. Orchard Core Docs new structure The structure of the Orchard Core docs will be reorganizing and come with a new MkDocs theme. Here you can see just the material and here you can see the new structure that coming soon. Demos Add ability to generate DisplayText with a Pattern Let's set up a site using the Blog recipe. Now head to the admin site and edit one of the content types, for example, the Article. Add a new Text Field to it, let's use the Name for the Technical Name. Now edit the Title of the Article. Here you will see an Options drop-down list with the following options: Title is editable: you can edit the title when editing the content item. Title is generated and input is disabled: you can't edit the title and the textbox for the title is disabled. Title is generated and input is hidden: you can't edit the title and the textbox for the title is hidden. And under that, there is the pattern used to render the title of this content type. The pattern gets injected and this gets called when the content item is updated. Now let's edit the existing Article, called About and fill the Name Text Field with some value, for example Name. And change the value of the Subtitle Text Field to Subtitle. After hit Publish. Now if you navigate to Manage Content page you will see that the title of this Article has been generated using the values of the Name and the Subtitle Text Fields. Because at the content definition of the Title we select that the Title is generated and input is disabled, when you try to edit an existing article, you will see the disabled textbox for Title. Generating static sites using Statiq(Wyam) and Orchard Core If you haven't heard about Wyam(Statiq) yet, let's recap the underlying concepts first: Wyam is a simple to use, highly modular, and extremely configurable static content generator that can be used to generate web sites, produce documentation, create ebooks, and much more. Since everything is configured by chaining together flexible modules (that you can even write yourself), the only limits to what it can create are your imagination. Common static sites are using tools like Jekyll/Hugo which are based on content in markdown files, stored in GitHub. Some arguments: This might work for small and technical teams, but when users are more than a handful or don't have technical knowledge it's not possible anymore. When assets management is required, with organizing images or adding metadata. Rights management, such that sections of the site can only be modified by some users. Editing workflow, when content needs to be reviewed and pass different levels of validation. Allow more complex editing scenarios, like editing maps, choosing a color. Managing more than a dozen content items, like e-commerce sites that could span thousands of products. When online B2B communications are required, like export processes, tax data updates, or webhooks. Now let's see how to generate static sites! First, let's set up a site using the Blog recipe. Now head to the Configuration and enable the following OpenID modules: OpenID Authorization Server and OpenID Token Validation. We also need the GraphQL, so enable that module too. The goal is to implement the authentication from a service to the Orchard Core by using Bearer tokens and OpenID. With that, you can use the APIs from another service. After go to the Authorization server settings under OpenID Connect/Settings and allow the Client Credentials Flow. The OpenId Connect Client Credentials grant can be used for machine to machine authentication. In this grant a specific user is not authorized but rather the credentials are verified and a generic access_token is returned. Now create a new application under OpenID Connect/Management. This will be our service that will connect to the Orchard Core instance. Don't forget to allow the Client Credentials Flow here and of course, provide a Client Id and a Client Secret. We will need these soon. Now we have a configured Orchard Core instance to serve content to our application using GraphQL and the Client Credentials flow. For the sake of simplicity, we will create a Console Application. This application has to use the Client Credentials Grant Flow for authentication. curl -XPOST "https://<region>.onelogin.com/oidc/token" \-H "Authorization: Basic <base64 encoded client_id:client_secret>" \-H "Content-Type: application/x-www-form-urlencoded" \-d "grant_type=client_credentials" First, create a request on the /connect/token on the Orchard Core instance. Then create a Basic authentication header with the Client Id and the Client Secret. Remember you provided these data when setting up the OpenID application in Orchard Core. After we send the request and the response will be a JSON document with an access_token property. This property stores the value of the access token that we can use to send any request to the server as a Bearer token. Check this code snippet to receive this token. using (var httpClientHandler = new HttpClientHandler()){ httpClientHandler.ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator; httpClientHandler.AutomaticDecompression = System.Net.DecompressionMethods.GZip | System.Net.DecompressionMethods.Deflate; using (var httpClient = new HttpClient(httpClientHandler)) { string accessToken; using (var request = new HttpRequestMessage(HttpMethod.Post, new Uri("https://localhost:44300/connect/token"))) { request.Headers.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.UTF8.GetBytes("theclientid:theclientsecret"))); request.Content = new StringContent("grant_type=client_credentials"); request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/x-www-form-urlencoded"); using (var response = await httpClient.SendAsync(request)) { var data = await response.Content.ReadAsStringAsync(); var doc = JsonDocument.Parse(data); accessToken = doc.RootElement.GetProperty("access_token").GetString(); } } }} And the value of the doc JsonDocument will be the following, where you can see the access token. {"token_type":"Bearer","access_token":"CfDJ8IFF_p0sw0lLjSdTpd..........cDRRiQXfpVZsHo","expires_in":3600} In the next step, we are creating a new Bearer token with the access token and we are pointing to the GraphQL endpoint with a query listing all the blog posts. With that, we can get all the blog posts. using (var request = new HttpRequestMessage(HttpMethod.Get, new Uri("https://localhost:44300/api/graphql?query=query%20MyQuery%20%7B%20blogPost%20%7B%20displayText%20markdownBody%20%7B%20html%20%7D%20%7D%20%7D"))){ request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken); using (var response = await httpClient.SendAsync(request)) { var data = await response.Content.ReadAsStringAsync(); Console.WriteLine(data); }} You can see that we pass the GraphQL query in the query string in an URL encoded format. Here is the query in a readable way: MyQuery { blogPost { displayText markdownBody { html } }} We use Console.WriteLine to see the data coming from Orchard Core. Because we set up our site using the Blog recipe and haven't added any additional blog posts, our response will be the following: So, this is how you do Client Credentials Flow to authenticate your application against Orchard Core. This is the first step needed to generate a static site. Now let's just refactor our code a little bit. Create a ClientCredentialsAuthenticate method to get the access token. With the ClientCredendialsAuthenticate method, we can do as many calls as we want. You can see the BlogPosts query that we will pass to a custom Statiq module called GraphQLQuery. This module will just take the GraphQL endpoint, the query, and the access token. We will also need to develop another custom module extension using Statiq, called Liquid module to be able to use Liquid. const string BlogPosts = @" MyQuery { blogPost { displayText markdownBody { html } } }";static async Task Main(string[] args){ var token = await GraphQlQuery.ClientCredendialsAuthenticate(new Uri("https://localhost:44300/connect/token"), "theclientid", "theclientsecret"); await Bootstrapper .CreateDefault(args) .BuildPipeline("Posts", builder => builder .WithInputModules(new GraphQLQuery("https://localhost:5001/api/graphql", BlogPosts, token)) .WithProcessModules( new SetDestination(Config.FromDocument(doc => new FilePath(doc.GetString("displayText") + ".html"))), new Liquid("templates/blogpost.liquid")) .WithOutputWriteFiles() ) .RunAsync();} For every blog post, it will apply the transformation, by getting the displayText property of the JSON document and create an HTML file based on that. After apply the Liquid filter based on the blogpost.liquid template, that has the following content: <h1>test</h1><p>{{ displayText }}</p>{{ markdownBody.html | raw }} If you run that application you will get one HTML file in the bin/Debug/netcoreapp3.0/output folder of your application called Man must explore, and this is exploration at its greatest.html. If you open the file you will see the following result. With that, you can go further and generate all the static sites you want based on GraphQL and use Razor or Liquid. On Lombiq Orchard Dojo Newsletter Now we have 98 subscribers of the Lombiq's Orchard Dojo Newsletter! We have started this newsletter to inform the community around Orchard with the latest news about the platform. By subscribing to this newsletter, you will get an e-mail whenever a new post published to Orchard Dojo, including This week in Orchard of course. Do you know of other Orchard enthusiasts who you think would like to read our weekly articles? Tell them to subscribe here! If you are interested in more news around Orchard and the details of the topics above, don't forget to check out the recording of this week's Orchard meeting!

This week in Orchard - 10/11/2019

The Preview feature is improving, you can have admin templates and better defaults for the SearchController, and we are just scratching the surface of the new features that coming to Orchard Core. Let's check out those with some other fascinating features! On Orchard Core Validate stereotypes This prevents stereotypes from having non-alphanumeric values because these are used for file template names. Another issue was people assume that they can provide multiple stereotypes by passing a coma, but no, it's not a valid use case. Here's the fix in the UpdateAsync method of the ContentTypeSettingsDisplayDriver by adding the IsAlphaNumericOrEmpty private method. Fix attached media field add button visibility There was a couple of regressions with the media editor and media attached field editor: the delete button doesn't seem to work anymore (permanently disabled) in the media attached field editor, the add button doesn't reappear after deleting an image until you publish and re-edit the page You can see the fixes in the following gif. Adding shape_dump filter Do you remember the Shape Tracing feature in Orchard 1? It's like pressing the F12 button in a Chrome browser, but for shapes. You will see all the shapes that have been rendered and all the alternates and the source code for alternates. It makes easier to template shapes. The first step is towards this feature in Orchard Core is to use this filter to dump a shape. With this filter, you can export the JSON document of the shape. Let's say we have a site installed with the Blog recipe. Use the shape_dump filter in the Content-Article.liquid file by adding this line: {{ Model | shape_dump }}. After if you navigate to an article, you will see the following page with the rendered JSON document. This feature is under development, but you can check the current progress in this branch. Orchard Core Preview feature improvements The idea is to improve the Orchard Core Preview feature. Today when we do a preview it's using the ContentItemController, the one that renders the ContentShape. With that, you can have your own custom templates and it will render that. When you click on the Preview button, there is a new window that opens and this new window will call into a custom preview controller. This controller is in the OrchardCore.ContentPreview module, called PreviewController. What it does is when it's get called on a POST from the second window it gets the content item, which is inside the form post and tries to update the result of the POST, like it was a publish or a save action on the form. And in the end, we get a new content item as if we were about to save the content item form. And from this content item, we just call BuildDisplayAsync and render it using a view. And the Render.cshtml will just render the shape in the current layout of the frontend. The improvement would be to find a way to customize how to render the page in the preview window. This feature is working well when we are using the content shapes with the full CMS mode, but when we are in the decoupled mode to render anything it's not based on the content shape. It's based on the developer's own views and templates and controller actions. There will a new part, called PreviewPart, that contains nothing, but has settings. When you attach the PreviewPart to your content type, you will go to Settings and define the pattern to use to build the path. So, the developer makes their own view and then they can configure this content type to say that for the preview you should use my route that will display my content type. Then when we click on the Preview button, intercepting the Render to invoke the URL that will actually render the content item from the developers perspective instead of trying to render the content item using the content shape. In this case, we won't have any customization. In the end, we will have a working preview feature even in decoupled mode. If you are curious about the current state of this new feature, check out this branch. Demos Admin templates It's like templates, but for the admin. Let's see how it works! We have front end and admin themes. When you want to customize the admin theme, right now there is no other way than creating a new theme and having the theme as a base one and selecting your own admin theme in the dashboard. This feature is kinda same as the templates module and lets you create shape templates from the admin itself for the admin. This way most developers won't have to create a custom admin theme, because it's usually just to change a summary for a blog post or a detailed template for a specific widget to look different. Or maybe you would like to hide something like you want to hide the TitlePart editor in a way to make it different. Set up a site using the Blog recipe. To use this feature head to Configuration -> Features and enable the Admin templates feature. After you will see an Admin Templates option in the Configuration menu. Here click on the Add Template button to add a new admin template. Let's call this template Content_SummaryAdmin__BlogPost to override the summary admin shape of a BlogPost. Give it a likable content and hit save. Now navigate to the Blog option in the admin to see the list of the blog posts. Here you will see the new look of the one blog post that we have. This might also allow us to be able to create custom widgets to place on the landing page of the dashboard and many more. Better defaults for the SearchController The search feature is part of the Lucene module, that could not be the right way to do. Maybe we could have its own module, because there is a custom controller and it's doesn't care about what is indexing anything. By default when you have the Lucene module enabled you have a SearchController under the /search URL. It doesn't have any styling, because there is no customized search page for that in the TheBlogTheme. If you navigate to Configuration -> Settings -> Search you can select which index you want to able to search and the default search fields which are the fields in which we will look for the content you type. If you haven't provided the default search fields, you will get a BadRequest in the front end with a Couldn't execute search. The search index doesn't exist message and also a log entry. But what is Content.ContentItem.FullText? For example, let's check the content type definition of the Article. Here you can see a section called Full-text. Here you can say what should be used to look for the Articles. For instance, by default, we include the display text and the body parts. But you could say I also want to use some more data, like the values of the different fields. You can use Liquid here to provide the values. Future improvements could be to make a custom shape for the search results for the list and for each item. And of course, change the themes to support this page correctly. On Lombiq Orchard Dojo Newsletter Now we have 97 subscribers of the Lombiq's Orchard Dojo Newsletter! We have started this newsletter to inform the community around Orchard with the latest news about the platform. By subscribing to this newsletter, you will get an e-mail whenever a new post published to Orchard Dojo, including This week in Orchard of course. Do you know of other Orchard enthusiasts who you think would like to read our weekly articles? Tell them to subscribe here! If you are interested in more news around Orchard and the details of the topics above, don't forget to check out the recording of this week's Orchard meeting!