I started with a templating system that had a very limited logic and I'm still quite fond of this approach.
Basically arguments for a template had a form of a tree prepared by the controller function. The template could only display values from the tree (possibly processed by some library function, for example date formatter), hide or show fragments of html dependaning on the presence or absence of some value or branch in the tree, descend into a branch of a tree and iterate over an array from the tree, while descending into one iteration at a time. Also could include subtemplate feeding it a branch of the tree. This was enough to build any UI out of components and kept their html simple, separate and 100% html. Even the template logic had a form of html comments. One could open such template in any html editor including visual ones. It was all before advent of client side frameworks.
You could mimic this in React by preparing all data in render method as a jsonlike tree before outputting any JSX tag and limit yourself inside JSX part to just if and map(it =>{}) and single value {}
Yeah. I did this too. Mine's driven off a database with a structure of
1. pages, each of which may or may not have a parent pageID; the entire tree is read and parsed to generate the menu system and links/sub-links
2. modules which reference HTML templates to load through a parser that replaces areas with {{handlebar}} variables written by the clients through their own API
3. something like page_modules which locate the modules on the page,
4. a renderer which uses the above stuff to make the menu system, figure out what URL people are trying to get to, load the page, load the modules in the page, and fill in the crap the client wrote inside the {{handlebars}}
This has worked so well for so long that I can basically spin up a website in 15 minutes for a new client, let them fill in anything I want them to by themselves, throw some art on it and call it a day.
It worked so well that I ended up writing a newer version that uses a bunch of Javascript to accomplish basically the same thing with smoother transitions in a single-page app that doesn't look or act like an SPA, but it was basically pointless.
Basically arguments for a template had a form of a tree prepared by the controller function. The template could only display values from the tree (possibly processed by some library function, for example date formatter), hide or show fragments of html dependaning on the presence or absence of some value or branch in the tree, descend into a branch of a tree and iterate over an array from the tree, while descending into one iteration at a time. Also could include subtemplate feeding it a branch of the tree. This was enough to build any UI out of components and kept their html simple, separate and 100% html. Even the template logic had a form of html comments. One could open such template in any html editor including visual ones. It was all before advent of client side frameworks.
You could mimic this in React by preparing all data in render method as a jsonlike tree before outputting any JSX tag and limit yourself inside JSX part to just if and map(it =>{}) and single value {}