Skip to content

View composers #2907

Open
Open
@tremby

Description

@tremby

I posted on Stack Overflow today with a question about whether Express provides any way to automatically have data calculated and provided to a view context, per view. Apparently not. The feature is known as a "view composer" in Laravel.

The use case would be for things like data needed in every page view using a particular layout -- instead of including the same function call to get the data in every res.render call in every route which calls a view using that layout, and remembering to add it to new routes each time, add the data to the view composer associated with the layout view containing the widget in question. Or for a widget in a view partial used sporadically across the site which requires some database lookup or other calculation, that calculation is done in the view's composer rather than the developer having to remember which pages have the widget and which don't, and having the calculation or reference to it in all of the relevant route files. And remembering to remove that from the view context if the widget is removed.

It's also nice in the case where the views and the business logic are written by different people, like when the designer is the front end developer. The designer may decide to add or remove such a widget at some point, and now the relevant data is calculated and available, or no longer calculated when no longer needed, without the route having to be edited.

I'm wondering if this is a feature others would be interested in, and how feasible it might be. Since there are myriad view engines for Express, and presumably they all handle partials and layouts in different ways, I expect this would work as a pre-render callback which is registered through Express.

That is, the developer writes something like:

app.set('view engine', 'twig');
app.set('view composer', function (view, context) {
  // Whatever logic the developer wants, given the view name
  // (or filename/path?), adding to or transforming the context
  // such as this trivial example...
  switch (view) {
    case 'layout':
      context.loggedIn = auth.isUserLoggedIn();
      break;
    case 'widgets/date':
      context.date = new Date();
      break;
  }
});

This callback would then be called (at the responsibility of the view engine, presumably) at some point before each view file is rendered. The context can therefore be added to, with whatever data the view needs.

Obviously with suitable logic the developer could break these out into separate files to keep things organized.

Or alternatively there could be a standard for an event fired at an equivalent suitable time, and with similar arguments, which could be listened for by the developer.

Any thoughts?

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions