cjss-group / CJSS

A CSS based web framework
https://cjss.js.org/
MIT License
670 stars 20 forks source link

Allow for Javascript to modify data #26

Closed c-harding closed 5 years ago

c-harding commented 5 years ago

At the moment, JavaScript is evaluated after the HTML. This means that the data, which is restricted to being just an object and only modifiable by interpolation in the HTML, is fairly inflexible. This is a proposal to add two build steps: one before the html build and one after the html.

My proposed naming for this would be --pre-render and --post-render, with the --html tag renamed --contents. --js would remain a synonym for --post-render. To allow for multi-language usage (#14), the language could then be treated as a function to the css body. For example:

--data: json(
  name: ["one", "two", "three"],
);
--pre-render: js(
  data.link = data.name.map(n => `#${n}`);
);
--contents: html(
  <a class="item" href="${data.link[0]}">${data.name[0]}</a>
  <a class="item" href="${data.link[1]}">${data.name[1]}</a>
  <a class="item" href="${data.link[2]}">${data.name[2]}</a>
);
--post-render: js(console.log(data));

This would require a separate copy of the data for each element, rather than just one for all elements in the selector.

c-harding commented 5 years ago

The language flag would be optional to maintain backwards compatibility

c-harding commented 5 years ago

The return value of the --pre-render stage could be used as the new data attribute, if present.

c-harding commented 5 years ago

As a basic proof of concept for multi-language usage, without needing plugins, --contents could also support js(…), where the return value is the data.

In addition, we could get a javascript expression plugin that takes an expression and returns it: js-expr(5+2) would be equivalent to js(return 5+2;). Annoyingly, with Function there's no way to return the final line implicitly, and do-expressions are a long way off.

c-harding commented 5 years ago

Resolved with #37