This Repo implements a simple website which shows a Hero image, generates a custom greeting, has a custom test
This is a repo which demonstrates the planned featureset of "Bundles 2.0" (Internal Name) - specifically a new Execution Engine for all Bundled Entities. In this README existing Buundles will be referred to as V1, and Bundles 2.0 will be abbreviated as V2.
Structural changes from V1 to V2
===
As opposed to V1 bundles, V2 Repos generally support arbitrary files inline with the Git Repo in any folder structure desired. This will allow for build processes (webpack, etc.) that may be run outside of expression to be included in the bundle to make sure they are self contained.
With that in mind, there are certain requirements for a proper V2 Bundle structure.
The `/xpr/` is where all "active" Expression objects live. This includes datasources, elements, SSJS, etc.
The `/web/` folder is intended to contain static files which can be served up at runtime directly from the filesystem.
Tree Overview:
```
/xpr/bundle.json manifest
/xpr/server_js/**/*.js SSJS files
/xpr/models/**/*.json JSON definitions for Dyanmic Data Models
/xpr/element/**/*.hbs HBS Templates
/xpr/element_config/**/*.json Match Folder layout of /element/ , maps datasources to their elements
```
Notable Features
===
Paths & Folder Structure
---
V2 Bundles normalize the handling of relative paths within bundle entities which cross reference each other, i.e. element configurations, datasources, and server js scripts. Within each "magic" top folder per type, you can organize code as makes sense for your application, and perform relative path resolution, and reference entities from other bundles.
For Example: The SSJS's `require` implementation supports arbitrary lookups within a folder structures. In this example, our scripts have been separated into logical groupings of `components` (scripts to populate data for Element rendering), `handlers` (scripts to be run in response to routes), `installer` (contains the install script) and `modules` - for housing library features which are Expression agnostic.
Installation & Planned APIs
---
V2 Bundles now explicitly point out an installer script which will be run as part of an Expression managed installation procedure. In the example you can see conceptualized a `custom_fields` helper, and a `bundle_settings` helper which is envisioned to create custom settings scoped per bundle, likely leveraging Expression's KeyValuePair storage system.
In addition, the installation procedure will automatically create any dynamic data models from the `models` folder within `xpr`.
Custom Routes
---
`/elementAjax/` is intended to be replaced with an explicit `routes` table set in the bundle manifest. Routes may route directly to `server_js` scripts (`handlers`), for JSON/REST style access. For rendering of AJAX elements for client-side runtime page assembly, routes can be pointed directly at an `element` to provide an HTML API.
We're moving from a "public by default" (i.e. `/elementAjax/`) model, to an explicit model. This will increase maintainability of the code, as the routes required by a particular bundle are explicitly defined and therefore discoverable by an unfamiliar developer who needs to do maintenance on a bundle.
### A Note on POST Handlers
At this juncture, it seems that in bundles V2 there is not a real requirement for POST handlers, as the developer can simpily make a virtual endpoint e.g. /postForm/ and post JSON directly to that. This simplifies the amount of "code objects" needed to produce the current post/posthandler behaviour.
SSJS Module / Processor Environment Changes
---
SSJS Modules (anything included from `require` or as a datasource `outputProcessor`) now have a consistent interface for exporting functionality, as processors are now handled the same way as modules.
```
//V1 Style Processor
// define a global function with the magic name "process"
function process(data) {
data = data.toUpper();
return data;
}
```
```
//V1 Style Module
module.exports.custom_function = function(args) {
}
```
Compare with V2, which uses the same interface for both:
```
//V2 Style Processor
exports.process = function(context) {
};
```
```
//V2 Style Module
exports.custom_function = function(args) {
};
```
Datasources
===
`contextName` has been eliminated. In experience, this option to remap the name at the datasource level mostly leads to confusion when renaming datasources, and adds an additional maintenance point for the developer and code-referencing lookup for the developer who is trying to figure out what {{HBS}} maps to which datasource. A replacement for this functionality is now exposed in `element_config` which allows you to remap the name of a datasource _per element_ rather than per datasource. This provides the developer with the ability to resolve collisions when integrating multiple bundles, or change inputs without having to modify the templates.
Datasource Imports
---
Datasources can import additional datasources into their context. See `template.json` and view the `import` block to see an example of how this is planned to work.
Script Sources
---
`"outputProcessors": [ ... ]` has been simplified to just `script`. If multiple (chained) processors are needed, best practice will be to do this directly in the javascript.
Cache TTL
---
The `cache` object is envisioned to provide control over a datasource caching layer to enable developer control over the cached behaviour of a specific datasource.
Elements
===
Elements are written the same way as in V1. The main change is in how Element Datasource bindings are handled, which are now handled through `element_config`.
Element Config
==
Element Configs are a "new" component, compared to V1.
Cache TTL
---
This setting is to illustrate intended support for rendered output caching. When set, Elements will cache their rendered output and not regenerate until a request occurs past the defined TTL window. Requests within the TTL window will bypass all compiling, datasource and SSJS execution, and simply serve up the cached content.
Bundle Settings
===
Included in this sample repo is the concept of bundle settings, managed external to the Bundle Repo itself.
Page Rendering Best Practices
===
The following diagram illustrates the intended flow from Expression to Browser
```
0. Entry Point . 1. Page Data / API Interaction . 2. Rendering proceeds. Portions of
. Should be Hoisted as close . primary Page Data context are
. as possible to the entry point . delegated to sub elements when
. and not spread across many . necessary to reduce complexity of
| .... | AJAX Bundle Routes to server_js and elements
| . . | <-------------
| .... |
| |
| ......... |
| ......... |
| ......... |
| |
|_________________|
```
Bundle Configuration
===
In the `/xpr/` folder, all bundles are required to include a `bundle.json` file which functions as a manifest for the larger Expression environment to be aware of what this bundle does.
```
{
"version" : "1.0",
"name" : "WidgetBrochure",
"author" : "Backbone Technology",
"description" : "A brochure about a widget where people can comment on how amazing the widget is",
"installer" : "installer/install",
"templates" : [
{ "element" : "template/template" }
],
"skins" : [ ],
"routes" : [
{
"uri" : "/add-testimonial/",
"method" : "POST",
"submissionType" : "json",
"handler" : "handlers/add-testimonial"
},
{
"uri" : "/get-testimonials/",
"method" : "GET",
"handler" : null,
"element" : "ajax/get_testimonials"
}
],
"js-packs" : [
{
"name" : "site-js",
"scripts": [
"js/widget_js.js",
"js/vendor/jquery-3.4.1.min.js"
]
}
]
}
```
(Installer) "installer"
---
Path to the install script in this bundle.
(Template) "templates"
---
List of elements to expose to the Expression UI for selection in the Section Editor
(Playlist Modules) "skins"
---
List of Skin definitions for use with Playlists 2.0
(Routing) "routes"
---
List of URI endpoints (which will be attached to the bundle's own namespace) to map to
Bundle Installation
---
`installer` in the bundle.json points to the location of a serverside javascript