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

Featured tags

IIS
API
All tags >

Orchard Harvest 2024, log file path based on orchard_app_data environment variable - This week in Orchard (12/04/2024)

Add cache busting parameter to media thumbnails and links in Media Library, the log file path now based on the orchard_app_data environment variable, and the latest news about this year's Orchard Harvest conference! Check out our post for the details! Orchard Core updates Add cache busting parameter to media thumbnails and links in Media Library It's recommended to send long far-future client cache TTLs in HTTP response headers for static resources like images, documents, and CSS files, and this is what Orchard Core also does. However, in the Media Library admin, this causes an issue if you change files since thumbnails and View links will now load the old files. This is especially a problem with CDNs, since then it's not just your browser caching these files but the CDN too, which for an ordinary user is impossible to purge, and thus they won't see the updated files. The solution here is to make Media Library admin thumbnails and View links use the usual cache-busting parameter mechanism. Log file path based on orchard_app_data environment variable As described in the document here, setting the environment variable orchard_app_data doesn't change the log location, and logs are still placed under the App_Data folder. So, if you created an environment variable orchard_app_data with value C:\\orchard_data, and ran the application with the Default tenant, you noticed that the Sites folder created at C:\\orchard_data but logs are generated under App_Data. But because the orchard_app_data environment variable has a value C:\\orchard_data, logs should also be created under C:\\orchard_data. The goal of this change was to fix this behavior. News from the community Orchard Harvest 2024 We had the first online Orchard Harvest last year, and it was so great to see that we had 188 sign-ups for the conference! It was an excellent opportunity to share knowledge, talk about development plans and ideas, and foremost, meet the rest of the worldwide community. And of course, we recorded every session, which means they are available on YouTube! Click the link to rewatch all the inspiring talks and discussions! So, after last year, the Orchard Harvest Conference will be held again in 2024. Last year it was held online due to economic reasons. This year the organizing team has decided to finally organize the Orchard Harvest 2024 Conference in person. Each year, we try to attract as many people as possible, and a face-to-face event helps to build truly productive relationships. Last year, we started organizing the event in Las Vegas, so that's one of the reasons we're going to do it here again this year! Also, most of the active people in the community are either from the US or can reach the US. According to the questionnaire, most people wanted the event to take place in September. With the organizers, we agreed that a Thursday and Friday would be best, so it wouldn't take so many working days away from people. They could even stay for the weekend on an individual basis. Finally, we chose the 12th and 13th of September. It's not right after the summer holidays, people don't travel as much then. There are fewer things that could come up for potential participants that would prevent them from participating. Also important is that it does not interfere with any national holiday. We are currently working with the organizers on a contract with the venue. We are also thinking about what themes the event should be based on. Furthermore, we are trying to put together a set of goals that we will try to follow through. Do you have any ideas that you would like us to consider? Please tell us under this GitHub Discussion! There is a possibility of sponsoring the Orchard Harvest conference, and we are currently in the planning stage. We would be open to it if you would like to sponsor our event. If you are interested, you can contact us using [email protected] or the [email protected] email addresses, and you can also write under the mentioned GitHub Discussion page. If you would like to be kept informed about the events around the conference sign up here to receive our announcements about Orchard Harvest. As we move forward, we will keep community members informed of the details, and you will also find every detail in this newsletter too! Orchard Dojo Newsletter Lombiq's Orchard Dojo Newsletter has 471 subscribers! We have started this newsletter to inform the community around Orchard of the latest news about the platform. By subscribing to this newsletter, you will get an e-mail whenever a new post is published to Orchard Dojo, including This week in Orchard of course. Do you know of other Orchard enthusiasts who would like to read our weekly articles? Tell them to subscribe here! If you are interested in more news about Orchard and the details of the topics above, don't forget to check out the recording of this Orchard meeting!

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

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

Cache Failover and Shared options, YesSql updates - This week in Orchard (26/11/2021)

Huge YesSql updates, new cache failover and shared options, Media Library improvements, and a new site running on Orchard Core! Do you want to know more? Then don't forget to check out our current post! Orchard Core updates YesSql updates YesSql has updates for the following drivers: MySqlConnector 2.0, Npgsql 6.0, Microsoft.Data.Sqlite 6.0. The Npgsql 6.0 has breaking changes in terms of date and time serialization. The breaking change is in the way it handles time stamps and date-time storage and the type of column that it stores them into. The Microsoft.Data.Sqlite is on 6.0, which contains the SQLite Connection Pooling, so it's pooling SQLite connections now. If we check out the benchmarks for MVC, where Orchard is one of them, and it's running the About page on SQLite, and you can see that on both Windows and Linux it goes up from around 5000 requests per second to 16000 requests per second and also the latency went down. Removed beforeFolderAdded to stop multiple calls to fetch folders When you click OK on the new Media Folder name dialog, the first thing it does after creating the new folder emits beforeFolderAdded which loads the folder we are currently on. Then it emits the folderAdded, which selects the new folder (triggering a load of the new folder through the watcher). It appears that both requests are in flight at the same time, and we are seeing that occasionally the beforeFolderAdded request comes in last and then makes it appear as if the new folder has all the contents of the previously selected folder. bus.$on('addFolder', function (target, folder) { if (self.model == target) {bus.$emit('beforeFolderAdded', self.model); if (self.children !== null) { self.children.push(folder); } folder.parent = self.model; bus.$emit('folderAdded', folder); }}); So, when we create a folder, we fire the beforeFolderAdded then folderAdded both of which load contents of a folder, but there is no guarantee on the order these calls will resolve in. Occasionally, we are seeing the first call to the original folder come in second, and the new folder appears to be populated with images already. Cache Failover and Shared options Sometimes the Redis server is not available because there could be timeouts for example. What do you serve when Redis is down, and it's part of your system. Do you serve something or just wait and try again? You could say that if the cache fails then go to the database and return something from there. But at the same time, it can also be dangerous because you could expose yourself to put your site down. If you expect not to do a lot of database stuff because you have a caching layer, you can put your site down. The DefaultDynamicCacheService uses the IMemoryCache to at least prevent something if Redis is down. For example, cache the id of a requested document locally so that the memory cache is used during the FailoverRetryLatency, which is a configuration value that has a 30 seconds value by default. News from the community Dixin's Blog is running on Orchard Core If you navigate to https://weblogs.asp.net/dixin, you will find a blog that contains several interesting posts about .NET, Windows, and many more. The site is using Orchard Core, and as you may notice, it's very fast, no matter how much content it has on it. Lombiq Gulp Extensions with Stylelint Our Gulp Extensions project now also provides Sass SCSS linting with Stylelint! To use it in your Gulp JS SCSS build pipeline, just configure the corresponding SCSS targets Gulp task. Read more about how you can do that here! Orchard Dojo Newsletter Lombiq's Orchard Dojo Newsletter has 232 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!

GitHub Actions, Media Slugify - This week in Orchard (18/12/2020)

This time you could see two great demos in our post! One is about the GitHub Actions integration for Orchard Core and the other one is about a new addition for YesSql. But first, let's check out the latest improvements of Orchard Core, like the new Media Slugify feature or the Synchronization Latency Option! Orchard Core updates How to enable Razor templates in my theme? It's just a few additional lines to the Orchard Core documentation, but we thought we should mention this change because it's a very common mistake that developers would like to use Razor in their custom themes instead of Liquid but the Razor code in the cshtml files doesn't do anything. New feature to slugify media folders and files to make them SEO-friendly Let's set up your site using the Blog recipe then navigate to the admin UI of Orchard Core. Head to Configuration -> Features to find the new one, called Media Slugify, and enable it. The media slugify module slugifies new folders and files to make them SEO-friendly. Now navigate to Content -> Media Library and try to upload something to the Media Library. And let's say that the name of the file that you would like to upload is something like this is a Szép kép.jpg. You can see that the filename contains several spaces and some special chars too. If you upload this image, the feature will slugify the name of the image and the result will be this-is-a-szep-kep.jpg. And the same applies to the folder names too. Check out the following gif to see what will happen if you upload files and create a folder with special characters when the module is disabled or enabled. If you would like to read more about this new feature, this will be your page on the Orchard Core documentation. Using Docker with Orchard Core Orchard Core's source code repository includes a Dockerfile which will allow you to create your own Docker images and containers. It can be quite useful for Orchard Core developers when needing to test PR's. It allows them to deploy locally quickly in some testing environments. There is a new page in the Orchard Core documentation with examples that will be shown for that context. Docker can also be used for more complex usage (ex: production deployment) but this documentation doesn't aim to explain that in detail. For more advanced examples we strongly suggest reading docker and docker-compose documentation. Synchronization Latency Option This is about being able to set how long you are OK to wait before refreshing your document cache. Let's say you have multi-node and the document updates on one node. It will be in the Redis cache, but you don't check for the new values every request, we can just say this is the grace period for which I don't want to check the cache. Like I would only check it every second even if I have one million requests per second, one million times we will get the value from the cache, but the next one will say: OK, I need to get something to be refreshed from the Redis cache. It was set to one second by default. Check the GetInternalAsync method of the DocumentManager, where we get the SynchronizationLatency property of the DocumentOptions. You can set the values of the DocumentOption using app settings. Demos GitHub Actions GitHub Actions allows you to use service containers, so basically just loading a Docker image and exposing it as a service to your main container that runs your tests. This is basically the same as Docker Compose when you have multiple containers running concurrently. What's need is that by using the Orchard environment variables, be able to run the functional tests for each database type to make sure the CMS works on all of those. If you open up the GitHub repository of Orchard Core, you will find several yml files in the .github/workflows folder. The one you can see here is called functional_all_db.yml that runs the functional tests on all databases. The first job here will run the Cypress script called mvc:test on the latest version of Ubuntu. If you aren't familiar with Cypress and Cypress test, you could see a demo about that in this This week in Orchard post. And there are a lot more tests in the workflows folder, check them out if you are interested in running tests! To run the actions manually, we can go to the Actions tab of the GitHub repository of Orchard Core where you can see all the workflows defined in these yml files, like Release - CI, Functional Tests - all Databases, etc. Select the Functional Tests - all Databases one and then click one of the results to see the actual jobs. And you can see all the steps in the job with the time it needed to complete with detailed execution results. And there are a lot more to see and speak about here. If you would like to know more, you should definitely check out this recording on YouTube! YesSql: Fixing subclass support Let's navigate to the GitHub repository of YesSql and open the CoreTests.cs file in the test/YesSql.Test folder and find the ShouldQuerySubClasses unit test. Here you can see a Circle and a Square class, these are both inherit from Shape. After we are creating some new instances of the Circle and Shape we do some queries and say give me the Squares and Circles. The new thing is in this line: Assert.Equal(3, await session.Query<Shape, ShapeIndex>(filterType: false).CountAsync()); Here we say list all the Shape types. And there will be three of them: two Squares and one Circle. So, now you can query by the base type to get inheritance inside that and it was not working before. And in this case, the index is just to store the name of the type that you are storing, just to be sure that it's the correct type. If you would like to see the recording of this new feature, head to YouTube now! News from the community Our full Orchard Core tutorial series, the Dojo Course 3 is here! After a long wait, the new Orchard Core version of our legendary Dojo Course tutorial series is here, the Dojo Course 3! Are you a newcomer and want to learn Orchard Core from the ground up, both from a user's and a developer's perspective? Are you somewhat familiar with Orchard Core but would like to get up to speed and become an Orchard pro? Look no further, check out Dojo Course 3! Dojo Course 3 guides you from the very basics of Orchard Core all up to be able to write your own themes and modules, utilizing various APIs of Orchard. We're publishing a tutorial video every day for 40 days starting on 1 December. So, this is your 40 days of Orchard :). And now we have published every video that is about the admin UI features of Orchard Core. From video 19., we will check the structural overview of the Orchard Core source, and then we will start coding! If you are really interested in the coding part, the upcoming 20 videos are specially for you. If you're looking for our previous Orchard 1.x tutorial series check out Dojo Course 2. A new website using Orchard Core: Cornish Mining World Heritage Explore what World Heritage Site status is and why the Cornwall and west Devon mining landscapes have this globally important designation. Check out this site to see the loads of capabilities that you can achieve using the CMS. 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. Orchard Dojo Newsletter Lombiq's Orchard Dojo Newsletter has 176 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!

Distributed cache, Media crop picker - This week in Orchard (08/11/2020)

This week we will see the new IDocumentStore, which is a cacheable, committable, and cancellable document store allowing to get documents from a shared cache. And don't forget to watch a demo about how you can add an alt text and crop the images of your Media Field! Orchard Core updates Make features actions sticky while scrolling If you navigate to the admin UI of Orchard Core and head to Configuration -> Features, you will see all of the currently available features of Orchard Core. This list is now getting longer and longer, so the idea here is to use a sticky bar on scrolling for very long pages instead of the scroll to top button. The first page that gets this sticky bar is the Features page, which looks like the following now. Edit button for lists in DetailAdmin view This is a feature that was already there in Orchard 1. When you want to edit something in the admin, you can return a route to the controller that will edit an entity. Or that will display it as a list or display it as a detailed object in the admin. And when you have a list, you have two options. Either you want to show all the content of this list or you want to actually edit the list itself. And to do that, when you see a blog and you click the link of the blog in the content items, it will go to the list of blog posts. This is the DetailAdmin view. And if you actually want to edit the blog you need to click on the edit button. This feature is about adding a new button for the list and you are now not confused about clicking the link or click in the properties button. Move feeds to feature There is a new feature now in Orchard Core called Feeds. Don't forget to enable that module if you would like to have feeds capabilities on your site! Generate xml documentation (comments) for nuget packages Whatever documentation we put on the files, they were not available, because if you don't put the GenerateDocumentationFile tag then it's not generated in the XML file that contains all the documentation, it's not embedded into NuGet, and Visual Studio won't load it. You need that to export your API docs. Not even to generate documentation, just to be able to have it in the NuGet package for the IntelliSense. If you don't do the NoWarn, every public member that doesn't have an API doc would fail the build. The <NoWarn>$(NoWarn);CS1591</NoWarn> removes the warning that some public members do not have comments. Now you will have more documentation when they use the NuGet packages to build sites! Distributed cache Whenever you want some cacheable document that is stored in the storage using YesSq for instance you need to inject the IDocumentStore interface. This will use YesSql to load the document and it will be able to cache it. So, for instance, if you would like to get the site settings you can use the IDocumentStore to do that because it's stored as a document and you want to cache it. And then when you load the site settings using IDocumentStore by passing the type, you can say GetOrCreateImmutableAsync or GetOrCreateMutableAsync. Mutable meaning that when you load the site settings just to read it, you want to say I want an immutable object. And when you want to load the site settings to update it, then use the GetOrCreateMutableAsync method. The difference is in the way that it will either cache it or not and also would it take it from the cache or not, or put it back in the cache or not. Or invalidate the entry in the cache. And there is the IFileDocumentStore which has the same methods as the IDocumentStore, but it's a totally different service. This one can be used to store a document on the file system that can be also cached. But it's a different store. We use the IFileDocumentStore to store the content type definitions. Demos Media crop picker and Alt text editor Set up your site using the Blog recipe. That recipe comes with the Blog Post content type that has the Banner Image Media Field by default. Let's check out the predefined blog post content item to see the new features of the Media Field. If you select the post-bg.jpg image and click on the button with the speech bubble icon, you can set the alt text for the image. Another new button is doing a more interesting thing. If you click on the button with the target cross icon, another new modal window will open where you can select the anchor for the selected image. Using the target cross, you can easily specify the crop point of the image. If you open the preview in another window you can easily see the changes of the image in real-time. But how you can enable/disable these options? Navigate to Content -> Content Definition -> Content Types and hit Edit near the Blog Post and edit the Banner Image settings. Here you will find two new options. One is about allowing alt text and one is to allow the center cropping. These are on by default, that's why you could see the mentioned buttons when you edit the media field. And that's not all! If you would like to know more about this feature don't forget to check out this recording on YouTube! News from the community Orchard Dojo Newsletter Lombiq's Orchard Dojo Newsletter has 172 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!

Export contents as setup recipe, Shape Debug Mode to dynamic cache - This week in Orchard (24/07/2020)

Export contents as setup recipe and import recipe from JSON are about to make it easier to manipulate data and setup your Orchard Core site. Edit cached shapes using the Shape Debug mode to see your changes right away. We think if you are an Orchard Core developer, you will find these features very useful. These are the bigger topics for this week! Orchard Core updates Export Contents As Setup recipe This is a new feature that allows you to use a checkbox when you want to export some content and remove any information that would reuse properties like the content item ID, author, owner. Let's see an example for this and create a deployment plant that contains only that All content deployment step and see the JSON schema of the Blog content item that you can get if you install your site using the Blog recipe. So, if you leave this checkbox unchecked, you will see the following content. Nothing special here, you see the same content as you saw before. The content item has an ID, a version ID, and the dates when this content item was published and modified. But let's see what will happen if we put a tick in that checkbox! In this case, all the IDs are regenerated (for now it's not the case for the contained content items) and the values for the owner and the author are coming from the AdminUsername parameter. But be aware of the note that you can read under the checkbox: If checked, you will have to manually declare variables for the Content Picker fields, Taxonomy fields, Tags fields, and List item ids and replace them where needed in the recipe. Any reference to these content items will be lost. And the logic in the ContentDeploymentSource is about checking the value of the ExportAsSetupRecipe boolean property. If you want to export contents as a setup recipe, then the related properties of the objectData will be changed as you can see in the recipe file. We have to mention one new thing here. If you add the All features deployment step to your plan that exports the state of all features, you can say to ignore the disabled features. In that case, your recipe will only contain the enabled features and not the disabled ones. Import Recipe from JSON If you navigate to Configuration -> Import/Export in the admin UI, you will see a new option called JSON Import. This new feature will let you type some JSON and then run it, so you can execute some custom recipe steps from this UI. This new edition comes with the Deployment feature and it's using permission which is the Import permission. Let's say you want to change the site theme of your site for the default one. To do that you can use the following JSON. You can see you can do it in the same way as you would do it in a recipe file. Fix modules referencing other modules You may notice how many modules are referencing other modules for no need. Mostly this is just because they are doing so to get transitive references. The solution was to take direct references on the required abstractions/core projects instead of transitively depending on other modules to provide those references. Dean Marcussen also reviewed other references, removed superfluous references, and ordered them all. Migrate the OpenID module to OpenIddict 3.0 OpenIddict 3.0 has matured enough to envision using it in Orchard Core 1.0 RTM for both the server and validation features. As part of this migration, a few properties will be added to OpenIdServerSettings and OpenIdValidationSettings and others will be renamed for clarity. Due to this change, existing deployments will have to be updated to use the revamped settings. No exception should be thrown and the migration should be limited to re-configuring the server/validation options using the UI and/or updating custom recipes to use the new names. An important aspect of this migration is that the validation feature will now internally use the OpenIddict validation handler instead of the Microsoft JWT bearer handler, even with external OAuth 2.0 authorization servers. Unlike the MSFT JWT handler, the OpenIddict validation handler uses the new Microsoft.IdentityModel.JsonWebTokens stack and comes with JWT token type validation enforced by default, which is required by the not-yet-standardized JWT access token specification. This change will break existing deployments targeting OAuth 2.0 authorization servers that don't issue "typ": "at+jwt" access tokens. At least the following implementations are known to be impacted: Azure AD/B2C. IdentityServer3.IdentityServer4, except its latest 4.0 version (unless 4.0 is configured to use a different typ header) OpenIddict-based deployments are not impacted, as the validation handler includes special logic to deal with the tokens produced by OpenIddict 1.0 and 2.0, whose JWT tokens always include a special token_usage claim to prevent token substitution attacks, which has the same purpose as the "typ": "at+jwt" header. To ensure the validation feature can still be used with servers that don't issue "typ": "at+jwt" access tokens, an opt-in option was added to the validation configuration UI. This option can only be enabled when configuring a remote OAuth 2.0 server and is not shown when using a local OpenID server or a server located in another tenant, as OpenIddict 3.0 always issue "typ": "at+jwt" access tokens. Demos Shape Debug Mode to Dynamic Cache If you have a lot of menu shapes in your site and if you want to edit the templates you can't do that easily because the items are cached. The solution here is to provide an easy way to disable the cache, so in that case, the menus will not be cached. To set the cache mode, head to Configuration -> Settings -> General, where you will find a new tab called Cache. The settings here are very similar to the resource settings, the default is that the cache would be enabled in production and disabled otherwise. You can say I want to enable or disable it all the time. And there is a very useful option called Enabled with cache debug mode. Let's select this one and see what will happen! Now navigate to the homepage of your site and view the page source. Everywhere where is a cached block you will get a little piece of information about the given block. It shows you the cache ID, the dependencies that it's using, how long it's cached for, and any of the variations that are present. You will also see where is the end of the block. Let's see how it works! You will find a CacheStatement class that is about to check the value of the cacheOptions.DebugMode and if it's true, then it will add the additional content to the source of the page. If you are interested in more details about the cache settings, head to YouTube, and see the recording of the demo! News from the community Orchard Core workshops The contributors of Orchard Core will hold some unique online workshops in September 2020. So even with Orchard Harvest postponed due to the coronavirus pandemic we'll get some new learning events. Are you looking to get up to speed with Orchard? Check out the workshops' details on the Orchard Core homepage! Orchard Dojo Newsletter Now we have 154 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!

Sortable lists, IScopedDistributedCache - This week in Orchard (17/01/2020)

Get ready for a deep dive! In our post, we will introduce the IScopedDitributedCache service and show how to use it in the RoleStore. And we are going to solve the mystery about do you need the Model prefix to access different kinds of properties of a model in Liquid and in Razor too? Orchard Core updates Document recipes new Lucene settings There is new documentation on the updated Lucene index settings. Now to create an index from a recipe, it's not just about passing the name of the analyzer. You have to provide the following: AnalyzerName: the name of the analyzer, that you want to use. IndexLatest: a boolean value that indicates that if you want to index the latest or just the published versions. IndexedContentTypes: the list of types you want to index. Re-use in some places the ContentItem Liquid property There was a change in the Liquid TemplateContext, that broke some properties, that are available in the templates. If your AliasPart, AutoroutePart or Workflows patterns don't work anymore, it's because of the previous change. Now, this issue has been fixed. For example in an Autoroute pattern that used to render the custom URL of the content type you could do something like: {{ ContentItem.DisplayText | slugify }} That will generate a nice text for your routes. But in some cases, you have to write {{ Model.ContentItem.DisplayText | slugify }}. Maybe using the Model prefix is collateral damage, but maybe it has a purpose. Anytime we have a Liquid template for a shape we do Model.ContentItem to get the ContentItem. In Razor everything is Model.Something. It has to be because in Razor we are doing C# and the current context is the page and the page is a class that doesn't have our properties like @ContentItem. So the only thing we could get is the @Model that is typed to the generic type of the RazorPage and Model will provide all the properties like the ContentItem. Because we do too much Razor, it could be possible that we reused this approach into some Liquid patterns. In Liquid it's not necessary to have the Model prefix. But it appears that there is already a way in Fluid to use a first-level model without a custom prefix (so we don't need a Model prefix), by setting the TemplateContext.Model property. In conclusion: in Liquid that is easier to write {{ ContentItem.DisplayText }}, you don't need the Model prefix. But in Razor, you have to use the Model prefix. Constraint admin controllers to mapped routes Since we can change the prefix of the admin route, we have to ensure that every admin controller's actions have the correct prefix to use. There is an implementation of the IActionConstraint, called AdminActionConstraint, that checks if we are in the admin and the route doesn't start with the admin URL prefix (_adminUrlPrefix), then it will create a warning log entry. So, the AdminActionConstraint applies a convention that restraints all AdminControllers or [Admin] controllers to use the mapped route only, and not the default route applied by MVC. Fix the recipes not found bug in the documentation We have a guide about how to create a new decoupled CMS Website using Orchard Core. It told you to add the OrchardCore.Application.Cms.Core.Targets NuGet package to your new ASP.NET Core project, because this package won't contain the themes. And when you do a decoupled CMS site you will don't need the themes, because you want to create your own front end. The issue is with this package on the master branch is that the setup doesn't contain any recipe in the RC1 version. The community fixed that bug for now, but it's just in the dev branch yet. So, if you follow the guide and you using the RC1 version of that package, when you arrive at the setup screen you will not be able to set up the site because there will be no recipe to choose from. Mitigation is to use the OrchardCore.Application.Cms.Targets package, that contains all the themes and recipes. Of course, in this case, you will get several unwanted themes, but you will not be blocked to continue following the guide. So, it's not the perfect solution, but when there will be a new version of Orchard Core, we can rewrite this back to use the OrchardCore.Application.Cms.Core.Targets NuGet. There is also a hint about if you are using the nightly builds of Orchard Core then you should use the Core package instead. Creating IScopedDitributedCache The main goal is to increase the performance of Orchard Core and try to make it faster from time to time. To measure that, check the blog posts Liquid template page and start to remove everything from there. Just to see how fast could be the performance if we didn't render anything. Then start to remove stuff from the controller that displays content. For example, let's take a look at the ItemController. This is the controller, that renders content items by default. Take a closer look at the Display method of this controller! It first loads the content item. If it's not there, we return a 404. Then we check the ViewContent permission for this content item for the current user. We return Forbid if they authenticated but don't have the proper permission, or return Challange if the user is anonymous. Now let's build the display! That will build a shape containing all the part shapes and everything for this content item. So, it will render the display of this content item and we send this shape to a view that will just call Display of the shape. That's what we do in this method. The thing that made it slow actually is that one which checks the permissions, the _authorizationService.AuthorizeAsync. The user is anonymous and checking that the anonymous users could see something was the bottleneck of the performance. For each display of the site, there would be a database query just to authorize the anonymous user to be able to see something. This is actually a regression. Once you remove this code the controller will be much faster. An authenticated user would have added Claims cached in the User object. But in the case of an anonymous user, nothing was cached. Each request for an anonymous user would ask the permission for the anonymous user from the RoleStore. The RoleStore would do a query all the time. There is a new service, called ScopedDistributedCache. The idea is to use a distributed cache, such that we would store the Roles document in memory if we have a single node or in a store that is shared across every node if you have multiple nodes. Scoped means if you do multiple queries on the same cache entry for the same request, then we will load it from the DistributedCache only once. That will be much faster if you have multiple queries. You can see the usage of the ScopedDistributedCache in the RoleStore. Instead of injecting the IMemoryCache (that puts everything in the memory that shared by all the request) here comes the IScopedDitributedCache. The code is much simpler with that: you just pass it an object. Check the GetRolesAsync and the UpdateRolesAsync methods of the RoleStore. Demos Make lists sortable with ordering setting Let's say you have a site that you set up using the Blog recipe. In that recipe you can find a Blog content type, that is used as a container of the Blog Post content items. To behave the Blog content type this way, you need to add the ListPart to it, which will add the list behavior. Here you could see a new option before the Contained Content Types list, called Enable Ordering. If you check this option you will enable the manual ordering of the items. Let's put a tick here! Now head to the Content -> Content Items page and select the one named Blog (or just simply hit Blog from the menu). Here you can see the list of the blog posts contained in this blog content item. Let's add more posts to it to see the power of this new feature! By using a simple drag and drop, you can set the order of the different items and save it on the fly. Check out the following GIF to see how the reordering works! This feature is under development, but you can find the code in this pull request. And don't forget to watch the recording about this demo, where you can also hear an informative discussion about some interesting questions to solve, for example, what about reordering content items that have a published and a draft version too? News from the community New Orchard Core site: Buzz Interactive Buzz believes that great digital products are built on intelligent strategy and outstanding technical abilities. They partner with vibrant clients and help them create future-proof platforms for web, app, and VR. And they use Orchard Core for their site! 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. Tell us about your .NET performance challenges! - Hastlayer developer survey Help us build the nerdiest .NET thing, Hastlayer: It turns performance-critical sections of .NET programs into computer chips! If you fill out our short questionnaire you can win a cool compute accelerator board worth $265! Check it out here: https://forms.office.com/Pages/ResponsePage.aspx?id=Wt6elek45kStyIVVO-uCIMkFNjqW2E1Pm4v3YMcflMNUOVlDNUE3MlpDS044VDI1OEFSMUgxUkxSTC4u The reason we're asking this is that we're building a .NET hardware accelerator, Hastlayer (https://github.com/Lombiq/Hastlayer-SDK it turns your program into a chip!) and want to better understand what other developers do. Thank you in advance! Orchard Dojo Newsletter Now we have 113 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!

Performance-tuning modules you should know about

These modules are really useful if you want to squeeze out the performance of your Orchard website: Mini Profiler for profiling Orchard.Caching for a wide variety of caching solutions Cache for output caching (included in Orchard as of Orchard 1.7) Combinator for bundling and minifying static resources (stylesheets, scripts)