Orchard Harvest 2017–Client-side components in Orchard
A client-side component is defined as a component that implements its rendering and behavior on the client, with server interactions going through some APIs.
Such components can be implemented in Orchard using a range of technologies from simple shape templates to full-blown parts and elements. A good compromise is layout snippets. Layout snippets can be implemented with a simple SomethingSnippet.cshtml file that can simply be dropped into the Views folder of a module, and is then available as a regular element in layouts. Snippets can also be associated with a manifest that specifies metadata such as toolbox icons, and also configurable fields.
Daniel showed how to use a shape table provider in his module to add an API URL onto his shape from site settings.
To manage client-side assets, he’s using Gulp. There’s a choice however to put the generated assets in source control or not. His preference is to keep them out: they don’t get stale, don’t need to be pushed on all modifications, it reduces noise and footprint. The downside is of course that developers wanting to modify the module need to install the tooling.
The component client assets are Handlebars templates, TypeScript, and scss, and they are bundled using Browserify. The corresponding tooling is brought in by a package.json file.
Things get a little more complicated when building Angular components, because of Angular routing, which happens purely on the client and integrates into browser navigation. That requires integration with Orchard server-side routing, which doesn’t work out of the box. The way to make it work is to use the routing features from the IDeliverable.Bits module to add a base URL tag to the page and tweak routing so Orchard can recognize that base URL as an Orchard route. The rest of the URL will be handled client-side by the Angular component to display the proper thing.
One last thing that is required is to prepare some data for the scripts to use, such as base paths. This is done by rendering those pieces of data into data-* attributes in the markup.