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

Hosting Orchard Core at Exoscale

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 Exoscale! Blog post series overview This 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 Exoscale? Exoscale is a cloud provider from Switzerland, with hosting locations back at home, as well as in Germany, Austria, Bulgaria, and since July also in Croatia. 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. DNS management is also available, though that's something I'd keep at Cloudflare for a real-life app. I'd also use Cloudflare as a CDN, despite Exoscale offering a CDN layer (with Akamai) on top of their object storage; but since in Orchard Core we don't serve Media files from storage directly, that wouldn't help anyway. 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 environment You surely already guessed, but we'll need three Exoscale services: A Compute Instance, i.e. a VM, for the web server. A DBaaS database; we'll use PostgreSQL. We could also create SQL Server instances, but not only would the minimum 2-core VM be an overkill for our purposes, it's also much more expensive, starting at about EUR 247/month (vs a Postgres DBaaS starting at EUR 42/month). Object Storage for Media. Let's start with the server! I went with the Swiss zone, since there's no place like home, and opted with a 2-CPU plan with 2 GB of RAM. For this site, 1 CPU would also be more than enough (while to cater for Windows, I'm more comfortable with 2 GB of RAM instead of 1), but there's no 1-CPU 2 GB RAM instance type. [image alt="Creating an Exoscale Compute Instance"]BlogPost/other-posts/2025/hosting-orchard-core-at-exoscale/creating-a-compute-instance.webp[/image] You may notice two things here: On the right, there's a warning about having to create Security Groups for ingress rules first. (Somewhat confusingly the ADD button below it actually creates the compute instance, not a Security Group.) To be able to actually connect to the VM, we also need to edit the default Security Group (or perhaps more diligently, create a new one), then open up the ingress port 80 with TCP (for HTTP), as well as add a rule for RDP. As a last step, you'll also need to add 0.0.0.0/0 (i.e. all IPs) under External Sources, allowing anyone to connect to our web server. Those ENABLE buttons for instances Mega and up mean that you need to ask Exoscale support to allow them "after a manual screening process". This I find a bit strange. Until the server started, so in the meantime, I created an Object Storage bucket in the same zone (to minimize latency, these resources should all be in the same zone): [image alt="Creating an Object Storage bucket"]BlogPost/other-posts/2025/hosting-orchard-core-at-exoscale/adding-bucket.webp?2[/image] It seems that unlike with other cloud providers where you create a storage account, then a bucket under it, here everyone shares the same storage account. Thus, bucket names should be globally unique. This doesn't seem appealing at a first glance, but apart from the naming issue, I didn't find any practical problem with it. Somewhat counterintuitively, the storage access and secret keys are API keys. You can create these following the docs; for the sake of simplicity, I created a key for the Owner role, but for a production app, you should follow the docs' recommendations and create a restricted role just to access this bucket. Finally, we also need a single-node Postgres database server: [image alt="Creating a managed database"]BlogPost/other-posts/2025/hosting-orchard-core-at-exoscale/adding-postgresql-dbaas.webp[/image] Note that this runs on its own VM. The IP filter is necessary for the web server to access the DB server; the provided CIDR matches the exact IP of it. This is everything we need, so now we can continue with setting up Orchard Core in this environment. Deploying Orchard Core to the web server You 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: [image alt="The Orchard Core app running under Windows Server"]BlogPost/other-posts/2025/hosting-orchard-core-at-exoscale/app-running.webp[/image] 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 Core Running 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 Exoscale Console, take the password of the default user from the DB's Users menu, and ask your favorite AI tool to turn them into an Npgsql connection string that .NET uses. Once setup finishes, you can configure Media storage too. I've elaborated above how to set up a bucket; the service URL for it will be in the format https://sos-{zone}.exo.io, with our Switzerland zone being ch-dk-2. 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://sos-ch-dk-2.exo.io", "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": "oc-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 Exoscale? OK, so we've seen that running Orchard Core under Exoscale 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 Exoscale is not just hosting in Europe, but the company itself is also based in a European country. 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. Note though, that while Switzerland is highly aligned with the EU legally, it's not an EU member state, nor part of the European Economic Area. Costs Exoscale can be a lot cheaper. At €17/month, the Exoscale server provides roughly the same as an A1_v2 Azure VM, which costs €45/month. However, the smallest managed Postgres instance at €42/month is way above what we'd use on Azure for an entry-level app, where an S0 Azure SQL DB would be around €13/month. So, in the end, Exoscale costs around EUR 60/month, while the roughly equivalent service in Azure would be basically the same. We do get more with Exoscale (a dedicated VM for the DB, and I think the web server is faster too), a lot more room to grow, but the cost advantage, in itself, disappears, at least in the beginning. For an entry-level app the storage is cents in both cases, but if you increase your usage, Exoscale's storage costs can be dramatically lower (EUR 0,00002750/GB vs Azure's Standard Hot tier at EUR 0,0185/GB). Network costs at Exoscale (EUR 0,02/GB for egress) and per-operation costs at Azure (there's no simple number for this) complicate things, though, so be sure to calculate what's applicable for your app. 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 Console, I could fully understand the Exoscale 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 (plus getting stuck on the mentioned storage configuration). The cons Coming from frequently using the cushy but extremely complex ecosystem of Azure, using a more basic provider like Exoscale 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 Exoscale: 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 €43/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 Exoscale, 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).There are also three notable things I very much didn't like about Exoscale's pricing: All prices on the pricing page are shown for usage hours only. That's necessary, but a metric frequently a lot more useful is the monthly cost. While I can always multiply by 730 to get an approximation of a month, it would be much clearer to have it indicated in the pricing table already. Also, I'd welcome seeing these hourly and monthly costs indicated in the Exoscale Console, when creating resources, too. The Pricing Calculator helps, and it does show monthly costs too, but it's better to show this information everywhere. The prices in EUR, CHF, and USD are exactly the same. Given that 1 CHF is 1,07 EUR, and 1 EUR is 1,16 USD as of writing this, there's a significant difference in your costs depending on what you pay with (you pay almost 25% more in CHF than USD). According to the website, "Your account can be setup in either CHF, EUR or USD, depending on your initial legal residence." This seems like an arbitrary disadvantage for Swiss users, and an advantage to non-EU ones. The latter is a surprising policy for a company primarily targeting EU customers. I'd welcome the price differences to disappear.You can only pay in advance, at least as a new customer. This requires you to either be ready to top up your balance any time you get a low credit notification, or you need to park an excessive amount at Exoscale. In either case, it's also a manual process. It would be better if they would just charge my card after each month's usage. So, what should I do?Based on the feature set, Exoscale 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. However, I think the particularities of Exoscale's pricing are not for everyone. And if you need help hosting Orchard Core at Exoscale, Azure, or onboard of a satellite (not kidding), drop us a line!

Latest tutorials

Hosting Orchard Core at Exoscale
zoltan.lehoczky
Step away from that Node.js
sara.el-saig

Featured tags

AI
SMS
IIS
MCP
API
SEO
SSL
All tags >

Cleanup IContentManager, updated Azure Application Insights module - This week in Orchard (21/06/2024)

Documentation about opening and managing issues, cleanup IContentManager, and the updated Azure Application Insights module for Orchard Core are the topics for this week. You can still apply to speak at Harvest 2024 and share your insights on Orchard Core's future, CMS roles, AI tools, cloud integrations, and more! Let's see the details! Orchard Core updates Issue management documentation, auto-close, and triage comment workflow Now all the bugs and PRs are closed automatically. If there is no activity after 15 days on a PR, we close it but only if the need author feedback is present. So, if we can't merge the PR because we don't have enough information and there is no answer for 15 days then the PR will be closed. But you can reopen it if you have time to answer later. All of the stuff related to opening and managing issues is documented here. You can read about how to open an issue, what happens after you open an issue, or how to manage issues as a core contributor. Cleanup IContentManager The IContentManager interface was modified. The method Task<IEnumerable<ContentItem>> GetAsync(IEnumerable<string> contentItemIds, bool latest = false) was removed. Instead, use the method that accepts VersionOptions by providing either VersionOptions.Latest or VersionOptions.Published will be used by default. Additionally, the GetContentItemByHandleAsync(string handle, bool latest = false) and GetContentItemByIdAsync(string contentItemId, bool latest = false) were removed from IOrchardHelper. Instead, use the method that accepts VersionOptions by providing either VersionOptions.Latest or VersionOptions.Published will be used by default. Lastly, we dropped support for AllVersions option in VersionOptions. Instead, you can use the new GetAllVersionsAsync(string contentItemId) method on IContentManager. News from the community Orchard Harvest 2024 date and location Get ready to power up your Orchard skills at Orchard Harvest Conference 2024! Join us on September 12th-13th at the Orleans Hotel and Casino in lively Las Vegas for two days packed with learning, coding, and community fun. What can you expect at Orchard Harvest Conference 2024? Hands-On Workshops: Elevate your coding game with interactive sessions led by industry experts. Insider Insights: Learn best practices, advanced techniques, and real-world insights from qualified developers. Global Connections: Connect with fellow enthusiasts, exchange ideas, and forge meaningful relationships within the Orchard community. Special Perks: Participants get exclusive discounts on accommodations at the Orleans Hotel and Casino. Can't wait until September? Check out recordings from last year's special online Orchard Harvest on our YouTube channel here. Ready to be a part of something extraordinary? Reserve your spot today and take advantage of early-bird pricing at Orchard Harvest Conference 2024. We also opened the registration form for the speakers: https://forms.office.com/e/fewh7hh20d This year's leading themes: Leading up to a v3.0, what will the future Orchard Core look like? What's the role of a CMS nowadays (with the decoupled/headless operating models, and AI development tools) Explore some advanced topics such as Shapes, Placements, Cloud Integrations, Performance, module extensibility, etc. Showcases on implementing Orchard Core in action. We've extended the sign-up period by another 2 weeks, so if you haven't signed up yet, you can still sign up now! Apply to be a speaker until the 29th of June, midnight Anywhere on Earth! We'll notify you whether your talk is selected for Harvest in 1 or 2 weeks after the application period. The chosen speakers will receive complimentary tickets for the event. Want to support our mission? Become a sponsor! Reach out to us at [email protected] or [email protected] to explore sponsorship opportunities. Secure your spot today and get ready to level up your skills at Orchard Harvest Conference 2024! See you there! Updated Azure Application Insights module for Orchard Core Our Orchard Core module enables easy integration of Azure Application Insights telemetry into Orchard. Just install the module, configure the instrumentation key from a configuration source, and the collected data will start appearing in the Azure Portal. Check out the module's demo here! We have recently updated this module to version 8.1.0, now with Entra ID authentication! Well before the 30 September 2025 deadline when Azure deprecates API keys. Check out the module's details and install it from NuGet here. Do you want to quickly try out this project and see it in action? Check it out in our Open-Source Orchard Core Extensions full Orchard Core solution and also see our other useful Orchard Core-related open-source projects! Orchard Dojo Newsletter Lombiq's Orchard Dojo Newsletter has 472 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!

Keyed services, Hastlayer.com is running on Orchard Core - This week in Orchard (29/12/2023)

Adding helpful methods for ContentPart, ContentType builders, and ContentItemExtensions, introducing keyed services, and a case study about modernizing and migrating Hastlayer.com to Orchard Core are the topics for the last week of this year. Let's check them out in detail! Orchard Core updates Adding helpful methods for ContentPart, ContentType builders and ContentItemExtensions This is about introducing several new useful methods and extension methods for Orchard Core to make the developer's life easier. Let's see the changes! New methods in ContentPartDefinitionBuilder ContentPartDefinitionBuilder WithField<TField>(string fieldName) ContentPartDefinitionBuilder WithField<TField>(string fieldName, Action<ContentPartFieldDefinitionBuilder> configuration) Task<ContentPartDefinitionBuilder> WithFieldAsync<TField>(string fieldName, Func<ContentPartFieldDefinitionBuilder, Task> configuration) New methods in ContentTypeDefinitionBuilder ContentTypeDefinitionBuilder WithPart<TPart>() ContentTypeDefinitionBuilder WithPart<TPart>(string name) ContentTypeDefinitionBuilder WithPart<TPart>(string name, Action<ContentTypePartDefinitionBuilder> configuration) New extension methods in ContentItemExtensions bool TryGet<TPart>(this ContentItem contentItem, out TPart part) bool TryGet<TPart>(this ContentItem contentItem, string name, out TPart part) bool TryGet(this ContentItem contentItem, Type contentElementType, string name, out ContentElement part) New extension method in EntityExtensions bool TryGet<T>(this IEntity entity, out T aspect) But let's not just list these here, see a little example too! On this screen, you can see the migration of the SeoMetaPart where we configured this part and added some fields to it. You can see that this part contains a field called DefaultSocialImage and by using the OfType method, we can set the type of the field (MediaField in this case). But by using one of the new overloads of the WithField method, we don't need to use the OfType method, we can pass a typed value, the type of the field itself. Keyed services The recently released .NET 8 introduces keyed service dependency injection container support. Currently, we don't support it in Orchard Core and the goal of this feature is to allow us to use keyed services in Orchard. Here you can see that in this CloneSingleton extension method, we need to understand whether is it a keyed service or not, and based on the ServiceKey object (which gives the key of the services, if applicable) of the ServiceDescriptor (which describes the service with its service type, implementation, and lifetime) we can decide which overload of the ClonedSingletonDescriptor method do we need to call to add our service to the ServiceCollection. News from the community Case study: Hastlayer.com is running on Orchard Core The new website for Hastlayer, the .NET hardware accelerator originally built on Orchard 1, now runs on Orchard Core! Check out our case study here about the migration! We are happy with the results and the additions to our open-source modules, and stay tuned, as we keep the migrations rolling. This is an excellent time if you're considering migrating your Orchard 1 website to Orchard Core. Should you have any questions or encounter challenges, don't hesitate to reach out to us. We're always ready to bring our expertise to your unique project needs. Contact us today, and let's start making your Orchard Core website even better! Orchard Dojo Newsletter Lombiq's Orchard Dojo Newsletter has 484 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 a way to Remove User from a Role, Lombiq Hosting - Tenants Email Quota Management - This week in Orchard (15/12/2023)

New Get users by roles and Unassign users from roles activities, add async methods to ContentDefinitionManager to prevent possible thread starvation, and a demo about Lombiq's Tenants Email Quota Management module! Let's get started! Orchard Core updates Add a way to Remove a User from a Role This change introduces two new activities that you can utilize when working with workflows. The first one is called Get users by roles. Here you can easily choose the roles to identify users by using the Roles check boxes. You can see that you can provide a key (Output Key Name) that will be used to store the user's ID in a list that you can use in an upcoming activity in your workflow. The second activity is the Unassign user from roles one. The Roles check box works the same and the UserName text box can be used to provide the user name of the user who you want to update. Here in this silly example, we hard-coded the admin user name but of course, you can use Liquid to have a flexible activity. Add Async method to ContentDefinitionManager to prevent possible thread starvation The idea here is to make all the IContentDefinitionManager methods async to prevent possible thread starvation. To avoid a breaking change, the old ones were marked as obsolete. Here is a list of interfaces that were modified: IStereotypeService IStereotypesProvider IRouteableContentTypeProvider IRouteableContentTypeCoordinator IContentDefinitionService IContentDefinitionManager IContentDefinitionService On this screen, you can see the updated IContentDefinitionManager interface, where the non-async methods were marked as obsolete with a warning message that these methods will be removed in the upcoming releases. So, when you update your solution to the latest Orchard Core version, don't be surprised when you see some warnings after you build your solution. Demos Lombiq Hosting - Tenants Email Quota Management This demo will be about a new Orchard Core module, part of our Hosting Tenants repository, that helps you manage email quotas. Hence the name Email quota management, which could be useful if you have a SaaS provider (like our SaaS provider, DotNest) and you would like to restrict the number of emails sent out per month per tenant only if the tenant is using your SMTP provider. Of course, you don't want to restrict those tenants who are using their own SMTP provider. To set the quota you can use the appsettings.json file or an environment variable. The default value here is 1000 emails per month. Now it's time to try out this project and see it in action! The easiest way is to clone Lombiq's Open-Source Orchard Core Extensions solution. This Orchard Core Visual Studio solution contains most of Lombiq's open-source Orchard modules and themes, as well as related utilities and libraries, containing the Email quota management module too. First of all, you need to enable the Lombiq Hosting - Tenants Email Quota Management module under Configuration -> Features. After that, let's navigate to Configuration -> Settings -> Email. And wow, you can see that we have already sent 997 emails out of 1000 this month. Yeah, we cheated a little bit and we already sent out some emails using workflows. In this case, the users who have site owner permission will receive an email when the tenant reaches 80% of the available email quota for this month. They will get another email if you exceed 90% of the email quota. When you reach your quota for this month, you will get a red notification that can be seen on every page in the admin UI. It means that you will not be able to send out more emails until next month. As always, if you would like to know more about this module, head to YouTube for a recording! News from the community Orchard Dojo Newsletter Lombiq's Orchard Dojo Newsletter has 487 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!

Pager with page size, refactor IContentAliasManager to IContentHandleManager - This week in Orchard (25/09/2020)

Several great features and fixes were added to Orchard Core this week! You could see a fix for an interesting issue about how you can use XSS in an SVG file, the new IContentHandleManager, and two great demos! One is about the upcoming Pager with the page size, then check out the improvements of the Shape Components! Orchard Core updates Media Content Security Policy There was a Stored Cross-site Scripting security breach through the upload of a malicious SVG file, containing malicious JavaScript code, that is then executed whenever a user tries to view the contents of the uploaded file. In order to replicate this issue, you just needed to follow the steps described below: Create an SVG file with malicious JavaScript: <?xml version="1.0" standalone="no"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg version="1.1" baseProfile="full" xmlns="http://www.w3.org/2000/svg"> <rect width="300" height="100" style="fill:rgb(0,0,255);stroke-width:3;stroke:rgb(0,0,0)" /> <script type="text/javascript"> alert(1); </script> </svg> In the Media Library, upload the file you just created. Locate the uploaded file in the Media Library and select View. Observe that a JavaScript alert popup is triggered. To prevent that the fix is to add a new security policy. This means the browser will render the SVG without executing the inline scripts. The Media.StaticFileOptions is now slightly more configurable with services.PostConfigure to allow more fine-grained controlled, if any wants to adapt the event handlers and/or use them to block certain types of requests, or whatever they feel they need to. You can see the changes in the MediaOptionsConfiguration where the DefaultContentSecurityPolicy stores the value of the content security policy header. Refactor IContentAliasManager to IContentHandleManager This is about refactoring the IContentAliasManager and associated providers to be referred to as handle. From now you will see new extension methods: Orchard.GetContentItemIdByAlias("my-alias"); Orchard.GetContentItemIdBySlug("blog/post-1"); Orchard.GetContentItemIdByHandle("slug:blog/post-1"); and generally refactors everything else that referred to as an alias as a handle. It will not break anything, because it's keeping the IContentAliasManager and registering it to resolve the IContentHandleManager. The IContentAliasManager is not obsoleted to prevent compilations errors. But we could also just drop it completely in the near future. The IContentAliasProvider however has been renamed to IContentHandleProvider with no cross resolving. Now let's see an example to make this change clear. Let's say you have a content type that has the AliasPart attached. Every alias has a pattern, which is generated by the DisplayText of the content item: {{ Model.ContentItem | display_text | slugify }} So, if you create a new content item of this content type with a display text My new content item, your alias will be my-new-content-item. OK, now we have this content item. Let's say we need to get this content item and modify some properties of it from code. But how can we get this content item? Well, you can use the default implementation of the IContentAliasManager to do that: var myContentItem = await _contentAliasManager.GetContentItemIdAsync("alias:my-new-content-item"); Notice that here we need to pass the alias: string also because we would like to get a content item by an alias. From now we can use IContentHandleManager instead of the IContentAliasManager in the following way: var myContentItem = await _contentHandleManager.GetContentItemIdAsync("alias:my-new-content-item"); The GetContentItemIdAsync method of the IContentHandleManager iterates through all of the IContentHandleProver implementations and we have an AliasPartContentHandleProvider, that checks if the handle starts with the alias: string, and if yes, it returns the content item by using the AliasPartIndex table. As we mentioned you have new extension methods to use in your Razor code. The GetContentItemIdByHandleAsync is now just about calling the same IContentHandleManager implementation as we showed you above. Configure cookie lifetime for CulturePicker The issue was about you cannot change the expiration of the content localization cookies. By default, the cookie lifetime is set to 14 days, but if you would like to set it to 1 day, you couldn't do that until now. If you open the appsettings.json file in the OrchardCore.Cms.Web, you will find an OrchardCore_ContentLocalization_CulturePicker section there. Just uncomment that lines and use the CookieLifeTime to set the culture picker cookie lifetime in days. Demos Pager with page size If you have ever worked with an Orchard 1.x site, you may have seen how does the pager looks like at the bottom of the lists, like when you are on the page that shows you the contents list. It shows you the total number of items, the current page where you are right now, and you can also set how many items you would like to see on each page. It's slightly the same in Orchard Core too. The only difference is here that you don't have the option to set how many items you would like to see on the current page. If you navigate to Configuration -> Settings -> General you will see an option called Page size, but that's about saying 'I would like to see 10 items in every page'. You can't set the page size of the current page near the pagers. Antoine Griffard decided to start working on this feature for Orchard Core too. If you enabled the Tenants feature and navigate to Configuration -> Tenants, you will see the first prototype of this feature on that page. We have 11 tenants in the system and we set the page size to 10. In this case, the pager shows two pages and you can see the number 10 here as well. There is also a recording that shows you this feature, head to YouTube to know more! Shape Components updates Two weeks ago we wrote about a great upcoming feature to Orchard Core about having Shape Components. Let's think about a shape like a reusable component, like a view component in ASP.NET, but like an Orchard shape component, that can be reused. The development on that feature is continuing, this time you could see making the Razor Tag Helpers a little bit more feel like a component. Watch this recording on YouTube to see the current state of this upcoming feature! News from the community Blogs posts about Shortcodes, Shortcode Templates, and Shortcode Delegates I think we don't need to introduce David Hayden to the Orchard community. David Hayden is primarily a C#, .NET and Orchard CMS Developer with 20 years experience developing ASP.NET Websites and related technologies. David is currently primarily focusing on .NET Core, Orchard Core, and Orchard Core CMS for building modular, multi-tenant web applications and websites. He recently published two new posts in his blog about Shortcodes and Shortcode Templates in Orchard Core CMS and Shortcode Delegates. If you would like to learn more about Shortcodes or you haven't heard about them yet, it's definitely worth to check out these articles! But don't forget that you can find two videos on YouTube about Shortcodes: check out this one first, then watch this video for the second part of the demo! We also mentioned these features in This week in Orchard too several times. Check out this for an introduction, then this one for the first demo, finally don't forget to read this post to see the improvements of the Shortcodes! And the documentation is available in this URL! Orchard Dojo Newsletter Now we have 160 subscribers of the Lombiq's Orchard Dojo Newsletter! We have started this newsletter to inform the community around Orchard with the latest news about the platform. By subscribing to this newsletter, you will get an e-mail whenever a new post published to Orchard Dojo, including This week in Orchard of course. Do you know of other Orchard enthusiasts who you think would like to read our weekly articles? Tell them to subscribe here! If you are interested in more news around Orchard and the details of the topics above, don't forget to check out the recording of this week's Orchard meeting!

This week in Orchard - 09/27/2019

The first release candidate of Orchard Core has been shipped! Read our post about the latest improvements of the new release and everything you need to know about where you can download the release and how you can work with an application that uses .NET Core 3.0! On Orchard Core Add contentitem tag helper and liquid tag Now we have a new contentitem tag helper and a Liquid tag. By using this tag helper we can render a content item directly and can also use caching. We still need to use the menu shape, because it has custom alternates that are specific to it, so we can't remove that. But at least now we have a contentitem helper that also do it for anything. Handle standard Startup class Until now if you add the Startup.cs to your module, you need to inherit the Startup class from StartupBase and you need to have to override the ConfigureServices(IServiceCollection services) or the Configure(IApplicationBuilder builder, IRouteBuilder routes, IServiceProvider serviceProvider) method. Now you can define a Startup class and don't have to inherit from anything like in ASP.NET Core. Of course, you can include the ConfigureServices or the Configure method to configure the app's services if you want, but you don't have to override anything. Fallback to Detail display type for bag parts If you create a BagPart and in the settings, if you remove the display type of the content types that you want in the BagPart, then it will be null in BagPart.cshtml and will fallback to Summary. Because they are widgets if you haven't implemented the Summary view of the widget that you are rendering, it will fallback to template Widget__Summary. But this thing doesn't exist. So the result will be a shape not found error. The solution is to fall back to the Detail, which is the default display type that we use for widgets when we render them. Configure ContentParts and ContentFields with IOptions<ContentPartOptions> or IOptions<ContentFieldOptions> We don't inject a ContentPart in the DI directly. We add the type of the ContentPart to an option, which is IOption<ContentOptions>. In this case, we don't have to resolve the ContentPart to get instances of ContentParts to know what are the ContentParts that are available. We do the same for ContentFields. Content items: Bulk actions and Filters UX Here you can see a concept to redesign the content items page for the bulk actions and the other filters: As you may see, Antoine has been mainly inspired by the GitHub issues UX. The new features are: Select all aligned vertically with the other checkboxes. Smaller left and right padding in the items list. All filters and actions on only one line. Dropdown actions with a light background (correctly displayed on a small screen). Even the Culture filter could appear. Display the number of items and the number of selected items when checked. It is just a POC. To make it work completely, we will need to find a way to select and display the state of the different filters like GitHub does it. For example: type:Article status:published sort:created Just to have a big picture of the two different screens, the current UI looks like this: This feature hasn't been available in Orchard Core yet but will be added in the next version of Orchard, because it was too risky to change the content items page before the RC in this huge way. Add translation metapackage to Cms.Targets As expected we added the OrchardCore.Translations.All to the Cms.Targets. If you use the Cms.Core.Targets you won't have it, but if you use the Cms.Targets you will get the themes and all the localization in your solution. But it didn't work, because there were some missing MSBuild Targets. Now it has been fixed. Orchard Core first release candidate has just shipped The community proudly presents the first release candidate of Orchard Core! RC means that the software is almost ready for the final release. No feature development or enhancement of the software is undertaken; tightly scoped bug fixes are the only code you're allowed to write in this phase, and even then only for the most heinous and debilitating of bugs. Let's see the list of changes for this release. As you can see from the list, Orchard Core is now on ASP.NET Core 3.0. That means now if you would like to contribute to Orchard Core you will need to install Visual Studio 2019 16.3. By updating to this version you will automatically get .NET Core 3.0 too because it is included in this version, but from here you can download both the SDK and the Runtime. The NuGet packages in NuGet.org are also updated and have the version number 1.0.0-rc1-10004. Don't forget that from now you can also download the translation packages from NuGet.org. There is an OrchardCore.Translations.All package that contains all the languages, but you can find the packages for every language separately too. Oh, and don't forget the Docker images of Orchard Core! You can also try the new version on Try Orchard Core. So don't hesitate, upgrade your Orchard Core site from Beta 3 to RC now! Building modular, multi-tenant ASP.NET Core apps with Orchard Core framework There was the .NET Conf this week, which was a 3-day virtual developer event co-organized by the .NET community and Microsoft. Sébastien submitted a talk about Orchard Core modularity and multitenancy and he was able to speak! At September 24 at 00:00 (UTC), he made a great talk about building modular, multi-tenant ASP.NET Core apps with Orchard Core framework. If you haven't seen his section yet, you can watch the recording in Twitch. On Lombiq Silent improvements in the background in DotNest As you may now DotNest is a SaaS provider that gives hosted Orchard CMS web applications hosted by Lombiq Technologies. We are thrilled to develop and maintain a provider like that and improved our services for time to time to make a better DotNest for you! Now we have just added some infrastructure improvements and making payments safer with PSD 2. Orchard Dojo Newsletter Now we have 94 subscribers of the Lombiq's Orchard Dojo Newsletter! We have started this newsletter to inform the community around Orchard with the latest news about the platform. By subscribing to this newsletter, you will get an e-mail whenever a new post published to Orchard Dojo, including This week in Orchard of course. Do you know of other Orchard enthusiasts who you think would like to read our weekly articles? Tell them to subscribe here! If you are interested in more news around Orchard and the details of the topics above, don't forget to check out the recording of this week's Orchard meeting!

This week in Orchard - 07/12/2019

Lots of new features and improvements and a very interesting demo about the Content Culture Picker is waiting for you in our current post! Oh, and of course our Orchard Core Training Demo Module has got a huge update too! On Orchard Core Set Content Types during Azure Blob creation When uploading a file, for example, a PDF into Orchard the Content Type is set to "application/octet-stream" on the Azure Blob when it should be "application/pdf" (this is the content type that Azure itself picks when you upload a PDF directly). Now Orchard Core has the fix that sets the blob properties during creation. Improve ImageSharp Middleware Processing Speed Because /Media is a well-known location we could improve the processing speed of the ImageSharp middleware and reduce the allocations it makes on every request. At the moment the MediaFileProvider returns IsValidRequest which is the first opportunity for ImageSharp to drop out of the processing pipeline. The first check in IsValidRequest checks for a valid image extension in the URL using Request.GetDisplayUrl(). If we check Request.Path for contains Media first we can bypass all the allocations from Request.GetDisplayUrl() and _formatUtilities.GetExtensionFromUri(...). Let' see the MediaFileProvider now! The IsValidRequest method here first checks that the first segment of the path is equal with the Startup.AssetsRequestPath. The AssetsRequestPath contains PathString("/media"). Add grouping of widgets to their site layer The GraphQL siteLayers query enhanced to group widgets into their layers. In the following screen, you can see that there are two widgets in the Always layer and one on the Homepage layer. Add PathBase PathBase may contain a virtual folder and, before the execution of the tenant pipeline (e.g. when executing a middleware configured at the app level), it doesn't contain the tenant prefix yet. PathBase = /{virtualFolder} - Path = /{tenantPrefix}/somePath// If no value => {}, converting the PathString to a string results in an empty string. Then, when we are in the tenant pipeline (e.g. when executing a middleware configured at the tenant level e.g. by a module), the tenant prefix (null for the default tenant) has been moved to the PathBase. PathBase = /{virtualFolder}/{tenantPrefix} - Path = /somePath In some contexts, we don't have to care about this e.g. when using the URL helper for an action, but here, how we build URLs, this is not the case. So, here it was not working under a virtual folder, the fix is to use PathBase but without reusing the tenant prefix. _contentItemlistUrl = httpContextAccessor.HttpContext.Request.PathBase + "/Admin/Contents/ContentItems1/";var formActionWithoutTypeName = Context.Request.PathBase + "/Admin/Contents/ContentItems"; LocalizationSettings recipe step documentation The Localization section in ReadTheDocs of Orchard Core has been updated with how to add cultures with recipes using the settings step. Demos Content Culture Picker When you enable the Content Culture Picker module, you will get a culture picker shape for the frontend. The Content Culture Picker module helps you manage cultures for the frontend. This uses a dropdown listing all the supported cultures and you select which culture you want to see when you are on the website. The Content Culture Picker selects the URL to redirect to like: if the ContentItem has a related ContentItem for the selected culture, it redirects to that Item if a HomePage is specified, finds the ContentItem that is set as the Homepage and attempt to find a Localization of this ContentItem for the current culture or a NotFound() page Let's see how it works! To create localizable content items, you have to enable the Content Localization module. This module will provide you the LocalizationPart, that you can attach to your content type. For the sake of the demo, we set up the site with the Blog recipe and attached the LocalizationPart to the Blog Post Content Type. Then head to Configuration -> Settings -> Localization to add more supported cultures. Now head to the editor of a content item that has LocalizationPart attached and save or publish it. You can see that our default culture is English and we added 3 other supported ones. If you click one of the cultures, the localized version of the content will be created. We created slightly modified blog posts for each culture to be able to see the differences between them. Now it's time to use the Content Culture Picker! You can find detailed documentation on ReadTheDocs about how to use the picker and what shapes are available for the frontend theme. For now, let's just simply modify the Layout.liquid file of the TheBlogTheme and using the liquid syntax, use the shape shape tag to create and render the ContentCulturePicker shape. We added a white background behind the picker to see it better. Now if you visit one of the blog posts you can switch between them using the content culture picker. On Lombiq Orchard Core Training Demo Module V2 Orchard Core Training Demo module is a demo Orchard Core module for training purposes guiding you to become an Orchard developer. You can use this module as part of a vanilla Orchard Core source that including the full source code - which is the recommended way. You can use it as part of a solution the uses Orchard Core NuGet packages, however, it's harder to look under the hood of Orchard Core features. The module assumes that you have a good understanding of basic Orchard concepts and that you can get around the Orchard admin area (the official documentation may help you with that). You should also be familiar with how to use Visual Studio and write C#, as well as the concepts of ASP.NET Core MVC. Now, this module has got a huge update with new tutorials: permissions, admin menus, site settings, caching, file management, background tasks, and VueJS! In the StartLearningHere.md you can find all the training sections to easily navigate to the topic that you are interested in. Orchard Dojo Newsletter Now we have 78 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 every time when 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!

Diving into the Orchard API - Dojo Course

UPDATE (2017-11-22): Dojo Course 2 is released with new, updated videos! This week on Dojo Course we dive into the Orchard API, use some of the build-in services and extending the capabilities of our module to make it even better! Using LazyField<T> to load data lazily so they are only loaded when we really need them. Using Work<T> to load dependencies lazily so they are only resolved when we really need them. Applying the [Admin] attribute for admin-related Getting to know an other Orchard service: IAuthorizer. Creating our own permissions by implementing the IPermissionProvider. Using the ContentManager so we can finally work with content items! Generating ad-hoc shapes and matching them to an actual template. Implementing the IResourceManifestProvider interface for managing static resources. Remember: if you have any questions don't hesitate to ask them by creating a new issue in the Orchard issue tracker with the "discussion" label. Make sure to prefix your thread's title with "Dojo Course - "! We keep an eye on these issues. Also follow us on Twitter to get notified about the latest Dojo Course news, including when a new tutorial is posted. Do you have some feedback about the course? Please send it in. Haven't you enrolled yet? Why not do it some time in the near future like right now?