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

Featured tags

IIS
API
All tags >

4 ways to display something from your module nested within a page in Orchard Core - Orchard Core Nuggets

A common question during Orchard Core development, something that came up again recently, is how to display something within the context of an Orchard page when that piece of data comes from your module? How can you "inject" something into the Orchard layout when you want to display e.g. a list of products retrieved from an external API? There are a couple of ways to do this depending on what exactly you need. All are fairly straightforward so let's see a quick rundown! Creating a whole page from you module If you want a whole page served by just your module then it's really simple: Create a module, add a controller as you'd do in standard ASP.NET Core MVC, make an action produce a view and that's it! The view will be wrapped into the Orchard layout so the theme you've selected will be visible around it: The basic styling will be there, the header and menu, any widgets you have put onto layers... Our Training Demo module has a simple sample exactly for this, just check it out and you'll see what we're talking about. The above screenshot comes from our Open-Source Orchard Core Extensions solution BTW. Creating a widget Widgets (see official docs) are basically little boxes of content or other functionality that you can put anywhere on the site. For example, an infobox about the site, a search box, a recent articles box, a footer can all be widgets. You can use them in two ways: Add a widget to a content item with Flow Part: Flow Part can be used to build flexible layouts out of various widgets, including nesting them (like putting widgets into a Container Widget). When you set up Orchard with the built-in Agency recipe and theme then you'll get a Page content type that has Flow Part out of the box: You can get the same content type from our Helpful Extensions Orchard Core module too. Another option to use widgets is to put them onto a layer, a sort of container of widgets. There you can place the widget into a global zone, an area of the Orchard layout, like the header, footer, or sidebars. The widgets on a layer will be displayed whenever the layer rule of that layer matches (you can think of it as a logic expression producing a boolean value), like on every page except the home page or on every page but only for authenticated visitors. For more info check out the docs. OK, but how can you create a widget? A widget is just a content item whose content type has its stereotype set as "Widget". You can change this value from the admin from under Content / Content Definitions and also from code. So, basically, the task is to create a content part of yours that'll display the data you want to show from its driver, then create a widget content type where that part is attached. Seems like a lot? It isn't, check out the relevant content part development tutorial again from the Training Demo, including creating a widget. Injecting a shape into the layout This can be a lot easier than developing a widget but also less flexible to use. You can also write your own code in a template (like a cshtml Razor file) and inject that into the Orchard layout directly. You can see an example of injecting a shape in the Training Demo module too. Displaying a shape from a Liquid Widget The Liquid Widget is a widget that can render a piece of Liquid markup. While there is such a widget in the Agency theme and you can throw it together from the admin quickly too the Helpful Libraries module has it built-in as well. With this widget and Orchard's pretty advanced Liquid support you can of course just write Liquid directly. However, for more complex apps maintaining templates editable from the admin quickly becomes an issue so we'd recommend keeping code in your modules and themes. The good news is that once you have a piece of Razor code in a cshtml template (or Liquid in a .liquid template) then you can just display it from a Liquid Widget! For example, if you have a WeatherData.cshtml template fetching some weather information from an external API then you can display it from a Liquid Widget, and thus use it just as any widget with this little piece of code: {% shape "WeatherData" %} There's more to it, check out the docs on the shape Liquid tag. Conclusion Pretty much that's it. There are other ways too but these are the most straightforward and most flexible ones. Do you have another technique you'd like others to know? Add below in the comments! Did you like this post? It's part of our Orchard Core Nuggets series where we answer common Orchard questions, be it about user-facing features or developer-level issues. Check out the other posts for more such bite-sized Orchard Core tips and let us know if you have another question!

Writing an Orchard Owin middleware

So you heard about how fancy Owin is, with all of its loosely-coupled thingies? Well, it's now in Orchard: as you may have heard on this week's Community Meeting, you can now write Owin Middlewares in the Orchard-y way. Let's see how! We won't discuss how Owin works or what a middleware is, so if you don't know these yet, check out the linked meeting video. Also, make sure to grab the latest source from the 1.x branch of Orchard's repository because only the upcoming 1.9 version will have Owin support. First you'll need to get familiar with the IOwinMiddlewareProvider interface. Middleware providers are injected services that return a collection of OwinMiddlewareRegistration objects. The latter ones contain the actual middlewares, i.e. those delegates that will run when the Owin pipeline is executed. This all is where the magic happens: you need to implement IOwinMiddlewareProvider and inside your implementation create OwinMiddlewareRegistration instances. See the following example: public class OwinMiddleware : IOwinMiddlewareProvider { // Mostly you'll only need the WCA, see below why. private readonly IWorkContextAccessor _wca; // Or use Work<T> injections, also see below for the explanation. private readonly Work<ISiteService> _siteServiceWork; public ILogger Logger { get; set; } public OwinMiddleware( IWorkContextAccessor wca, Work<ISiteService> siteServiceWork) { _wca = wca; _siteServiceWork = siteServiceWork; Logger = NullLogger.Instance; } public IEnumerable<OwinMiddlewareRegistration> GetOwinMiddlewares() { return new[] { // Although we only construct a single OwinMiddlewareRegistration here, you could return multiple ones of course. new OwinMiddlewareRegistration { // The priority value decides the order of OwinMiddlewareRegistrations. I.e. "0" will run before "10", but registrations // without a priority value will run before the ones that have it set. // Note that this priority notation is the same as the one for shape placement (so you can e.g. use ":before"). Priority = "50", // This is the delegate that sets up middlewares. Configure = app => // This delegate is the actual middleware. // Make sure to add using Owin; otherwise you won't get why the following line won't compile. // The context is the Owin context, something similar to HttpContext; the next delegate is the next middleware // in the pipeline. // Note that you could write multiple configuration steps here, not just this one. app.Use(async (context, next) => { // Note that although your IOwinMiddlewareProvider behaves like an ordinay Orchard dependency, the middleware // delegate lives on its own and will run detached from the provider! Because of this you'll need to either // access the Work Context as we do here, or inject your dependencies as Work<TDependency> objects. If you // build multiple middlewares with many dependencies here, doing the following is a better choice. var workContext = _wca.GetContext(); // But this would be an alternative: var siteSettings = _siteServiceWork.Value.GetSiteSettings(); var clock = workContext.Resolve<IClock>(); var requestStart = clock.UtcNow; // We let the next middleware run, but this is not mandatory: if this middleware would return a cached page // for example then we could just leave this out. await next.Invoke(); // Think twice when wrapping this call into a try-catch: here you'd catch all exceptions that would normally // result in a 404 or an 503, so it's maybe better to always let them bubble up. But keep in mind that any // uncaught exception here in your code will result in a YSOD. var requestDuration = clock.UtcNow - requestStart; // No need to use the ugly HttpContext, because we have OwinContext! var url = context.Request.Uri; // OK, but what if we _really_ need something from HttpContext? if (context.Environment.ContainsKey("System.Web.HttpContextBase")) // This is Orchard, so should be true... { var httpContext = context.Environment["System.Web.HttpContextBase"] as System.Web.HttpContextBase; if (httpContext != null) { // Voilá, we have the ugly HttpContext again! Like RouteData: var routeDataValues = httpContext.Request.RequestContext.RouteData.Values; // ...you know what to do. } } Logger.Information("The request to " + url + " on the site " + siteSettings.SiteName + " had taken " + requestDuration + "time."); // You see, we've done something useful! }) } }; } } Oh, and you'll see inline documentation for all the Owin interfaces :-). Also this sample will be part of the Training Demo module. Happy Owin'!

Forum favourites: records, database indices and about the necessity of drivers

Forum topics from the Orchard discussion board that we found interesting: "Record persisting advices": checklist if you want to store something in a low-level (non-content part) record "Adding empty part to type fails": always create a driver for your part "Records only in Models namespace: good?": remember to put your records under the Models namespace "Indices with SchemaBuilder": you can add database indices from migrations, but only from AlterTable

Forum favourites: model editors with shapes, accessing a shape's generated html and accessing content fields programmatically

Forum topics from the Orchard discussion board that we found interesting: "Passing my own data types to a view": using form field html helpers with dynamic models and in alternates defined with the shape attribute "Dynamically built html with Clay": capturing the generated html coming from a shape "How to access fields of a content item again?": ways of accessing a content field's value by using dynamic or statically typed extension methods

A small Orchard API reference: Orchard Cheatsheet

The Orchard Cheatsheet is a nice little API reference for some lesser known objects, made by Orchard's lead developer, Sebastien Ros. The cheatsheet's list only contains elements of the API that are accessible from (sometimes very specific) shape templates (well, ExtensionDescriptor seems to be an exception), but e.g. WorkContext is something you definitely encounter elsewhere too.

Orchard extensibility explained - aka why Orchard's flexible content model rocks

Bertrand Le Roy's not-so-recent article "Orchard Extensibility" in MSDN Magazine explains the various aspects of - surprise - extending Orchard. The article mainly covers Orchard's content model, its concepts and flexibility: something we all love in Orchard. Bertrand also lists some other important parts of the Orchard API, all worth knowing.

"Writing an Orchard Webshop Module from scratch" module development tutorial

"Writing an Orchard Webshop Module from scratch" is an excellent, 11-part (planned for 15) tutorial on Orchard module development by Sipke Schoorstra. Everyone who has ever written at least a short tutorial will feel what amount of work such a series contains: not surprisingly it's well worth reading, even for ones already somewhat familiar with Orchard module development.