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

Featured tags

IIS
API
All tags >

Leverage CSPROJ meta information, Lombiq Helpful Libraries - Navigation for Orchard Core - This week in Orchard (29/04/2022)

Adding an AppSetting option to disable SQLite connection pooling, leveraging your CSPROJ meta information and news and updates around the Lombiq Helpful Libraries! Check out our current post to read about the details! Orchard Core updates Remove Lucene from built-in recipes This is about making the built-in setup recipes lightweight: Lucene is a feature that you don't need on every site, especially due to it storing files on the local file system that need to be preserved (i.e., not temp files) it needs special considerations for hosting (you need to take care of those files when moving the app between environments and doing deployments). The goal here is to not enable Lucene by default in the following recipes: Headless: just remove it. Blank: just remove it. Blog: Create an SQL RecentBlogPosts Query and don't enable Lucene by default. Have a separate, non-setup recipe to set up the search just for a frontend search page (i.e., 90% of what happens related to Lucene in the recipe now). Have a second non-setup recipe that runs the previous one and also swaps out RecentBlogPosts with a Lucene Query. And from now you can find two new optional recipes in the TheBlogTheme: Lucene Query Recipe: this recipe runs the Blog Lucene Search recipe and as an example, the recipe replaces the RecentBlogPosts SQL query with a Lucene query. Lucene Search Recipe: this recipe enables the Lucene feature and creates the Search setting, Lucene indices, and permissions. The Recipes and Starter Themes page of the Orchard Core documentation has also been updated to reflect these changes. Leverage CSPROJ meta information Out of the box, a Manifest.cs file is generated, which includes the ModuleAttribute, FeatureAttribute, ThemeAttribute, and so forth, that describe the Orchard Core meta-information about your projects. However, let's say you want to connect available meta properties at the CSPROJ level, i.e., such properties as $(MSBuildProjectName), $(AssemblyVersion), $(PackageTags), to name a few. At its core, you may want to follow a pattern similar to InternalsVisibleTo, i.e. <ItemGroup> <AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleTo"> <_Parameter1>Test.$(MSBuildProjectName)</_Parameter1> </AssemblyAttribute></ItemGroup> The principles are the same, but in prior versions, the attribute constructors were not available to lean into. Michael W Powell also decided to provide helpful MSBuild Items as a more accessible, self-documenting shorthand input. From now, you can connect available meta properties at the CSPROJ level by leveraging CSPROJ meta information. If you are interested in how to leverage Orchard Core CSPROJ item lists and properties to enrich and get the absolute most from your authoring experience, this is the page you should take a look at! News from the community Lombiq Helpful Libraries - Navigation for Orchard Core The Lombiq Helpful Libraries contains various useful libraries that can be handy when developing for .NET, ASP.NET Core, and Orchard Core, to be used for your own projects. This time we would like to show you two helpful abstract classes: the NavigationProviderBase and the MainMenuNavigationProviderBase. NavigationProviderBase: an abstract base class for creating reducing boilerplate in INavigationProvider for checking the name parameter and if the user is authenticated. MainMenuNavigationProviderBase: an abstract base class derived from NavigationProviderBase for creating a home page menu structure using the main navigation name. If you use the Lombiq.BaseTheme automatically displays the generated menu as a widget in the Navigation zone. There is a Lombiq.HelpfulLibraries.Samples project for various examples in the form of an Orchard Core module. And that project contains a class called HelpfulLibrariesNavigationProvider. This class inherits the MainMenuNavigationProviderBase, which overrides the NavigationName with the "main" value. And if you check out the sample code here, you can see some other interesting stuff, like how we set up where to navigate users when they click on the given menu items. .ActionTask<LinqToDbSamplesController>(context, controller => controller.SimpleQuery())) In this case, we say that let's navigate the user to the SimpleQuery action of the LinqToDbSamplesController. And of course, you have the option to provide additional arguments as well if you check out the NavigationItemBuilderExtensions static class. Orchard Dojo Newsletter Lombiq's Orchard Dojo Newsletter has 247 subscribers! We have started this newsletter to inform the community around Orchard with the latest news about the platform. By subscribing to this newsletter, you will get an e-mail whenever a new post is published to Orchard Dojo, including This week in Orchard of course. Do you know of other Orchard enthusiasts who you think would like to read our weekly articles? Tell them to subscribe here! If you are interested in more news around Orchard and the details of the topics above, don't forget to check out the recording of this Orchard meeting!

Checking your infoset data consistency after upgrading from 1.x to 1.8+

Many Orchard developers, including ourselves act as early adopters of the Orchard source and use the code from the 1.x and other work-in-progress branches. While it gives us the opportunity to try the new features and get the latest bugfixes, some changes introduce important bugs every now and then. That was the case lately on the 1.x branch, when a problem surfaced regarding the infoset storage: for shifted, versionable content parts the infoset data was not saved in the ContentItemVersionRecord table, but into the ContentItemRecord table instead. Sébastien discovered this issue before 1.8 release and provided a method to fix it. At this moment, we are in the middle of upgrading all our sites to Orchard 1.8+ (+ means we are running 1.x, of course) and after careful testing in our local and staging environments we'll soon hit the big red button to make it go live: every Lombiq-related website will run on the latest source, that includes every DotNest tenant too! While upgrading your sites and testing the fix for the infoset storage, you may need to check if your data was really restored to its desired state, so here's a little help: below is an SQL-script that you can run against your DB, which checks if there's any corrupted infoset entry left, so you can verify if the upgrade mechanism worked. USE [MyDatabase]GOSELECT Item.Id AS ItemId, VersionItem.Id AS VersionItemId FROM [dbo].[MyPrefix_Orchard_Framework_ContentItemRecord] AS Item INNER JOIN [dbo].[MyPrefix_Orchard_Framework_ContentItemVersionRecord] AS VersionItem ON Item.Id = VersionItem.ContentItemRecord_id WHERE VersionItem.Latest = 1 AND VersionItem.Data IS NULL AND Item.Data IS NOT NULL ORDER BY Item.IdGO Happy upgrading!

Advanced Orchard: accessing other tenants' services

Many using Orchard's multi-tenancy feature sooner or later want to share data between tenants or generally, execute some operations on other tenants from one tenant. This is possible! Let's see how. First some core Orchard fundamentals: Orchard creates so called shells for tenants. These shells describe that sub-application what a tenant is, among others the shell also has its own Autofac IoC container. This container deals with all the dependencies that are injected or otherwise requested. The interesting thing is that you can access the shell - the shell context - of all running tenants and through it also their IoC container. Now if you have the container you can make dependency resolution calls on it - what means that you can resolve services from that shell, i.e. that tenant. public class TenantAccessDemo { // ShellSettingsManager lets you access the shell settings of all the tenants. private readonly IShellSettingsManager _shellSettingsManager; // OrchardHost is the very core Orchard service running the environment. private readonly IOrchardHost _orchardHost; public TenantAccessDemo(IShellSettingsManager shellSettingsManager, IOrchardHost orchardHost) { _shellSettingsManager = shellSettingsManager; _orchardHost = orchardHost; } public void UseServicesFromTenant() { // Fetching the shell settings for a tenant. This is more efficient if you have many tenants with the Lombiq Hosting Suite, // see below. var tenantShellSettings = _shellSettingsManager.LoadSettings().Where(settings => settings.Name == "TenantName").Single(); var shellContext = _orchardHost.GetShellContext(tenantShellSettings); // Creating a new work context to run our code. Resolve() needs using Autofac; using (var wc = shellContext.LifetimeScope.Resolve<IWorkContextAccessor>().CreateWorkContextScope()) { // You can resolve services from the tenant that you would normally inject through the constructor. var tenantSiteName = wc.Resolve<ISiteService>().GetSiteSettings().SiteName; // ... } } } If you're operating a multi-tenant environment you may also want to look at the Lombiq Hosting Suite: among others it has a Maintenance feature that you can use to run code in the context of tenants in a safe and scheduled way. Also it has an extended ShellSettingsManager that stores shell settings in the database: this means you can have any number of tenants, you can even fetch their settings by name or you can page when listing them and you don't have to take care about all the Settings.txt files in App_Data.