Roundup Tracker - Issues

Issue 2551270

Better templating support for JavaScript
Type: rfe Severity: normal
Components: Versions:
Status: new
: : rouilj
Priority: : Effort-Medium

Created on 2023-03-28 22:48 by rouilj, last changed 2023-03-28 22:48 by rouilj.

msg7745 Author: [hidden] (rouilj) Date: 2023-03-28 22:48
I sent this to roundup-devel. Got no replies. I think it is worth doing.

>I have been working on trackers that need more javascript than a
>classic tracker. Currently javascript is used via onclick or other onX
>handlers on elements (buttons, inputs) in the generated HTML. If you
>are using a content security policy, using onX inline javascript is a
>bad idea.  Instead you want a javascript function to run that adds
>event listeners to the elements. This will result in more required
>I would like to totally remove javascript from the Python code and
>move it to external file(s). These files could be loaded via:
>   <script src="@@file/...">
>tag or be included inline like base_javascript().  Inserting the
>javascript into the HTML will make the HTML work even if loading a
>script fails (network issues ...).
>When base_javascript() is called, it inserts values from Roundup
>(self._client.client_nonce, self.base) into the returned
>javascript/html. (Note that the client_nonce must never be exposed
>anywhere except in the HTML processed by the browser.)  Some
>javascript I have written needs replaced values as well.
>The tokens (except for security nonces) could be specified using a
>json formatted variable created by a templating extension. But some
>way to embed an external javascript file into the returned HTML is
>still required.
>My thought is to provide a templating method:
>  inline_javascript("filename", values={}, options={})
>This would:
>  1 read the contents of filename (relative to the tracker home
>    unless it starts with /) into a string. (Optional: if started
>    with @@file, it's relative to the HTML directory.)
>  2 use string interpolation with only named values '%(name)s' on the
>    string. (Optional: scan and  autofix '%' not followed by a '('
>    if there is a TypeError when interpolating.)
>  3 have a predefined set of values that can be updated by passing new
>    values using the values={} parameter. At the very least:
>      * client_nonce
>      * base
>    would be defined. If values=None is supplied, interpolation is
>    not done.
>  4 return the (optionally) interpolated string
>This should allow the file to:
>   * be externally stored,
>   * substitute Roundup variable values,
>   * be inlined in the returned HTML
>The options dict is for future expansion. E.G. the file could be
>minimized on the fly or something. (Note it would probably be better
>to use a .js.min and inline that to remove the processing overhead.)
>I chose string interpolation because '%(' is a unique marker. In
>javascript '%' is used for remainder operations. It is not heavily
>used IMO. If a parenthesized expression is needed, '% (' can be used
>as a workaround (although minimizing the file might be an issue).
>I decided not to use the string.format method because the specifiers
>"{...}" can be used in javascript and I am concerned this will cause
>syntax errors. (That will be difficult to auto-correct.)
>I am not sure if I could write a custom Formatter class to replace the
>'{' and '}' but that's more involved/fragile/requires testing. For
>output that is to be consumed by humans (e.g. to provide a template
>for email messages) I think format makes sense. But broken formatting
>here breaks the application.
>Similarly template strings require replacing $ with $$. Since a lot of
>javascript uses $ as a variable/function name (e.g. jQuery) template
>strings are a nonstarter as well.
Date User Action Args
2023-03-28 22:48:18rouiljcreate