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

Featured tags

IIS
API
All tags >

How to migrate an Orchard 1 application to Orchard Core

How long have you been using Orchard 1 for your website? How satisfied are you with its features and performance? Have you encountered any limitations or challenges with Orchard 1 that you hope to address? If you are looking for a modern and improved version of Orchard 1, you might want to consider migrating to Orchard Core which is a better version of Orchard 1 in many aspects. Orchard Core is not just a port of Orchard 1, but a new and improved system that offers many benefits over its predecessor. What are the benefits of migrating to Orchard Core? You can enjoy numerous remarkable benefits by migrating to Orchard Core. First of all: Performance. As the saying goes: “The faster the better.” Orchard Core is so fast that an output cache module like for Orchard 1 is not required. For example, you can set up a site with the blog recipe in less than half the time that Orchard 1 needs for the same task. It is portable: it can run on Windows, Linux, and macOS, as well as on Docker containers. It has a more flexible and extensible modular framework that allows building modular and multi-tenant applications more easily. Orchard Core also supports NuGet packages for modules and themes, thus creating a new website with it is actually as simple as referencing a single meta package from the NuGet gallery. It is built on ASP.NET Core. This means that it can use any C# language version without any limitations, while Orchard 1 uses .NET Framework 4.8 which means it’s restricted to C# 7.3. It has new features that are not available in Orchard 1, such as GraphQL API, OpenID Connect, Liquid templates support, and more. It supports all major site building strategies: Full CMS, Decupled CMS, Headless CMS. This is just the tip of the iceberg, to read more about Orchard Core check out its documentation. Preparations The first thing to know is that there is no easy or fully automated way to migrate your website and content. The two systems are different in terms of data schema, modules, themes, and features. However, in general, we can say, that proficiency in Orchard 1 puts you in a good position to develop in Orchard Core too. There are a lot of similarities for example menu points on the admin UI, or how migrations work, etc. A good first step would be to take a look at your current application. Do you want to replicate what you have there, or do you also want to improve it? Migration is a good opportunity to renew your site, change design, and functionality, get rid of obsolete elements on the site, etc. You'll also need to know Orchard Core before attempting a migration. If you are new to Orchard Core development, we recommend that you start with our Dojo Course 3 - the full Orchard Core tutorial. This course covers the fundamentals of Orchard Core for both users and developers. New CMS, familiar features Before starting the migration, it is recommended to check your most used, most important features in Orchard 1 and list them. There is a good chance that there is an equivalent feature in Orchard Core, but it changed and has been upgraded, so you will need to do some research. For example, if you want to migrate your custom form, instead of Orchard.DynamicForms you can use OrchardCore.Forms to achieve the same result. Or instead of Orchard.Taxonomies you can use OrchardCore.Taxonomies. The Workflows and Audit Trail modules were ported to Orchard Core and improved too. Migrating content types Content types are composed of content parts and fields, which provide different functionalities and data types for your content. If you want to migrate your content types, you will need to recreate them in the new system. Luckily, as with features most of Orchard 1 content parts and fields have their equivalent in Orchard Core. Some examples are BooleanField, NumericField, TitlePart, or CommonPart. In this case, you can recreate your content type from the admin UI, from a recipe, or with a migration. Let’s say you have a BlogPost content type in Orchard 1, which has the following parts and fields: TitlePart: Provides a title for the blog post. AutoroutePart: Provides a URL for the blog post. BodyPart: Provides a rich text editor for the blog post content. MediaLibraryPickerField: Provides a way to select an index image for the blog post. Now take a look at what we have in Orchard Core. We have TitlePart and AutoroutePart in Orchard Core too, so that is handy, but there is no BodyPart and MediaLibraryPickerField. But after some research, we can find the equivalent of them: HtmlBodyPart and MediaField. We have all the parts and fields in the new CMS to recreate the BlogPost content type. In this example, we are creating it with the help of a migration file BlogPostMigration.cs: using OrchardCore.Autoroute.Models; using OrchardCore.ContentManagement.Metadata; using OrchardCore.ContentManagement.Metadata.Settings; using OrchardCore.Data.Migration; using OrchardCore.Html.Models; using OrchardCore.Media.Settings; using OrchardCore.Title.Models; namespace MyProject.Migrations; public class BlogPostMigration : DataMigration { private readonly IContentDefinitionManager _contentDefinitionManager; public BlogPostMigration(IContentDefinitionManager contentDefinitionManager) => _contentDefinitionManager = contentDefinitionManager; public int Create() { // Define a part called BlogPost with some fields. _contentDefinitionManager.AlterPartDefinition("BlogPost", part => part .WithField("Image", field => field .WithDisplayName("Index Image") .WithPosition("0") .WithSettings(new MediaFieldSettings { Multiple = false, })) ); // Define a type called BlogPost with some parts. _contentDefinitionManager.AlterTypeDefinition("BlogPost", type => type .DisplayedAs("Blog Post") .Creatable() .Listable() .Draftable() .Versionable() .Securable() // Add the Title part to provide a title for the blog post. .WithPart(nameof(TitlePart), part => part .WithPosition("0")) // Add the BlogPost part to provide some fields for the blog post. .WithPart("BlogPost", part => part .WithPosition("1")) // Add Autoroute part and configure it to use a pattern based on the title. .WithPart(nameof(AutoroutePart), part => part .WithPosition("2") .WithSettings(new AutoroutePartSettings { Pattern = "{{ ContentItem | display_text | slugify }}", })) // Add the HTMLBody part to provide a rich text editor for the blog post content. .WithPart(nameof(HtmlBodyPart), part => part .WithPosition("3") .WithEditor("Wysiwyg")) ); return 1; } } …and don’t forget to add your migration to the Startup.cs file to register it. However, if you have a content type with custom fields and parts, with custom functionality, and features, you will also have to recreate those fields and parts by reimplementing your custom code in the new project. Migrating content items The best way to add numerous content items is with a recipe. To migrate the content items, first, make sure that you have the content type created in the new system. After that, you will need to export your content items. The file formats of the recipes are different in the new CMS: Orchard 1 uses XML, while Orchard Core uses JSON, however, their functionality and use cases are similar. You will need to create an Orchard Core recipe: This can be done either manually, or Lombiq has a feature for this in the open-source Helpful Extensions module called Lombiq Helpful Extensions - Orchard 1 Recipe Migration. It has built-in functionality for content items with the most used content parts, but you can extend the built-in functionality to support more parts. Conclusion Migrating from Orchard 1 to Orchard Core is a challenging but rewarding process that can bring many benefits to your site. However, it requires careful planning, preparation, and testing to ensure a smooth transition. We have extensive experience and expertise in migrating sites from Orchard 1 to Orchard Core, and we can help you migrate your project. Lombiq has recently renewed and migrated its main site http://lombiq.com to Orchard Core too, and we are very happy with the results. You can check out our site and see how Orchard Core can power your site too. Happy migrating!

This week in Orchard - 08/30/2019

Let's start our post with a new contribution from Lombiq about back-porting Orchard Core's Live Preview feature to Orchard 1.x. Then read about two demos of Orchard Core's upcoming huge features: the Azure Blob Storage as CDN and about supporting custom Lucene analyzers! We also have other updates around our house as well. Check out our current post for more! On Orchard 1.x Demos Live preview feature A new Orchard module is available in Orchard 1.x, called Content Preview. This is the back-port of the Live Content Preview feature that you can meet within Orchard Core. To use the Content Preview feature, head to the Modules menu from the admin and enable the module. The main concept is the user wants to see the changes of a content item immediately somehow without needing to save the changes. Here you can see a Page content type with several parts attached. Here you can update the TitlePart, the BodyPart, and the LayoutPart too with a TextField and a NumericField. You can also have more than one TinyMCE editor in the editor of the content item, it will work without issues. If you edit a content item with invalid data (for example typing some text in the editor of a NumericField), you will see the error notification immediately in the preview window. In the live preview window, you can find a warning message: "The Content Preview feature doesn't support properties where there are relationships to ContentPartRecord (e.g. Taxonomies, Tags). These won't update in the preview windows but otherwise, keep working." You can see this message because this feature hasn't been implemented yet, but feel free to have a contribution and add this feature to the Content Preview in Orchard 1.x! Thank you for the contribution to Milán Keszthelyi from Lombiq Technologies! On Orchard Core Add more detail step on README.md of OpenId In the documentation, there are more steps about how to add the relevant identity of OpenId when using MMC.exe. New Orchard Core collaborators & teams in GitHub There is a new OrchardCore Devs team in the GitHub repository of Orchard Core. The members of this team now have wright access to the repository, they can merge PRs, create and delete branches, but can't merge to master. They contributed enough and with good quality that we can trust them now. They learned how to contribute to Orchard. :) Demos Azure Blob Storage as CDN We don't want to serve the Azure Blobs directly by rendering their own URLs that points to their Blobs. So, the clients load the Azure Blob directly and not us. We want Orchard to load the Blob, save it locally on the server and we serve the file directly. This file, which is copied locally from the Blob Storage is what we call the Media Cache. We do that because if we want an actual cache, that the clients don't ask us to serve a file, we will use a CDN which Azure Blob Storage is not and by doing that we can process the files to resize them if they are to be resized by ImageSharp. So, there are two things to solve here. For example, if you would like to show an image on your page with three different sizes, there are three requests coming for the same image with different sizes. But there is only one Blob on Azure. You just send one request to Azure to get the file, store it locally and then resize it to the three different pipelines and serve the three different files, which are cached by ImageSharp also. There is a cache of the Blob file in the Media Cache, and there is three cached, resized images from ImageSharp. This Purge Media Cache button under the Configuration -> Media Cache section is responsible for delete the Media Cache, not the ImageSharp cache. This feature is still under development. Supporting custom Lucene analyzers and additional Lucene indexes settings In the Lucene Indices settings page, you can now have an Edit button for each index. If you click on Edit, you can set the content types and also have an option to index a draft version of the content item. Before - by default - it was indexing everything, not just the ones we want. And - by default -, it was only indexing the published versions, without an option to index draft. If it's checked, it will still index one content item, but the latest version. When we index and tokenize the text, we need to tokenize based on the language. Using the Analyzer Name select list you can provide different language analyzers for each index. If the text of these items will be French, then you can use a French analyzer. This feature is still under development. On Lombiq Improving your employment security with Orchard Did you know that the Employment Security Department of Washington State also uses Orchard? Well, they do and thanks to them we've back-ported the Orchard Core live content preview feature to 1.x! See our post about it: https://lombiq.com/blog/improving-your-employment-security-with-orchard Migrate from Bitbucket Mercurial repositories to Git - we can help! Do you need help after Bitbucket dropping Mercurial support? If you want to move to Git, check out this page in our website about what are your options now. We've been doing hg-git conversion for six years! Orchard Dojo Newsletter Now we have 92 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!

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!