JavaScript's tagged template literals do provide nice ergonomics. These should work well with some variation on PEP 501's types.InterpolationTemplate as the backend implementation. Some thoughts on what that should look like: * I also increasingly prefer the idea of using backticks to define such templates, as opposed to further overloading standard quoting. More below. * We should separate the static elements of the template from evaluated expressions. This implies that a tagged template function would have a signature like def html(template, *exprs). To provide the same user interface as PEP 501, one could write a tag template function "i" that is an identity function - thus demonstrating a basic equivalence of these proposals. * Literal static strings from the templates are available in both raw and cooked forms (Unicode escapes applied). So there's no need to add a "r" prefix for raw. * Expressions are evaluated immediately using normal scoping and rendered later (taking into account escaping rules, et). Such rendering can be into any Python object. So using some "html" tag function would return a DOM (let's call it HtmlElement in this example) which can be further rendered eventually into returned text in the scenario of serving HTML. * Greater likelihood of syntax support. Being able to specify html`<p>Some expr: {x * y}</p>` probably simplifies being able to provide an IDE extension that is aware that the html tag function was imported from some popular library, and can therefore provide assistance with HTML tags or any other aspects of the templating language used. * Backticks are multiline and they nest in the context of expressions. This means there's no need to invent new templating syntax, such as Jinja's {% for ... %} ... {% endfor %} to provide iteration over a sequence. Just use Python in the evaluated expressions. So with reference to the example in the Jinja doc https://jinja.palletsprojects.com/en/3.0.x/templates/#synopsis, we could have functions like the following that can be further composed to create larger DOM objects: def ulistify(id: str, linkage: dict[str, str]) -> HtmlElement: # uses a dict to represent the linkage in this example, so slightly different than the Jinja example return html` <ul id="{id}">{ html`<li><a href="{href}">{caption}</a></li>` for href, caption in linkage.items() }</ul>` It's possible to write something similar using f-string syntax now, but it involves careful tracking of which quotes are being used to support nesting. The interaction of backticks and expression syntax keeps it simple in comparison. An example library in the JavaScript ecosystem that builds out from the JS tagged template literal support is Lit (https://lit.dev/, note that I haven't used this library.) Lit provides some nice functionality by composing HTML DOM out of DOM fragments; and doing this in a lazy fashion (virtual DOM, as ReactJS demonstrated; I am not aware of a fast virtual DOM library in Python as a C Extension, but it would seem like a straightforward thing to write). Anyway, Lit and other similar libraries in JS could help understand the scope of the available innovation if we were to add such functionality. Format specifiers and ! conversions should presumably still be available in expressions and thus available from the template literal object to be used as part of any rendering. However, I'm leaving this open for the moment as to exactly what this looks like - especially if I overlooked any parsing issues for such support! Lastly, it's worth noting that types.InterpolationTemplate could look quite similar to https://262.ecma-international.org/6.0/#sec-tagged-templates if it's a constant object - a template literal in other words - which a tagged function is then applied to with the evaluated expressions. - Jim On Mon, Jul 5, 2021 at 1:10 AM Thomas Güttler <info@thomas-guettler.de> wrote:
Am Fr., 2. Juli 2021 um 12:06 Uhr schrieb Nick Coghlan <ncoghlan@gmail.com
:
On Fri, 2 Jul 2021, 5:12 pm Thomas Güttler, <info@thomas-guettler.de> wrote:
Hi Nick and all other Python ideas friends,
yes, you are right. There is not much difference between PEP-501 or my proposal.
One argument why I would like to prefer backticks:
Some IDEs detect that you want to use a f-string automatically:
You type:
name = 'Peter' print('Hello {name...
and the IDE automatically adds the missing "f" in front of the string:
name = 'Peter' print(f'Hello {name...
This is a handy feature (of PyCharm), which would not work reliably if there are two different prefixes.
-------
You mentioned these things:
eager rendering: I think deferred rendering would increase the complexity a lot. And I think it is not needed.
Eager rendering is f-strings. Any templating proposal necessarily involves a delayed rendering step, when the template is combined with the interpolated values.
runtime value interpolation: It is up to the receiver of
types.InterpolationTemplate to handle the data structure.
I really meant runtime template parsing here (i.e. str.format).
dedicated templating libraries: One temp after the other. I think HTML
and SQL libraries would adapt as soon as the foundation is available.
The existence of i-strings likely wouldn't change the syntax of jinja2 templates, Django templates, SQL Alchemy, pandas, etc.
I would be happy if PEP-501 would come true.
So would I, but I still don't have a compelling answer to the "but it's yet another subtly different way to do it" objection.
Today I read the replies to this thread again.
Of course there where some "-1" replies, but overall there was positive feedback.
Today I played with template literals from Javascript:
[image: image.png]
I like it.
Nick, would you be open to adapting to the JS syntax for PEP-501?
I propose `...{var} ...`
This means backticks, but without the dollar sign.
I would make it like in JS: The string in backticks can span several lines.
So what is the next step now?
Regards, Thomas
_______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-leave@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/NRJ7NB... Code of Conduct: http://python.org/psf/codeofconduct/