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

Featured tags

IIS
API
SMS
SEO
All tags >

Media Profiles, Renamed SummaryAdmin shapes - This week in Orchard (16/10/2020)

Media profiles feature to Orchard Core that allows you to defined preset image resizing and formatting commands! Renamed SummaryAdmin shapes, and new routes to avoid features URL blocking by IIS, and a lot more in our current post! Orchard Core updates Prevent disabling or removing administrator role Let's say you set up your Orchard Core site using the admin as the user name and for some reason, you navigate to Security -> Users to disable your own account. The problem here is that in this case, you are the only user with an Administrator role in the system. From now you can't do that, you will get a warning message saying you cannot disable the only administrator. Go back and edit your own user again and try to edit the user name too. This also triggers a new validation error, because you cannot modify the user name of the currently logged-in user. The last thing here is about removing the Administrator role from your user account. You could do that, but if your user is the only user with the Administrator role assigned, you will get a warning message about you cannot remove the Administrator role from the only administrator. Avoid features URL blocking by IIS IIS has some default filters for security like you can't have specific words in the URL. There are a few words used by us too like .sitemap. IIS also blocks any request ending in .resources by default. The list of blocked extensions includes a bunch of other terms that could conceivably be used in feature IDs such as .master, .browser, .config, .skin, etc. It's possible to override this behavior in the web.config file but this would have to be done on a per-application basis and carries unwanted security implications. The solution is just to put these parts in a different segment. If you want to enable a feature the URL to do that was:https://localhost:5501/Admin/Features/Enable/OrchardCore.Sitemaps Now the new URL is:https://localhost:44300/Admin/Features/OrchardCore.Sitemaps/Enable So the goal of this fix is to use the pattern Admin/Features/{id}/Enable in place of Admin/Features/Enable/{id}. The same goes for when you want to disable a feature. Renamed SummaryAdmin shapes of ContentsDriver These shape names are not compatible when defining custom placement, so they have been renamed. They are admin shapes, so the impact is quite low. If you have your own custom theme and redefined these ones you have to change them. So, the ContentsDriver creates four shapes with different shape types. Shape("Contents_SummaryAdmin__Tags", new ContentItemViewModel(model)).Location("SummaryAdmin", "Tags:10"), Shape("Contents_SummaryAdmin__Meta", new ContentItemViewModel(model)).Location("SummaryAdmin", "Meta:20"), Shape("Contents_SummaryAdmin__Button__Edit", new ContentItemViewModel(model)).Location("SummaryAdmin", "Actions:10"), Shape("Contents_SummaryAdmin__Button__Actions", new ContentItemViewModel(model)).Location("SummaryAdmin", "ActionsMenu:10") However, the actual shape type is considered before __ i.e. all the above shapes are resolved to the same shape type Contents_SummaryAdmin. Renamed these shapes as following to apply a unique placement record for each shape. Contents_SummaryAdmin__Tags renamed to ContentsTags_SummaryAdminContents_SummaryAdmin__Meta renamed to ContentsMeta_SummaryAdminContents_SummaryAdmin__Button__Edit renamed to ContentsButtonEdit_SummaryAdminContents_SummaryAdmin__Button__Actions renamed to ContentsButtonActions_SummaryAdmin So that placement will target a single shape type. { "ContentsButtonActions_SummaryAdmin": [ { "shape":"ContentsButtonEditNoView_SummaryAdmin" } ] } Demos New ImageSharp.Web Features ImageSharp is a new, fully-featured, fully managed, cross-platform, 2D graphics library. Designed to simplify image processing, ImageSharp brings you an incredibly powerful yet beautifully simple API. With the v1.0., ImageSharp has got a bunch of new features and it's now a lot faster. And Orchard Core is also using ImageSharp to work with images. New features included: Format support to the Tag Helpers/Liquid Filters: The slight weirdness with adding this is the file extension on the URL will remain .png, but the image will be returned with the correct mime/type. Quality support to jpg encoding and Tag Helpers/Liquid Filters: The Quality support allows you to specify a quality % to jpg encoding. Note: only jpg encoding is supported, but the Format support allows you to convert an image from saying png to jpg, and then reduce the quality. CurrentCulture/InvariantCulture for query string parameters: Supported through custom ImageSharp configuration, but not integrated into Orchard Core. Basing this decision primarily on the idea that most of our resizing/processing query string building, is done through templates, which are culture invariant. And that's not all of it! There is now a new Media profiles feature in Orchard Core that allowing you to specify resizing options and much other stuff. A profile can then be called with the profile name resize_url: profile: 'banner' rather than having to specify all the resizing options that may apply. But that's enough talk for now, let's see them in action, after all, we are in the Demos section of This week in Orchard, right? Use the latest nightly build of Orchard Core and set up your site using the Agency recipe. Then navigate to the admin UI where you will see a new option in the menu (make sure to enable the Media profiles feature): Configuration -> Media -> Media Profiles. Media Profiles are quite simple, they just have the standard resizing options that we have in ImageSharp. Notice that here you can set the width and the height values only from the supported ones. We add the name md to this media profile, let's note it, we will need it right away. Now navigate to Design -> Templates and edit the predefined Content__LandingPage Liquid template. We will use the newly created image profile when displaying the portfolio images. Just a note here: the home page in this agency is a LandingPage content type that has several Bag Parts attached. The one with the display name Portfolio is about to add Project content types to your LandingPage content type. And the Project content type has a Media Field attached, called Image. In this Liquid template, we will use our newly created md media profile. Here we say use the md media profile when displaying these images and in this particular case we would like to override the resize mode for the processed image. Instead of crop, we would like to stretch these images, but just in this case. When you define a media profile, you can say I don't want to specify the width, the height or the resize mode. In that case, you can set them in your Liquid helper, just as you could do that before. Now, let's just check out how does the home page of our site looks like. Remember that we set a lot of values when setting up our md media profile and we also set the quality percentage for the processed image and we set it as 10. We also change the width and height values and override the resize mode to stretch the images. This result is low quality stretched images in the Portfolio section. Now let's see the source code of this page and check out the img tags using the DevTools of Chrome. As you can see it's not tied to ImageSharp, the logic just converts the media profile into a good query string. This means we can do the override easier and if we change the values the URL will change, and it breaks the cache. When you would like to show the kittens.jpg with 100 width and 100 height, by using the crop resize mode (that resizes the image using the same functionality as max then removes any image area falling outside the bounds of its container) and use only 50% as the quality when compressing the image you would write a Liquid filter like this: {{ 'animals/kittens.jpg' | asset_url | resize_url: width:100, height:240, mode:'crop', quality: 50, format:'jpg' }} The documentation is also updated to help you how to use these new arguments. Don't forget to head to YouTube and watch the recording of this awesome feature! News from the community Orchard Dojo Newsletter Lombiq's Orchard Dojo Newsletter has 162 subscribers! We have started this newsletter to inform the community around Orchard with the latest news about the platform. By subscribing to this newsletter, you will get an e-mail whenever a new post published to Orchard Dojo, including This week in Orchard of course. Do you know of other Orchard enthusiasts who you think would like to read our weekly articles? Tell them to subscribe here! If you are interested in more news around Orchard and the details of the topics above, don't forget to check out the recording of this week's Orchard meeting!

Distributed cache, YesSql improvements - This week in Orchard (09/10/2020)

Get ready for the upcoming additions of Orchard Core! This week you can see demos about adding distributed cache to Orchard Core and the latest improvements of YesSql! Orchard Core updates Restrict Content Types Admin Node to only create the specified content type Let's say you have a site set up with the Blog recipe and your goal is to add a new admin menu that is about to list all the existing Article content items. To do that you have to navigate to Configuration -> Admin Menu and click on the Add Node button. Here you will need to select the Content Types Admin Node because you would like to add a link for each one of the selected content types from the list. And yes, you will only select the Article content type in the next screen. And that's it, you have created a new admin menu that lists all of the Article content items from the system. If you click on that you will see the list of the Article content items. Note that from now you will not see a filter here to filter by content types because that really doesn't make much sense. You created this Content Types Admin Node to list only the Article content items. If you would like to filter by content type, use the filter in the Content -> Content Items page as you would do it before. Remove ManageOwnMedia permission The ManageOwnMedia permission isn't handled today and we can replace it with the ManageMedia permission. So, now there is no separate permission to manage their own media or manage the media. It will be added back to the system again if the authorization logic is to be able to separate the user's media and the media uploaded by others. Right now, if you head to Security -> Roles and hit the Edit button near one of the Roles, you will see the missing Manage Own Media permission. Use a dropdown menu on the admin top navbar for the user menu The user menu on the admin theme is just about listing the user name of the currently logged-in user with a little icon near it. And there was a Log off link at the right side of the user name. It was just a piece of HTML code in the Layout.cshtml file of the default admin theme. From now the whole user menu gets its own shape, called UserMenu.cshtml. If you would like to override the user menu, you don't need to create a Layout.cshtml file in your admin theme, you just need to override the UserMenu.cshtml file. And if you check out this GIF, you will see that now the content of the user menu is placed in a dropdown instead of having it's content inline. Document release procedure Orchard Core is open-source that means you can check out and request changes to the source code, tell your opinion about it, and update the relevant documentation for that piece of code. Now there is a new page in the Orchard Core Documentation about how to publish a new Orchard Core release. These notes are primarily for Orchard's core contributors to guide them on how to prepare a new release, but if you just take a look at these you can now see what are the steps that need to be done to be able to ship a new release of Orchard Core. Add option to allow Lucene query syntax in the search There is a setting in the Lucene module that you can turn on and whatever you type in the search box won't be parsed as 'these are the words that I need to search on', but parsed as this is a Lucene query. You can use the Lucene query syntax in search forms, like the quotes, plus signs and things like this. But by default, it will still be like today, which is type words and it looks for these words. If you type stuff that has weird characters, they would be ignored. But how can I turn on that feature? Just navigate to the admin UI of Orchard Core, then find the settings in Search -> Settings -> Search (make sure you have enabled the Lucene module). Demos YesSql: Adding support for multi filters on the same table index There is a new method on .IQuery called .Or(), which starts a filter on a distinct table. This can be used for instance when the same index needs to be queried for multiple sets. It will actually add many filters on the same record of the index. With .Or() you can do now filters on different inner joins of the same index. Which means it will do unions of result with the filters. Let's check out the following unit test. [Fact]public async Task ShouldQueryMultipleIndexes(){ // We should be able to query documents on multiple rows in an index. // This mean the same Index table needs to be JOINed. _store.RegisterIndexes<PersonIdentitiesIndexProvider>(); using (var session = _store.CreateSession()) { var hanselman = new Person { Firstname = "Scott", Lastname = "Hanselman" }; var guthrie = new Person { Firstname = "Scott", Lastname = "Guthrie" }; session.Save(hanselman); session.Save(guthrie); } using (var session = _store.CreateSession()) { Assert.Equal(2, await session.Query<Person>() .With<PersonIdentity>(x => x.Identity == "Hanselman") .Or() .With<PersonIdentity>(x => x.Identity == "Guthrie")) .CountAsync()); }} This PersonIdentitiesIndexProvider will just map the first name and the last name of each person. We created two persons here that means the provider will be creating four PersonIdentity records. Two to store the first name and last name for Scott Hanselman and two to store the first name and the last name of Scott Guthrie. If without using the .Or() it will issue a query where the Identity == "Hanselman" AND Identity == "Guthrie", which will return nothing. With the .Or(), it will do an inner join on PersonIdentity with a filter on Identity == "Hanselman" and another inner join on PersonIdentity with a filter on Identity == "Guthrie". In this case, we will get both the two persons. It's like give me any person who's PersonIdentity has a record like Hanselman OR where the PersonIdentity equals Guthrie. Let's see another example! // Creating articles.using (var session = store.CreateSession()){ session.Save(new Article { Content = "This is a green fox" }); session.Save(new Article { Content = "This is a yellow cat" }); session.Save(new Article { Content = "This is a pink elephant" }); session.Save(new Article { Content = "This is a green tiger" });}using (var session = store.CreateSession()){ Console.WriteLine("Boolean query: 'pink or tiger'"); var boolQuery = await session.Query<Article>() .Where(x => x.Word.IsIn(new[] { "pink" })) .Or() .Where(x => x.Word.IsIn(new[] { "tiger" })) .ListAsync();} This is a full-text sample where in this case we can query documents by their content, by their words. If we have the documents as you could see in the code, we are creating an index for all the words pointing to the document, like green and fox points to the first Article. Now the query is about to give me all the documents that have pink in it OR all the documents that have tiger in it. The goal is to get the last two articles in this case. Let's check out this query: var boolQuery = await session.Query<Article, ArticleByWord>().Where(a => a.Word.IsIn(new[] { "white", "fox", "pink" })).ListAsync(); This query will return all the articles that have white AND fox AND pink in it and there is none in this case. You can find the recording of this improvement on YouTube! But wait a minute! Could this syntax be better? When you have a query, you can say .Any() and every predicate will be done in a different table. .Any() being an OR, and .All() being an AND. In this case, we're querying on the same index (ArticleByWord) but each of the calls on .With() will be a different projection, a different inner join in this case. Here we are looking for an article that has the word pink OR the words green AND fox. await session.Query<Article>() .Any( x => x.With<ArticleByWord>(a => a.Word == "pink"), x => x.All( x => x.With<ArticleByWord>(a => a.Word == "green"), x => x.With<ArticleByWord>(a => a.Word == "fox"))).ListAsync(); SELECT DISTINCT Document.* FROM DocumentINNER JOIN ArticleByWord_Document AS [ArticleByWord_Document_a1] ON ArticleByWord_Document_a1.DocumentId = Document.IdINNER JOIN ArticleByWord AS [ArticleByWord_a1] ON [ArticleByWord_a1].Id = ArticleByWord_Document_a1.ArticleByWordIdINNER JOIN ArticleByWord_Document AS [ArticleByWord_Document_a2] ON ArticleByWord_Document_a2.DocumentId = Document.IdINNER JOIN ArticleByWord AS [ArticleByWord_a2] ON [ArticleByWord_a2].Id = ArticleByWord_Document_a2.ArticleByWordIdINNER JOIN ArticleByWord_Document AS [ArticleByWord_Document_a3] ON ArticleByWord_Document_a3.DocumentId = Document.IdINNER JOIN ArticleByWord AS [ArticleByWord_a3] ON [ArticleByWord_a3].Id = ArticleByWord_Document_a3.ArticleByWordIdWHERE ArticleByWord_a1.Word = 'pink' OR ( ArticleByWord_a2.Word = 'green' AND ArticleByWord_a3.Word = 'fox') Here you can also see how does the query look like. That's the current syntax right now. And it's not breaking change because if you had .query.With().With(), it will still behave the same as before. It will be a single projection with two .With(). If you project on the same table it will be an AND on the same table, the same projection.If you would like to know more about the current syntax and the latest features, this is the YouTube video that you are looking for! Distributed Redis Cache There is a huge PR with a great addition to Orchard Core about having Distributed Cache in Orchard Core. In fact, this PR is related to all modules services using cached data that need to be in sync with a shared database, e.g. site settings and other admin settings, templates, queries, layers, and so on. Currently, in the dev branch, this is already the case for most of them but by using local memory cache entries that are invalidated through a distributed signal. This PR has changed this pattern by using a multi-level cache including a distributed cache. And Jean-Thierry Kéchichian made more services to be distributed aware, there are remaining things but could be done in other PRs. And recently he added the ability through a separate feature to also keep in sync tenant states, when you enable/disable/create/setup a tenant. To summarize: All services that were using the memory cache are now using a multi-level cache including a distributed cache, this cache is kept in sync with the database without using a message bus but document identifiers. We have concrete implementations of distributed services based on Redis, Redis cache, Redis data protection, Redis message bus, and Redis lock. In the current code, we never use a message bus/distributed lock. When enabling a concrete distributed cache in the default tenant, we automatically keep all tenants in sync through a hosted service, here also without using a message bus but identifiers. Here a stateless configuration is needed. There is a separate feature (DefaultTenantOnly) to keep tenants in sync. Don't forget to head to YouTube and watch the recording of this upcoming feature! News from the community Orchard Dojo Newsletter Lombiq's Orchard Dojo Newsletter has 160 subscribers! We have started this newsletter to inform the community around Orchard with the latest news about the platform. By subscribing to this newsletter, you will get an e-mail whenever a new post published to Orchard Dojo, including This week in Orchard of course. Do you know of other Orchard enthusiasts who you think would like to read our weekly articles? Tell them to subscribe here! If you are interested in more news around Orchard and the details of the topics above, don't forget to check out the recording of this week's Orchard meeting!

Shape Tracing Helpful Extensions, Alt and Class attributes for the Image Shortcode - This week in Orchard (28/08/2020)

New guides in the Orchard Core documentation to learn how to build a blog that allows users to login with their AzureAD account and gets assigned roles based on the Security Groups they belong to, and how to create a Deployment Plan to migrate from the File Content Definition feature. After we will show you our new Shape Tracing Helpful Extensions feature! Orchard Core updates Content definition stores guide Now you can find a new small guide in the Orchard Core documentation that explains what the File Content Definition feature is, and how to create a Deployment Plan to migrate from the File Content Definition feature. Implement class and alt attributes for ImageShortCode Shortcodes are small pieces of code wrapped into [brackets] that can add some behavior to content editors, like embedding media files. The Image Shortcode can be used to display an image from the media library in your WYSIWYG editors. The simplest way to use that Shortcode is the following: You can also provide several attributes, like the width, height, and mode. And now you can also pass the alt attribute that specifies an alternate text for an image if the image cannot be displayed. And you can pass your custom classes too! In the following line we used the Image Shortcode with multiple parameters: Users with Manage Users permission can't delete themselves or change their roles If you try to delete the admin account and you are currently the admin what you could do is actually block everyone from being able to edit the site if the admin is the only user. The idea here is that you can't delete yourself. If you navigate to Security -> Users and edit the admin user, you will see that the editor of the roles and the Is enabled? checkbox are disabled. Don't Detach a document already loaded for update This is about how documents are loaded from cache stores. If you use the ASP.NET caching abstractions you can store in the IMemoryCache or in the IDistributedCache. The main difference between these two is that in the IDistributedCache you would put stuff that has to be and can be serialized. In IMemoryCache you can put stuff that is not serialized. It's a live object that can be changed and updated. There is a new method for documents in the ISessionHelper called GetForCachingAsync that gets a single document (or create a new one) for caching and that should not be updated, and a bool indicating if it can be cached, not if it has been already loaded for an update. Note that for full isolation, it needs to be used in pairs with the LoadForUpdateAsync method that loads a single document (or create a new one) for updating and that should not be cached. When you call the GetForCachingAsync method you say that the object that you want to load from the database will be cached, which means you should not change it. You should not be able to update it, it's for caching. When you get a document from the database from this layer it will tell you if you are allowed to change it or not. This way you know you can put it in a durable cache or a live cache. Use Azure AD as an external identity provider guide In order to authenticate users with AzureAD, you must enable and configure the OrchardCore.MicrosoftAuthentication.AzureAD (you can learn more about here) and the OrchardCore.Users.Registration features. There is a new guide in the documentation where you will learn to build a blog that allows users to login with their AzureAD account and gets assigned roles based on the Security Groups they belong to. Demos Shape Tracing Helpful Extensions Lombiq Shape Tracing Helpful Extensions adds a dump of metadata to the output about every shape. This will help you understand how a shape is displayed and how you can override it. But let' see how you can use it in your solution! Imagine you have a NuGet-based Orchard Core solution and you would like to use the Shape Tracing Helpful Extensions. For that, you have to clone or download the orchard-core-preview branch of the Helpful Extensions repository that is targeting a recent nightly build of Orchard Core and you will only find the Shape Tracing Helpful Extensions in that branch. Now head to the GitHub repository of the Helpful Libraries module (same branch) and clone or download that too. You will need this library to use the Helpful Extensions. Now add these as an existing project to your solution and don't forget to check the project reference between these two! Reference the Lombiq.HelpfulExtensions module in your Web project and now you are ready to go! Set up a site using the Blog recipe then navigate to Configuration -> Features and search for the word helpful. Here you can find all of the following independent extensions of the module. If you are interested in the other ones too, check out the Readme.MD file of the repository for more! Now we will enable the Shape Tracing Helpful Extensions - Lombiq Helpful Extension feature. After you will get a dump about shapes in the HTML output. Just view the page source where you will see several comments in the code. These are generated when the shape is displayed that gives you some basic debug data. You can use these to actually override the shape. If you navigate to the detail view of the built-in blog post, you will see every relevant data that could be important for you to override the given shape, check the display type, the position, the differentiator, the wrappers of the shape and many more! But that's not all about Shape Tracing Helpful Extensions! If you would like to see more, don't forget to check out this recording on YouTube! News from the community Orchard Nuggets: How to debug a NuGet-based Orchard Core solution? How can you debug Orchard Core code when you're working with a solution that loads Orchard packages from NuGet? Easily! In our newest Orchard Nuggets post, we give you the answer! Check out the other posts for more such bite-sized Orchard tips and let us know if you'd have another question! Orchard Core workshops The contributors of Orchard Core will hold some unique online workshops in September 2020. So even with Orchard Harvest postponed due to the coronavirus pandemic we'll get some new learning events. Are you looking to get up to speed with Orchard? Check out the workshops' details on the Orchard Core homepage! Orchard Dojo Newsletter Now we have 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!

User Impersonation, Export Content To Deployment Target - This week in Orchard (07/08/2020)

This week we are gonna show you three brand new features that are recently added to Orchard Core: the Add Content To Deployment Plan, the Export Content To Deployment Target, and View Or Download Content As JSON features. After we see a demo about user impersonation and finally we solve the mystery about what is GitHub Arctic Code Vault? Orchard Core updates Add Content To Deployment Plan, Export Content To Deployment Target, and View Or Download Content As JSON features Set up your site using the Blog recipe. Now you can head to Configuration -> Features and enable the Add Content To Deployment Plan, Export Content To Deployment Target, and View Or Download Content As JSON features. This will bring you several new stuff that you can use when you are managing the content items. If you click on the Actions button you can see that the context menu is now getting a lot more items. The Export to Deployment Target is about to automatically create a custom recipe file that can be downloaded locally or send it to a remote instance. You can use the Available Targets modal to select the destination. The Add to Deployment Plan is about to add a new content item step using this content item to an existing deployment plan. In this case, a new modal window will open again that lets you choose from the available deployment plans. The Download as JSON is about to directly download the recipe to your computer locally and the View as JSON is a very helpful feature because as you could see in the screen below it shows you the JSON representation of the content item. The same JSON will go to the content step of the recipe when you are hitting the Download as JSON button. Here you have the availability to copy the JSON structure by clicking on the copy icon at the top-right corner of the page. And don't forget that you can find two demos on YouTube about this feature. Click here for the Click to deploy demo and here to see the second part of the demo! Add authentication checks to some ISite drivers We had some drivers in Orchard Core where we hadn't check that the user has the appropriate permissions to modify the changes of given settings because the controllers won't do that for us. For example, if the user would like to change the settings of the reCAPTCHA, then we have to make sure that the user has the ManageReCaptchaSettings permission to do that. Now, these missings checks are added to the code. Fixing Linux setup by making sure a directory created before creating a file Let's say you would like to host your Orchard Core site in a Linux environment. But unfortunately, the setup failed on installation from Docker-Linux container. The strange issue was a directory needed to be created before file creation. Navigate to the SaveContentDefinitionAsync method of the FileContentDefinitionStore to see the check for the directory. Document HTML Sanitizer and Markdown Pipeline Options An HTML Sanitizer is available as part of the Orchard Core Infrastructure. The Sanitizer cleans user input that could lead to XSS attacks. From now you will find a new page in the Orchard Core Documentation about how to use the Sanitizer in your Razor view, how to configure the Sanitizer in the Startup classes, and much more. Markdown output is also sanitized during the rendering of content with Display Management. This page contains new sections about how to enable/disable or configure the Markdown Sanitization using the MarkdownPipelineOptions. Demos User impersonation Open GitHub in your browser and navigate to the OrchardCoreContrib.Modules repository. This repository contains a set of modules for Orchard Core CMS driven by the community members who love Orchard Core. Here we will focus on the one called Impersonation. That feature allows administrators to sign in with other user identities. To try this out, let's clone or download this repository then set up your site using a chosen recipe. After, navigate to Configuration -> Features and enable the Impersonation feature. To try out the impersonation, we need to have multiple users in the system. Go to Security -> Users and click on the Add User button to add a new one. In this case, we created a new user with the Author role with the author user name. In the users list, you will find a new green button called Impersonate. Here the Impersonate button is disabled for the admin user because we have already signed in with that user. So, click on that button near the user named author and see what will happen! You could notice a slightly changed admin UI in this case. The reason for that is quite simple: users with the Author role have access to the admin UI with some content and media library-related permissions. So in that case you can do and you can see what this exact user can see and can do in that site. It's a good way to for example test the permissions and the rights for that user. If you would like to end the impersonation and return your work using your account, you can just simply have to navigate to Security -> End Impersonation, that will do the trick for you. If you are interested in the full demo, head to YouTube for the recording! News from the community Orchard Core on GitHub Arctic Code Vault The GitHub Arctic Code Vault is a data repository preserved in the Arctic World Archive (AWA), a very-long-term archival facility 250 meters deep in the permafrost of an Arctic mountain. The archive is located in a decommissioned coal mine in the Svalbard archipelago, closer to the North Pole than the Arctic Circle. GitHub captured a snapshot of every active public repository on 02/02/2020 and preserved that data in the Arctic Code Vault. And why it is important? Because Orchard Core also sits in this Code Vault! If you have contributed a repository that is in the Code Vault you will see that in your GitHub profile! Check out this exciting video about the GitHub Arctic Code Vault! Lombiq Offline event Sometimes it's not just about work but doing something just for fun. These events are specifically for this: we get together, do something cool like breaking out of an escape room, going for a go-kart ride, or playing paintball. A few days ago we went hiking then we went back to Budapest in a boat. Check out this new picture of our team, shot at our Lombiq Offline event! While here in Hungary there are no restrictions on events like this anymore, we played it safe with a fully outdoor program. You can find this new picture on our About us page too! Orchard Core workshops The contributors of Orchard Core will hold some unique online workshops in September 2020. So even with Orchard Harvest postponed due to the coronavirus pandemic we'll get some new learning events. Are you looking to get up to speed with Orchard? Check out the workshops' details on the Orchard Core homepage! Orchard Dojo Newsletter Now we have 156 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!

OpenAPI, Swagger, Taxonomy Localization - This week in Orchard (12/06/2020)

This week we prepared with two new demos: the Taxonomy Localization and the Orchard Core OpenAPI Code Generation Tools based on NSwag! But before doing that, let's see the latest changes that will be added to the RC2 release of Orchard Core that is now really just a few days ahead! Orchard Core updates Refactor Blog recipe to have fewer required fields You may found that creating blog posts in Orchard Core using the Blog recipe could be not very user friendly. When you create a new blog post, you have to provide tags and select the category for the posts, however, you will also need to add a banner image for it. These are all required fields, without these, you cannot publish your post. But from now these fields are optional and the Markdown editor is just below the Title and the Permalink, so you don't need to scroll down to start typing your new exciting post! Add ConfirmationEmailSubject to RegisterUserTask When you are dealing with workflows you can find a task called Register User. This is about register a user from a form field, meaning that the activity is getting the request body as a form to get an IFormCollection and try to get the UserName and Email values from that. If everything goes fine, the task will register the user and if you edit the activity, you will find some more stuff to set up! Here you can say to send a confirmation email to the user with a given subject and you can also use a template for the confirmation email if you want! How to contribute to the Orchard Core documentation? Have you ever thought about contributing to the Orchard Core documentation, but you cannot find a line about how to do that? Well, here comes the good news! From now, you will find a new guide in the documentation that tells you everything that you need to know to add your great getting started guides, tutorials, and everything to the documentation! Thank you for doing that! Change content API permissions You want anonymous users to be able to view your site, view your page/content item and it would just show what the layout is or the view is. But you might not want anonymous users to retrieve the full content item JSON payload, because it might shows some properties and metadata that you don't want to expose. For that, you could use the custom permission called GetApiContent that you can assign to specific roles and this is not assigned to anonymous users by default. Now, this permission was renamed to AccessContentApi and protects all /api/content methods. If you don't want a user to see all the fields, just don't grant access to the APIs at all, hence the GetApiContent permission is not required as a separate one. This will also protect POST that currently returns the full content. And one more thing: the GetApiContent was already added to the Authenticated role. Now it's removed from that role as being authenticated should not grant access to all fields. Prevent array duplication when merging existing content When you do Merge using JSON.Net it will just merge the different arrays. In some cases, it's not what you want. If you want an array to be replaced (for example an array of tags) then it will just add a new tag to that array and not replacing the array with a new array. On the POST operation of the API, you just want to replace the value and the PATCH operation should be the one that merges different arrays in this case. So, the Content ApiController needs to use ArrayHandling.Replace when updating existing content, or array values are duplicated. Here you can see the changed code and here comes the UpdateJsonMergeSettings: private static readonly JsonMergeSettings UpdateJsonMergeSettings = new JsonMergeSettings { MergeArrayHandling = MergeArrayHandling.Replace }; Demos Taxonomy Localization Have you ever wondered how to localize your taxonomy terms in Orchard Core? Well, it could be hard to do it for the first time, but if you are watching the following recording you can get some tips and tricks to reach your goal faster! Orchard Core OpenAPI Code Generation Tools based on NSwag Head to GitHub and clone the master branch of the ThisNetWorks.OrchardCore.OpenApi repository. Make sure that the ThisNetWorks.OrchardCore.OpenApi.Sample project is your starting project then just simply build and run the solution. When setting up your site don't forget to use the Open API Sample recipe to enable the needed modules and theme. If you navigate to https://localhost:44300/swagger, you will see the endpoints that are available in Orchard Core and a sample controller named Foo that comes from the ThisNetWorks.OrchardCore.OpenApi.SampleModule module. Here you can make queries on them and now we will also get schemas that are generated using the NSwag toolchain! Let's check for example the BlogPostItemDto! Now we can use those! The samples folder contains a console client that you can use to try the endpoints. You can simply open the solution with Visual Studio (ThisNetWorks.OrchardCore.OpenApi.ConsoleClient.sln) and fire up the ThisNetWorks.OrchardCore.OpenApi.ConsoleClient project. This is about calling the endpoints by using a static HttpClient. Open the Program.cs file and check the first few lines of the Main method here. You could see that we are getting a content item by the 4qnhdhv3z54xk4fg4tdfke76c9 and we get the content of the content item in the FooTextItemDto object. The content item with the mentioned ID is a content item of the Foo text content type, which has got one Text Field attached, named Foo Field. Our client modifies the text of this field and making a POST request to send the updated data to Orchard Core. Now if you read back from the API you will get the updated content item with the new text in the Foo Field. But there is a lot more than that! You can see that you can get the RecentBlogPosts Lucene query and use the response data, or do other Lucene queries (like give me all the blog posts) and so on. If you are interested in it, there is also a TypeScript client (tsClient.ts) which has the same kind of classes and can be used directly from TypeScript. Of course, before doing that, you have to do the authentication, get the token, and so on. For that, you have to enable the OpenID module and configure it. It also comes with the recipe by default. The back-end, the Swagger is using Authorization Code Flow, and the console client is using Client Credentials Flow. The client app has a specific API role because it's relevant to just give very limited and specific access to the system. And that's not all of it! If you need more details about the project, don't forget to check the recording on YouTube! News from the community Orchard Nuggets: How to access services from another tenant in Orchard Core? Do you run a multi-tenant Orchard Core site? Have you ever wondered how you can cross tenant boundaries? We show you the code! Check out our latest Orchard Nugget post for more! Check out the other posts for more such bite-sized Orchard tips and let us know if you'd have another question! Updated Dojo library We've updated the famous Dojo Library to Orchard Core! Orchard Dojo is a portable package of coding and training guidelines, development utilities. Check out our updated library and start learning today! Orchard Core workshops The contributors of Orchard Core will hold some unique online workshops in the coming months, between May and September 2020. So even with Orchard Harvest postponed due to the coronavirus pandemic we'll get some new learning events. Lombiq's developers will also give two workshops, on using Orchard from the admin UI and on developing a module. Are you looking to get up to speed with Orchard? Check out the workshops' details on the Orchard Core homepage! Orchard Dojo Newsletter Now we have 146 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 - 12/20/2019

Custom parameters support in recipes, new Retrieve Content task, improved Roles UI, a new post about Orchard Core, demos about the Open Tags and the headless recipe for Orchard Core! Should I continue? Many news is waiting for you in our current post and for closing, we would like to show you some nice pics about our Christmas event! On Orchard Core Custom parameters support in recipes From now you can set custom parameters in the appsettings.json file that can be passed and used in a recipe. As you can see in the documentation, you can access a parameter value like [js: configuration('CustomParameterKey')]. For this, there is a new ConfigurationMethodProvider that receives the ShellSettings and retrieve the value to replace by ShellSettings.ShellConfiguration["CustomPropertyKey"]. Add version and target framework variables in .props Hisham Bin Ateya refactored the Dependencies.AspNetCore.props file and created a new variable named AspNetCoreTargetFramework, which contains netcoreapp3.0. Now when there will be updates on ASP.NET Core we just only need to pick this up more easily. This will simplify the process when we need to update the AspNetCore version. Here is a snippet from the Dependencies.AspNetCore.props file: <Project> <PropertyGroup> <AspNetCoreVersion>3.0.0</AspNetCoreVersion> <AspNetCoreTargetFramework>netcoreapp3.0</AspNetCoreTargetFramework> </PropertyGroup> <ItemGroup> <PackageManagement Include="Microsoft.AspNetCore.Authentication.AzureAD.UI" Version="$(AspNetCoreVersion)" /> <PackageManagement Include="Microsoft.AspNetCore.Authentication.Facebook" Version="$(AspNetCoreVersion)" /> <PackageManagement Include="Microsoft.AspNetCore.Authentication.Google" Version="$(AspNetCoreVersion)" /> ... </ItemGroup></Project> And here is a snippet from one of the modules where we use the AspNetCoreTargetFramework variable: <Project Sdk="Microsoft.NET.Sdk.Razor"> <PropertyGroup> <TargetFramework>$(AspNetCoreTargetFramework)</TargetFramework> <AddRazorSupportForMvc>true</AddRazorSupportForMvc> </PropertyGroup> ...</Project> New Retrieve Content workflow task There is a new task called Retrieve Content that tries and evaluates a content item ID from a JavaScript expression if provided. Let's see a sample workflow that has this new task in it. Here we have an HTTP Request Event as a start activity that creates a blog post that has a DisplayText: My blog post using the Create Content Task when someone invokes the URL with a GET method. The Create Content Task sets the WorkflowExecutionContext.CorrelationId (the correlation ID can be used to resume workflows that are associated with specific objects, such as content items) with the newly created content item's ID. As we mentioned, the Retrieve Content Task accepts a JavaScript expression, so here we used the correlationId() method to get the ID. The Retrieve Content Task returns the content item by it's ID and sets the WorkflowExecutionContext.LastResult with the retrieved content item. Now by adding a Notify Task, we can use a Liquid expression to display the DisplayText property of the newly created blog post content item. Finally, make a redirect to the admin page using an HTTP Redirect Task to see the displayed notification. Using custom admin URLs There is a new AdminOptions defined in the OrchardCore.Admin.Abstractions module. It tries to configure the prefix of the admin URL from the configuration and then it's creating a property called AdminUrlPrefix that is by default admin. You can change the prefix for all the admin pages. All you need to do is to add the following section to appsettings.json inside the section called OrchardCore: "OrchardCore.Admin": { "AdminUrlPrefix": "dashboard"} When you are creating a route to your AdminController, don't forget to change the route template of your controller to use this prefix like in the following snippet, which code can be found in the OrchardCore.AdminMenu module. public override void Configure(IApplicationBuilder builder, IEndpointRouteBuilder routes, IServiceProvider serviceProvider){ // Menu var menuControllerName = typeof(MenuController).ControllerName(); routes.MapAreaControllerRoute( name: "AdminMenuList", areaName: "OrchardCore.AdminMenu", pattern: _adminOptions.AdminUrlPrefix + "/AdminMenu/List", defaults: new { controller = menuControllerName, action = nameof(MenuController.List) } ); ...} Roles UI and default description We have role descriptions, but the default roles don't have any descriptions. This opens a great opportunity to improve the UI of the index and the edit pages of the Roles. In the index page, you can find the description of every role under its name and the Search box with a new UI. When you add a new role you can set its name and description. And when you edit an existing one, you can also edit its description. Here you can also find some hints about what is the difference between the Allow and Effective permissions. New post: Lucene, GraphQL and Orchard Core Sipke Schoorstra has published a nice article again in medium.com to guide people on how to implement Search using Orchard Core, Lucene and GraphQL. Read his interesting and easy to follow article about how to enable Lucene, set up a Lucene Query and consume the available APIs from Postman using Lucene and GraphQL, allowing us to use a consistent API from our applications. Demos Orchard Core headless recipe The idea of the headless recipe is to provide a recipe that sets up GraphQL, queries, and everything that has an API interface and restrict the interface down a little bit. The recipe has no home page, so when you set up your site using the recipe, you will see the login page first. And in the admin page, you will see only those options in the menu, that are related to the API interfaces. You can also watch a great detailed demo on YouTube about what will you get if you install your site using the headless recipe! Orchard Core Open Tags Last month you could see a great demo about how to work with tags using taxonomies in Orchard Core. Here we mentioned that when you add a taxonomy field to a content type with a Tags editor type and you type something in the field, you can't create a new tag that should be added to the list of tags, because that feature was under development that time. Now thanks to Dean Marcussen this is not an issue anymore. Let's see how he solved this problem! We have a site with the Blog recipe installed. Add a taxonomy field called Tags to the Blog Post content type using a Tags taxonomy with a Tag content type that has just a simple Title Part. Here use the Tags editor type with the Tags display mode. And here you could notice a new checkbox, called Open. As the hint says, if you put a tick here, you can create tags inline when editing or creating blog posts. Put a tick here and let's edit the predefined blog post! When typing something in the Tags editor and hit enter (or just click on it), you can add new tags to the Tags taxonomy and to this blog post as well. If you edit the Tags taxonomy using the dashboard you will see that the new tag has been created and the title of that tag is the value that we have just entered when editing the given blog post. If you checked the editor of the blog post well you could see that there is a section called Category with two radio buttons. But what are these for? The Category is also a taxonomy field added to the blog post with the standard editor and display mode. It uses the Categories taxonomy with the Category content type as the term. But this time the content type that is used as a term is not just about having a Title Part, but it also has a Text Field with an Icon picker editor. This means when you add Category term content types to the Categories taxonomy you can also set an icon for this term. And if you override this shape using a Liquid template or a Razor view, you can display the Font Awesome icon near the name of the term! You can also watch a nice demo on YouTube about the Open Tags for Orchard Core! On Lombiq Orchard Nuggets: How to use the same version of Orchard Core NuGet packages in every project across my solution? You have your own ASP.NET Core project that using Orchard Core NuGet packages, but every time when you update them you have to do it one-by-one across the whole solution? In our second Orchard Nuggets post, we show you a way how to update the packages easily! Check out the other posts for more such bite-sized Orchard tips and let us know if you'd have another question! Christmas in Lombiq Sometimes we do stuff. Together. Not (just) in front of computer screens. These are some usual events in Lombiq that are all announced and arranged in advance. We periodically have an event called RnDay: this is a few hours long event where we share with each other what we recently worked on and what we plan to do. E.g. if we recently finished a project then the project's team members demo what they've done. Last week we had our last RnDay for this year in the Loffice Budapest, which is a coworking office with an event space where we held this event. And at the end of the day, we visited a nearby restaurant to have dinner together. We would like to thank you all for reading our posts and making the Orchard community stronger together with us! We hope that we could give you valuable news and demos about the happenings around Orchard and Orchard Core from time to time by reading our posts and of course the This week in Orchard newsletter. We would like to wish everyone a Merry Christmas with some photos of our latest event! Orchard Dojo Newsletter Now we have 109 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!