Skip to content

Recursive resources #103

@pushred

Description

@pushred

Storyteller Editor allowed resources (and preprocessor functions) to be defined in partials, which enabled self-contained blocks that were portable, easily inserted into any page. IIRC, resources were fetched, preprocesser functions were run, and a template was rendered with the resulting context within each partial before it was inserted into the parent page. For any partials that relied on a preprocessor this could be quite slow, especially considering that a fresh V8 environment was instantiated for each preprocessor via therubyracer.

While Solidus views can be used both as pages and partials, any page configuration is ignored when views are inserted into pages as partials. If a partial has any dependencies on particular resources and anything else the context must be passed to the partial as an argument, scoped where appropriate.

For example, given this context:

{
    "resources": {
        “facebook": {
            ...
        }
    }
}

A partial that renders photos from a Facebook album would need to be inserted like this:

{{> photos resources.facebook.data }}

There’s definitely some merit to this approach, it’s evident what context partials have, and resources can be configured for the page. The downside is that if looking at the partial in isolation any API resource dependencies aren’t clear unless perhaps they are configured there for use as a page or comments are left. The resource must be setup manually regardless and can’t be updated centrally.

Reusability

The more significant downside is that this limitation doesn’t allow for the self-contained blocks we had in Storyteller. This isn’t so much of an issue within a single site, but we miss out on an opportunity with significant potential for enabling rapid development: reusing blocks across sites. Coupled with the versioning and distribution that npm/Git provide, we could reuse such blocks in the same way we do JS and CSS libraries.

Such blocks are essentially a more performant, highly customizable alternative to using iframes for such reuse. HTTP requests are kept to a minimum since the blocks depend upon assets in the parent site’s asset bundles. This also means the site’s assets can adjust CSS and interact with JS APIs as needed — iframes in contrast require serverside customization controllable via URL parameters.

Eventually Web Components will provide a better alternative altogether, but that’s still distant and doesn’t address API dependencies other than accessing them clientside. We should keep where those efforts are going in mind for our own solution however. CSS-Tricks has a good rundown of the details.

Recursive Resources

Here’s what a middleground between Storyteller Editor and Solidus might look like:

  • When rendering a page, we parse the configuration found in every partial and merge the resources with that of the parent page’s. If there are any name conflicts, any parents should win.
  • Since partials are currently handled by the express3-handlebars view engine we may need to take over partials, or at least parse and load any references ourselves prior to passing the template through the engine. It may be sufficiently malleable, and maybe addressed here: Intercepting Template Before Compile ericf/express-handlebars#39
  • Resources defined in this “flattened” configuration would be fetched at the same time, as if they were defined in the same view.
  • Preprocessors could be run in succession at this point, they should be referencing resources by name but we could run into some issues with duplication, overwritten data, etc. as the context is modified with each pass. This will have to be worked out amongst the blocks however.
  • There is a question of whether to spawn child processes for each preprocessor — multiplying the processes required for each page could be a problem.
  • For now, we support should be limited to 1 level deep to avoid things from getting out of hand. We should better understand the case for intra-block reusability before proceeding any further. I sense we’d be talking at an element level however, which is far more appropriate for Web Components.

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions