casid / jte

Secure and speedy templates for Java and Kotlin.
https://jte.gg
Apache License 2.0
748 stars 56 forks source link

Customizable template literal #299

Closed dzikoysk closed 9 months ago

dzikoysk commented 9 months ago

By default, jte uses ${} operator to inject values into a template. As long as it feels like a natural candidate for this kind of work, it highly interferes with some of the widely used pattern in JavaScript. For instance, the @raw/@endraw directive may work quite well for a simple use-cases, like e.g. this one:

@raw
<script>
    const foo = "foo";
    console.log(`This is ${foo}`);
</script>
@endraw

but it get's kinda messy, if we'd like to go for anything more complex (e.g. React-like solutions):

export function App() {
  const [count, add] = useReducer((a, b) => a + b, 0);

  return html`
    <button onClick=${() => add(-1)}>Decrement</button>
    <input readonly size="4" value=${count} />
    <button onClick=${() => add(1)}>Increment</button>
  `;
}

render(html`<${App} />`, document.body);

Also on backend, if we'd like to declare some components in e.g. Kotlin, it uses the same syntax for strings. It makes it kinda... complex and misleading. User-defined placeholder might do the job here, e.g. user could redefine placeholder to something like @{} (etc.). Synchronizing the IDE plugin with custom symbol defined in settings at runtime could be a little bit tricky, so it might be declared in some sort of config file in templates directory (.jteconfig)


Sorry for bothering you with so many requests, but I'm trying to find out if in the long run I would be able to build a library around jte (probably focused on Javalin based stack) with which I could finally implement a new frontend in Reposilite. I have some kind of conception & I'm trying to avoid writing everything from scratch on my own 💀

casid commented 9 months ago

Welcome, and no worries!

Doesn't the @raw thing work the same for the React-like scenario?

In general, having jte fragments in inline JS is quite dangerous. The auto escaping that jte does, only works properly if the content is written inside a Javascript String, everything else is potentially unsafe.

At work, we've explicitly forbidden inline JS in jte templates for this reason. Maybe there is a way to avoid JS in jte templates in your scenario, too?

As for the suggestion to redefine syntax, I'm strictly against having the user define a custom syntax. For one, this makes parsing a lot harder and blows up the complexity of jte itself, plus all other software that works with it, like the IntelliJ plugin. Plus, when users report bugs, we suddently might not communicate in the same language.