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

Copilot Integration, Last call: Speaker application for Orchard Harvest 2026 - This week in Orchard (01/05/2026)

This week, Mike Alhayek shows how to use Copilot directly inside Orchard Core!

But before that, check out some code where you can see that, starting now, Orchard supports static data migration methods, and suppressions are no longer required for migration steps that don't use instance state.

Welcome the first contribution from Jack Liu, who made the pagination of the List Part configurable to decide whether to show a full pager with page numbers or just the arrows to navigate to the previous and next pages.

Do you know that since 2013, we've been working with Óbuda University in a hands-on way to teach web development? If you are interested in our Orchard Core courses at the university, check out our post on our site!

As we mentioned, we started publishing last year's Harvest recordings to YouTube. Check them out for some inspiration, and don't forget to apply to be a speaker for this year's Harvest by the 5th of May, midnight, anywhere on Earth!

Ready to explore? Let's dive in!

Latest tutorials

Featured tags

AI
IIS
MCP
API
SMS
SEO
All tags >

Step away from that Node.js

When you develop a full-stack web app, Node.js just seems like a fact of life. Inescapable, even if you use .NET for everything, and comes with its own whole infrastructure even though you just want to manage a few front-end libraries for your app. It doesn’t have to be like that.

How we reduced our app's server-side latency in Azure by 98% while lowering cost by 28%

Sounds like clickbait, right? Fair enough, here's the TL;DR: We moved our Azure Web App from the Windows S1 plan to the new Linux P0v4 plan. Read on for the details!How we used to run our Orchard Core apps in AzureThose Orchard Core web apps of ours that aren't too resource-hungry (like the app running Orchard Dojo) we've been running on the Windows S1 plan of App Services. This now legacy plan provides 1 vCPU, 1,75 GB of RAM, and HDD local storage for a cost of USD 73/month. Not a lot of processing power, but it was enough if your requirements weren't high either. And it, as you may have guessed it, runs on a Windows server.We've done measurements before, and the Linux pair of this App Service plan performed worse. The newer Premium tiers, with newer hardware and SSD storage performed better, but were too expensive for our use-cases and the added performance wasn't necessary. However, two things happened since then: The S1 tier of App Services became deprecated, and a new, v4 Premium tier was rolled out. What's more, the lowest plan of Premium v4, P0v4, is actually cheaper at USD 53,3/month! This is a 28% cost reduction right off the bat, and it promised better performance, too, so we had to try it out. And this was a great success!Windows S1 App Services — the baselineThe test subject was our Lombiq Tenants Core app. This runs most of our own websites, including Orchard Dojo, dotnest.com (but not the sites created on DotNest), and our company website. This is how its performance looked under the Windows S1 plan: Not great, but not terr... No, at face value, it's actually quite terrible, with the 99th percentile being at 18 seconds for generating a server-side response. However, digging into the details revealed that the vast majority of requests that users cared about (e.g. excluding error pages that spambots hit) performed on an acceptable level, within 1-200 ms. Now, this is indeed not great, but not terrible either. Still, the average response time for all requests, even if this includes ones that no real person was seeing and one-off outliers, was 3,7 s. Can we fix this?The charts in this post are from Azure Application Insights, BTW, Azure's app monitoring service. We use it enhanced by our open-source Lombiq Hosting - Azure Application Insights for Orchard Core module, check it out!Linux wasn't always betterAn ASP.NET Core web app, especially in its source form but even when compiled to binaries, consists of a lot of small files, and it constantly works with a lot of small files too (like stylesheets, images). You'd expect that this is a clear case where Linux (with its usually used ext4 file system) has an advantage over Windows (with NTFS). Linux also generally has a lower resource footprint in itself, leaving more for the web app. So, it should just be faster, right? Nope!At least, it wasn't faster at the time when we compared the Windows and Linux S1 tiers. The average server-side latency was about 68% worse under Linux, although for a lower price. The tiny savings weren't worth the worse UX.But then the P0v4 App Service plan came.Migrating to Linux P0v4 App Services and reducing latency by 98%The new P0v4 App Service plan, which came out of preview and entered general availability in September 2025, offers still 1 vCPU but 4 GB RAM, and SSD storage. It also contains the latest hardware all around. So, we checked out how it performs in real life.Moving from a Windows to Linux App Service Plan is a manual process: You have to create a new App Service, configure every service connection and automation to use it instead of the old one, and deploy your app to it anew. It's a chore, but you have to do it only once. And this is your reward: As you can see, 50th percentile was reduced to only 39 ms from 226, and the 99th percentile from 17,8 s to 738 ms. The average response time on the Windows S1 App Service was 3,7 s, while on the Linux P0v4 one 77,5 ms. Let me write it out in a more obvious way: 3700 ms vs 77,5. That's a 98% reduction in latency! Which is absolutely awesome. There must be multiple generations between the CPUs and RAM of the S1 and P0v4 tiers, and I guess having an SSD and newer everything else helps too. More RAM surely does as well, although that was always enough before too.ConclusionMy recommendation would be to keep an eye on the offering that Azure, or your hosting provider, has, because the cost of compute is constantly coming down while performance is going up. With clever and not always ethical tricks, providers try to keep you paying ever increasingly more. However, the reality of hardware advances should eventually be reflected in your monthly bill and your app's performance metrics — you might need to work for it, though.Do you also want better performance for your Orchard Core or any ASP.NET Core app? Contact us and we can take a look!

Hosting Orchard Core at UpCloud

It's not all about hyperscalers: You can run your Orchard Core app in the cloud even if not using Azure, AWS, or some other giant like these. Let's see how we can do this with UpCloud!Blog post series overviewThis post is part of our series about hosting Orchard Core at European cloud providers. Orchard Core has built-in support for a lot of Azure services, including Media storage, secret storage, e-mail delivery and sending SMS, AI search, and even observability with Azure Application Insights with the Lombiq module. AWS also has support for Media storage. For cloud-hosted full-text search we can use Elasticsearch, and Redis to aid with horizontal scaling. How does using a smaller cloud provider, without specific support from Orchard Core, compare?We've looked into hosting a vanilla Orchard Core app as a proof of concept, and are sharing our experiences here. The goal was to run Orchard Core with a minimal hosting environment, but with a stateless web server (so, keeping the database and Media storage separate). This could've been simplified to only use a web server (and keep the database in a local SQLite file, as well as use local Media files), but we wanted to go a bit more realistic than that. To be able to play around with the web server from the GUI too, we've chosen Windows as the OS if available. Additionally, we also checked if the platform helps with any of the other common infrastructure requirements, like sending e-mails or observability.Note that while we usually received some credits from the cloud providers for testing, they are not paying for these reviews, and any endorsement or critique is our own.What's UpCloud?Not much, how about you? Hahaha... OK, to get back on track, UpCloud is a Finnish cloud provider with several hosting locations in Europe, as well as Australia, Singapore, and the USA. They don't have their own datacenters but use local datacenter operators.As far as services interesting for Orchard Core hosting go, they offer VMs with load balancing, AWS S3-compatible object storage, and databases as a service. Managed Kubernetes is also available, but for the sake of this post, trying to host a simple app, we won't create a cluster. Instead of Redis, you can create Valkey instances (Valkey is an open-source fork of Redis), which, for now, should just work with Orchard Core's Redis support. While OpenSearch is also available, that's incompatible with Orchard's Elasticsearch integration.If you want to send e-mails, implement observability, or add search and indexing other than with Lucene on the web server, you're on your own.Creating an Orchard Core hosting environmentYou surely already guessed, but we'll need three UpCloud services:A server, i.e. a VM.A managed database; we'll use PostgreSQL.Object Storage for Media.Let's start with the server! First, I wanted to create it in the Finland location, because there's no place like home, but at the time there was no Object Storage capacity available (there is since then). Due to putting all three resources into the same datacenter is kind of important for low latency, I went with the German location instead, and opted with a 1-CPU plan with 2 GB of RAM:The server took a few minutes to get provisioned, so in the meantime, I created an Object Storage instance (public connection is only enabled for any necessary troubleshooting later):And a single-node Postgres database server:Note that this runs on its own VM.This is everything we need, so now we can continue with setting up Orchard Core in this environment.Deploying Orchard Core to the web serverYou can deploy an ASP.NET Core app, including an Orchard Core-using one, with Web Deploy to IIS, using automated deployment from a GitHub Actions workflow, or just by copying its publish outputs to the server. Here, I opted with the simplest option: I published the web app to a folder from Visual Studio (but running dotnet publish from the CLI would be equally suitable), and copied the resulting files to the server via Remote Desktop. Then I could simply run the web app:The app listens to port 80 because I added an appsettings.Production.json file configuring it: { "Kestrel": { "Endpoints": { "HttpEndpoint": { "Url": "http://*:80" } } } }This allows you to simply open the IP of the server in a browser, or point a DNS A record to it. Our site is now available on the internet! ...after we allowed the exe of our web app through the Windows Firewall, that is.You may notice that this is a really barebones approach: There's no IIS, no HTTPS, no proper deployment. And you're right! This is a focused example of getting Orchard Core running, but we'll return to the missing pieces later.Setting up Orchard CoreRunning the Orchard Core setup is standard: Just fill out the usual settings on the setup screen, and point the app to the Postgres DB. For the latter, you can copy the Postgres connection string from the UpCloud Control Panel, and ask your favorite AI tool to turn it into an Npgsql connection string that .NET uses.Once setup finishes, you can configure Media storage too. First, you'll need to create a storage user for the app; I suggest attaching the ECSS3FullAccess policy, since that's the only one that seems to allow read-write access. Also, be sure to create a bucket for Media files; I named it just "media".Now it's time to configure the connection for the app. Again, you can use the appsettings.Production.json file to add something like below, resulting in the following full file: { "Kestrel": { "Endpoints": { "HttpEndpoint": { "Url": "http://*:80" } } }, "OrchardCore": { "OrchardCore_Media_AmazonS3": { "ServiceURL": "https://vrbd8.upcloudobjects.com", "Credentials": { "SecretKey": "add the secret of the user you created", "AccessKey": "add the access key of the user you created" }, "CreateBucket": true, "RemoveBucket": true, "BucketName": "media" } } }Be sure to change the ServiceURL value to that of your instance, as indicated on its Overview page (under "S3 endpoint"). That's actually an undocumented configuration key that comes very handy when, as we do here, you connect to an S3 account outside of AWS.Now restart the app (so it reads the updated configuration file) and enable the Amazon Media Storage feature from the Orchard Core admin. It'll work, despite it not running in Amazon. Magic!And with this, our app fully works!Why would you (not) use UpCloud?OK, so we've seen that running Orchard Core under UpCloud works. This is not a huge surprise, but it's nice to get it verified and have the basics figured out. Why would we do this, though, instead of choosing the beaten path with Azure or AWS, for example?European: UpCloud is not just hosting in Europe, and specifically, the EU, but the company itself is also based in an EU country, under strict EU privacy regulations. If that matters for you, either for sentimental reasons or as a matter of company policy (like using a provider that's not under the US CLOUD Act), it can be a big plus.Costs: UpCloud can be a lot cheaper. At €23/month, the UpCloud server provides roughly the same as an A1_v2 Azure VM, which costs €45/month. However, the managed Postgres instance at €30/month and the storage at €5/month (in total €58/month) are way above what we'd use on Azure for an entry-level app, where an S0 Azure SQL DB would be around €13/month, and storage only cents (depending on usage), altogether about €58/month too. We do get more with UpCloud (a dedicated VM for the DB and 250 GB of storage, and I think the VM is faster too), a lot more room to grow, but the cost advantage, in itself, disappears, at least in the beginning. All this being said, at Azure, we'd rather use App Services: This is a higher-level "websites as a service", offering a bunch of convenience features like automated deployment, staged publishing, and configuration management. The smallest proper App Services-based infrastructure (with a staging slot and separate staging and production DBs) comes at around €90/month, though, but that also contains a lot of features lacking from VMs.Simplicity: Without consulting any resource, just by playing with the Control Panel, I could fully understand the UpCloud offering (I think...) within like half an hour. Getting the full Orchard Core environment running wouldn't have been much more, have I not written this post at the same time.You matter and can talk to actual people: I had some question about setting up the storage, so I opened the chat window and had a real person from UpCloud answer within less than 5 minutes. The larger the cloud company, the larger of a client you have to be to matter to them; that translates to support request forms with dozens of fields, days to wait for a solution, and even having to subscribe to a paid support plan. As an SME it's much easier to work with a provider that's also an SME, instead of a huge multinational enterprise.Coming from frequently using the cushy but extremely complex ecosystem of Azure, using a more basic provider like UpCloud is certainly an interesting change. It seems to me that ultimately, there's a lot of work to do if you want to have a full-blown, highly automated hosting environment for Orchard Core, with an option for horizontal scaling. Below are the features that I'd consider necessary, and while these are given with Azure, you need to roll your own solutions with UpCloud:Staged publishing (blue-green deployment): You'd need to set up multiple VMs or multiple sites, and manage swapping staging with production somehow on your own.Automated deployments: I think under a Windows server, the easiest would be to set up Web Deploy and use it from an automation platform like GitHub Actions.Observability: You'd either need to host an observability platform yourself, or use an external service.The lack of a search/indexing service is less of an issue, because you can just use the Elastic Cloud (what's the option in Azure and AWS too), and I'd consider the lack of an e-mail service not a huge issue either (you can just use something like SendGrid). Managed Valkey is good, but starting at €50/month, it's not priced for an easy entry (just as Postgres), although it also provides a lot more resources than the lowest tiers of Azure Cache for Redis do (for a lower price).Yes, you could build an all-in-one infrastructure with Kubernetes, and have containers with services for all the above features (and a DB and storage as well), but that's a large complexity you need to manage. Using Terraform, supported by UpCloud, to ramp up your infrastructure can cut down on manual repetition (and aid portability to other providers to an extent), but is also work that you have to invest. And at the entry level, managed solutions for services like SQL and Redis (instead of hosting your own VMs/containers) can be more cost-efficient too (but that flips if your app's demand increases).So, what should I do?To me, the points mentioned above seem to be areas to improve. However, I can understand if the UpCloud team wants to focus on the core offering instead of becoming an everything cloud. Perhaps having a marketplace that easily lets you integrate external services to plug the holes would then be a good idea?Until then, UpCloud can be a good choice to host your Orchard Core app if you don't need anything beyond what's easily possible with the existing offering, or if you already invested into a portable Kubernetes-based infrastructure.And if you need help hosting Orchard Core at UpCloud, Azure, or onboard of a satellite (not kidding), drop us a line!An adjusted version of this post was also published on the UpCloud website as a tutorial.

How to add media management to an ASP.NET Core app? - Orchard Core Nuggets

Using media files, such as images, videos, and documents (like PDF files), is a common requirement for a modern website. Media can enhance user experience by making content more engaging, visually appealing, and/or easier to understand. Fortunately, Orchard Core has a built-in solution: the Orchard Core Media feature. As the description says in the official documentation:The Media module provides a UI to upload and organize binary files that can be used while creating content.Are you new to Orchard Core? It's a great open-source framework, and CMS built on ASP.NET Core. Check out the official getting started docs.Let's see Orchard Dojo and its blog for a real-life example of why you would use the media feature. At Orchard Dojo, we mainly use images for two things:Image of trainers: As you can see on the About page.Images for blog posts: For example, in this blog post.We have flexibility, and we can organize the media files using the media feature.Flexibility: Let's say a trainer got a new haircut and wants to update their image. Then, we can overwrite the old image with the same name in the media library, and that's it.Organization: We can have a “Trainers” media folder with the trainers' images, a “Blog Posts” folder with the images for blog posts broken down to years, and a folder for each individual blog post's images.Now, to turn on the feature, go to Configuration → Features and make sure the Media feature is enabled. You can additionally enable these media features: Media Cache: The feature caches remote media files locally, improving performance and reducing bandwidth usage for sites using external storage like Azure Blob or S3. For example, an online store with product images hosted on cloud storage can deliver images faster to users.Media Slugify: The feature ensures SEO-friendly URLs by automatically renaming new media folders and files to use slugs (e.g., “The team (2020).jpg” becomes “the-team-2020.jpg”). This is useful for improving search visibility, such as when uploading product images for an e-commerce site. The URLs are also just nicer.Secure Media: This feature allows administrators to control access to media folders based on user roles, ensuring only authorized users can view or manage specific files. For example, a company could restrict marketing files to the marketing team while allowing all staff to access shared resources, enhancing security and organization. If you are new to Orchard Core, you can check out user management (including adding permissions to roles) in one of our Dojo Course videos (to learn more about Dojo Course, click here).After enabling the Media feature, go to the Content menu, and you will see the Media Library menu item. Inside the Media Library, you will see one already existing folder named “_Users”. You can read about this here in detail. But in a nutshell, Orchard Core's Media Library includes a “_Users” folder with subfolders for each user, allowing them to manage their own media. New permissions like Manage All Media Folders and Manage Own Media let admins control access while restricting editors to their folders.A few buttons are not self-explanatory in the media library; we will go through them. With the plus button, you can add new folders to the media library. Just click on the folder and type its name. If you click on an existing folder, follow the same process; the new folder will be created as a subfolder of the current one.The invert button inverts the selection, so if you have image-1.jpg, image-2.jpg, and image-3.jpg, and you selected images 1 and 2, if you click on it, images 1 and 2 will be unselected, and 3 will be selected.With these buttons, you can change between list and grid view: This is the button for uploading files. You can select them from your computer, but you can also just drag them into the empty space in your folder in the media library.The delete button is also available, which is mainly for mass deleting files. If you want to do something with only one file, you can click on it, and three options will appear: rename, delete, and download. You can also filter by file name, that option is left to the upload button (4).Turning on different media features will also add new menu items to the Media menu under the Configuration menu. Media Cache: This menu item appears only if you turn on the Media Cache feature, which we discussed earlier. It contains options related to that feature, such as purging all the assets from the cache.Media Options: Here, you can see the configured media options. One option, for example, is Allowed file extensions, which tell you files with which extensions may be uploaded. You can configure these options from the appsettings.json file or other ASP.NET Core configuration providers. You can read more about it here. For example, if you want to allow only image uploads, you can specify extensions like .jpg, .png, or .gif. This ensures users can upload only images, preventing unauthorized file types like .exe or .zip.Media Profiles: In this menu item, you can define custom image transformations, such as resizing or cropping, to ensure consistent formatting across your site. For example, you can create a thumbnail profile that automatically resizes all product images to 200x200 pixels for a uniform storefront display.When you turn on the Media feature, you will also have a new content field, the media field. Returning to our example, we have trainers on the About page on Orchard Dojo. We already have a widget dedicated to trainers. A media field called image was added to the content type. You can see the media field's settings here: For example, when using the “Multiple” option, we can display multiple images in one media field. With the media field added, when we are creating a Trainer Widget, we can select an image: The plus button opens the media library, where you can select your image. After selecting the image, you will get a small preview of it: But let's see the blog post example. In our Blog Post content type, we have an HTML body (with the Trumbowyg editor). This supports adding an image with the image shortcode. Clicking on the “Insert Media” button, you can select the file from the media library. The result will be something like this: [], and the image will appear in the blog post after publishing it.In this blog post, we’ve seen Orchard Dojo's media library and how we use it, but let's look at another example: You have an e-commerce page where you sell tech products. With the Media feature, you can create product content items with media fields to display images of the products (even multiple with one media field). Let's say on the same site, you are also reviewing tech products in a blog-like format. When you are writing a review, you can use the image shortcode in the HTML body to display your photos of the product.To conclude, Orchard Core’s Media feature makes it easy and effective to manage media files across your site. With features like customizable media profiles, caching, and role-based access, it helps keep your media organized.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!

How to add import/export to an ASP.NET Core app? - Orchard Core Nuggets

When working with an ASP.NET Core application, it’s often necessary to move various content or configurations between different environments or back up critical information. Whether you’re setting up a new site, migrating content, or synchronizing data across multiple instances, the Orchard Core Deployment feature can simplify the process. This feature provides an easy solution for importing and exporting data.Are you new to Orchard Core? It's a great open-source framework and CMS built on ASP.NET Core. Check out the official getting started docs.Let’s say you manage multiple sites for clients. You might have a standard set of content (like sample blog posts, landing pages, or settings) to help clients get started. With Orchard Core Deployment, you can create these once, export them, and import them into each new Orchard Core instance to streamline the onboarding process. A similar example would be to move content or configuration between a staging and production app.To get started, go to Configuration → Features and search for “Deployment”. Some features will also enable others explicitly. We will go through each feature and explain what they do. Deployment: Offers a framework for importing and exporting recipes, JSON files containing configuration and content. This feature is the foundation of deployment (how we call export-import) in Orchard Core, allowing for the structured export and import of content, technical configuration, and user-editable settings for entire sites or specific components.Remote Deployment: Extends the deployment feature by allowing content export and import to and from a remote server. This feature is useful when managing Orchard Core installations across multiple environments, enabling direct deployment to remote instances, without downloading and uploading JSON files.Add Content To Deployment Plan: This feature adds an action in the content item action list to include specific content items in a deployment plan. This is useful when you want to select specific items to deploy without including the entire site’s content.Export Content To Deployment Target: Adds an option to the content item action list that allows you to directly export content items to a specified deployment target (including downloading the recipe, thus basically the content item inside a JSON file locally).View Or Download Content As JSON: Provides an action in the content item action list to view or download content as JSON files. This feature is helpful for reviewing content item details or troubleshooting.Here is an example of all the content item list actions that are added by these features:These actions focus on single content items and they are really simple. “View as JSON” and “Download as JSON” options are self-explanatory. If you select “Add to Deployment Plan” you will get a list of your current deployment plans and a default one will be created (“Export content to deployment plan target”):“Export to Deployment Target” will list the deployment targets. The default one is “File Download”:But what is a deployment plan? It’s a collection of steps that together produce a recipe JSON file. You can have multiple deployment plans. Let’s create one! Go to Configuration → Import/Export → Deployment Plans. Here you can see your deployment plans, rename them (with “Edit”), delete them, and modify them (“Manage Steps”).image alt="Deployment plans inside menu"]BlogPost/orchard-nuggets/2024/how-to-add-import-export-to-an-asp-net-core-app/deployment-plans-inside-menu.png[/image]Click on the “Add Deployment Plan” button. Here you can name your new deployment plan.After that, you can create the plan, and then you will see it in the list. Now click on the “Manage Steps” button for your deployment plan. You will see this screen, but it’s empty since you need to click on the “Add Step” button to add steps:Here you will see all the available steps:They have descriptions, but just to name a few important ones:All Content: Exports all the content items of the system.Content: Exports all content items for specified content types.Content Item: Exports a specified content item.All Features: Exports the state of all features, ensuring the same features are enabled or disabled across sites.We have two Page content items in our case, so let’s export those with the “My second deployment plan”.Add the “Content” step. Then select the Page content type. Additionally, you can check the “Export As Setup Recipe” option if the data should be exported as a Setup recipe. A setup recipe in Orchard Core is a JSON file that contains instructions for setting up content, configuration, and features on a new or existing Orchard Core instance, structured to automate the setup of a site. It’s almost the same as a recipe that you can export with the Deployment feature, just it needs to contain everything to set up a site, not just e.g. a couple of pages.After that, you can add the step by clicking on “Create” and execute the plan with “Execute”:When executing you can again select the target. The default option here is the previously mentioned “File Download” to download the deployment plan locally. This will download a ZIP file that has the “Recipe.json” file inside. This will contain in our case all the page content items.Okay, but how do you import? Go to Configuration → Import/Export. You will have multiple options:JSON Import: Here you can directly insert your Recipe.json file. You can copy the file's content, or you can also just drag the file there. The content will be visible as JSON and you can edit it before importing. In this example, we used the recipe which was inside the ZIP that we downloaded from “My second deployment plan”.Package Import: Imports a complete package (ZIP file) containing multiple JSON files, media files (yes you can export media files, by adding the Media step), and other resources. So this is best for large-scale site migrations or complete environment setups. You just need to select the ZIP file, then click on “Import”:In our case, this will throw an error but this is because we already have the two pages (thus the two permalinks of the pages are already in use), but if you import this package in another application that has the Page content type, it will work. But if it doesn’t have the Page content type, you can just add the “Replace Content Definitions” step in your plan, which will also export the content type after you choose it.But what if you want to import to a remote instance? If you have the Orchard Core Deployment Remote enabled you will see two more options under Import/Export: “Remote Clients” and “Remote Instances”.Under “Remote Clients” you can add your remote clients:You will need to set a “Client Name” and an “Api Key”. This will come from the client app. So for example, if you want to import from staging to production, you will need to go to production and create the client.After that, you can enter your staging site, and under “Remote Instances” you can add the instance.You will need to set a name (it’s just for display and can be anything) and a URL (which can be copied from under “Remote Clients” for example in your production app if you are importing to production).Then you will need to set the client name and the API key. These are the ones that you set first in “Remote Clients” in the other app.After that, the instance will be available as a target when exporting something (so it would be imported right into the target).Returning to the example at the beginning:Let’s say you manage multiple sites for clients. You might have a standard set of content (like sample blog posts, landing pages, or settings) to help clients get started.With Orchard Core Deployment, you can create the “template” of these sites, with the necessary items and settings, then export them into a recipe. After that, you can send that to your clients. Or Orchard Core Remote Deployment you can even export the recipe right to your clients' app.Orchard Core’s Deployment features make it easy to move content and configuration across environments or different sites. Whether you're migrating data or synchronizing settings, these tools simplify the process. Want to see these features in action? Check out our tutorial video to learn how to set up and use Orchard Core Deployment features!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!

How to add an audit trail to an ASP.NET Core app - Orchard Core Nuggets

When you have an ASP.NET Core application, that publishes content often and has different users, it’s a good idea to keep track of what is happening in the app: What changes? What content gets deleted or published by who? Who logged in, and when, did somebody fail to log in repeatedly using a wrong password? Who changed the settings?For example: Imagine you're managing a news portal where multiple articles are being written and published daily. One day, an article titled "Breaking News: Major Policy Change Announced" was accidentally deleted. It was a high-traffic piece, and its sudden disappearance created confusion among readers and the team. As an administrator or perhaps an owner, you want to restore the article, then find out what happened and who made this change. The answer is: Orchard Core and its Audit Trail module.Are you new to Orchard Core? It's a great open-source framework and CMS built on ASP.NET Core. Check out the official getting started docs.The Audit Trail module logs key changes and events in the system, such as content creation, deletion, and login failures. It also allows tracking changes to content, restoring previous versions, and recovering deleted items. It’s all extensible too, so you can add more features with some coding. Let’s see how to use it!First, go to Configuration → Features and make sure the Audit Trail feature is enabled. Optionally, if you also want to track user events (like somebody logging in etc.) you can enable the Users Audit Trail feature too. Please note that enabling the Users Audit Trail feature will automatically enable the base Audit Trail feature, as it is a dependency of the Users Audit Trail. After this, you can access the audit trail settings under Configuration → Settings → Audit Trail. You can see three tabs on the top: Events, Trimming, and Content. Let’s start with Events. Here you can see the events that will trigger an audit trail record, and by default, all of them are enabled. The first set of events is tied to content, so content item creation, removal, etc. You can disable any of those if you want. The second set of events is for the user. This set of events only appears if you enable the Users Audit Trail feature too. These are for user activities, so login, failed login, etc. You can also select to record the client's IP address. We recommend erring on side of caution, and starting with everything enabled, and only disable certain events if it turns out that they’re just noise for your site.Now take a look at the other tab, Trimming. If a site has a lot of activity, perhaps it’s good to delete audit trail logs after a year or so, since the records can eat up a lot of space in the database (it won’t really get slower, but depending on your hosting provider, you may need to pay more). The trimming setting allows you to do that. The default trimming option is 90 days. So any audit trail event that is logged and older than 90 days will be deleted from the database. To avoid trimming you can select the Disable trimming task option. In the Last run field, you can see the most recent time the trimming task was executed.Now, check the content tab. Here you can see the types of content for which events are logged. You can freely disable or enable any of them. In our example, some are enabled, but some are disabled. This is because we configured the audit trail settings in the startup recipe. For example, see this startup recipe in our open-source Lombiq Walkthroughs module. Of course, if you have different content types than our example site, you will see them on this screen. But remember, if a content type is disabled here, its events won’t be recorded (like deletion). Not all content types may be important for you to track. For example, if you're not actively using a particular content type, you might want to disable the logging of it to reduce unnecessary noise. Only track what’s necessary to balance performance and insight. For instance, in the image, just to name one, the tracking of the Layout Injection content type is disabled. This is because it’s a widget that is only used in one place, and it won’t be updated ever likely.Additionally turning on the Audit Trail feature will add a content part called Audit Trail part. This part as the description says: “Allows editors to enter a comment to be saved into the Audit Trail event when saving a content item.” If you add this part to the content type, you will see a new field for a comment, what you can use to add some explanation about the current content change. Staying with the news portal example, each time an editor revises, they can leave a comment in the audit trail explaining what was changed and why. For example, "I reworked the intro paragraph for clarity." This is all good, but how one can see the actual logs? Well, it’s pretty simple, now there is a new tab in the admin menu called Audit Trail. In this example, we had a page content type and audit trail turned on from the beginning. When I set up the site I created an admin user and I logged in. After that, I created a page content item, published it, and deleted it. You can restore deleted content items from the audit trail, so that’s what I did next. Then I renamed the title of the page. You can see all that from the logs: Returning to the example at the beginning:One day, an article titled "Breaking News: Major Policy Change Announced" was accidentally deleted.If the audit trail was turned on for that content type, now there is a solution! Go to the audit trail logs, you will see who deleted it and you can also restore it, correcting all the mistakes.For more audit trail features check out our open-source Orchard Core extension for the Audit Trail module: Lombiq Audit Trail Extensions. 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!

How to add workflows to an ASP.NET Core app - Orchard Core Nuggets

Do you want to send an email, when a form is submitted? Perhaps delete a content item after a certain amount of time? You don't want to write complex codes? Look no further with the Orchard Core Workflows feature you can achieve these, without writing any code. This way people who are not familiar with coding can also easily modify these processes.Are you new to Orchard Core? It's a great open-source framework and CMS built on ASP.NET Core. Check out the official getting started docs.Workflows in Orchard Core can be a powerful tool. A workflow is basically a visual script, that consists of two types of activities: Tasks and Events. A Task activity performs an action, for example sends an email, or creates a notification. An Event activity is like a trigger point, it listens for an event and it can activate Tasks. But why are workflows so useful? Here are some examples of what you can do with workflows:Automatically assigning a role to a user based on their input from a registration form.Moving content to an "Archived" state after a specified number of days since publication.Sending users a weekly email digest summarizing newly published content on the site.Sending a reminder to users who have incomplete profile information after a certain period.This is to name a couple.Let's see how you can create your own workflow! In this example we will create a workflow that displays a notification, but only for users in the Administrator role.First, go to Configuration → Features and make sure the Workflows feature is enabled. Now you can access the workflows in the Workflows menu point. Click on the Create Workflow button. Name the workflows for example "Display Notification for Administrators". You can leave the other settings as they are and click on Save. Now you will see the dashboard of our workflow. Here click on the Add Event button, so our workflow will have a starting point. Select the User LoggedIn activity, you can give it a title but it's not necessary. To make this your startup event, you will need to click on the event and then on the Startup task button. After that, the event card will turn green. Now let's add a task. Click on the Add Task button and select Validate User, as the description says it checks if the user exists for the current request and has the specified role(s)". When adding the task select the Administrator role in roles. Also select Set the 'UserName' workflow property if the user is authenticated. Okay, there is a starting event and a task, but how do we connect them? It's pretty simple: grab the green dot from the top of the starting activity and drag it to the task. We only need one more activity a task that displays notifications. So click on the Add Task button once more and select Notify. For the notification type let's go with Success, the message could be anything, but since we have the username from the previous activity, we can personally welcome the user. You can use Liquid syntax, just like this "Welcome, {{ Workflow.Properties.UserName }}!". After saving it, the only thing left to do is to connect the InRole dot from the top of the Validate User activity to the Sucsess Notification activity. In the end, your workflow should look something like this: Save it, then you can log off and log in with an admin user and see the results: That's it! You can modify this workflow how you want, add more events or tasks and based on this tutorial create your own!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!

How to change the idle logout time in Orchard Core - Orchard Core Nuggets

Keeping user accounts secure is important. One aspect of this is to constrain how long people can remain logged in: If they share a device, especially a public one, then it's better to be on the safe side and automatically log them out after some time of inactivity. Here is how you can do it in Orchard Core! Since an Orchard Core-using app is in the end just an ASP.NET Core app, you can use the standard Identity options to configure how user sessions work. What governs how long users remain logged in is mostly the cookie settings. This is how you can set it from the Program file of your web app: builder.Services .AddOrchardCms() .ConfigureServices(services => services.ConfigureApplicationCookie(options => options.ExpireTimeSpan = TimeSpan.FromMinutes(30))); This logs users out after 30 minutes of inactivity. You can also set options.SlidingExpiration = false if you'd like this to be counted from the time they logged in, as opposed to the last time they did something in the app. While the above example shows how to do this in the root web app, you can similarly set this from the Startup class of a module or theme. That's it! It's worth checking out the official Orchard Core docs on configuring other Identity options too. 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!