Something I don't understand is whether there is anything about this proposed feature that can't be accomplished with a simple function.
IIUC, the proposal turns this: foo = "spam & eggs" `Here, have some {foo}.` ...into something like this (I am making up a more readable repr): TemplateLiteral( template = " Here, have some {foo}.", tokens = (("Here, have some ", True), ("spam & eggs", False)), ) What is it about this task that cannot be accomplished with a class and function? Skeleton might look like: @dataclass class TemplateLiteral: template: str tokens: Sequence(Tuple(str, bool)) = field(init = False) def templify(s: str) -> TemplateLiteral: ... And use it like this: >>> templify("Here, have some {foo}.") TemplateLiteral(template = " Here, have some {foo}.", tokens = (("Here, have some ", True), ("spam & eggs", False))) What is it about this task that requires it being handled at the language level...? --- Ricky. "I've never met a Kentucky man who wasn't either thinking about going home or actually going home." - Happy Chandler On Thu, Jun 10, 2021 at 9:36 AM David Mertz <me...@gnosis.cx> wrote: > Strong -1 > > As others noted in prior discussion, even if this existed, it works be an > anti-pattern for SQL. So basically, it's just baking in an HTML-only > template language into the language syntax. > > Python already had excellent HTML templating in libraries. The fact Django > has a function with a long name just suggests importing it with a shorter > name. > > Python has many uses having nothing to do with web pages. This could make > sense for PHP (does anyone use that still?). It's a poor for for Python. > > On Thu, Jun 10, 2021, 2:31 AM Thomas Güttler <i...@thomas-guettler.de> > wrote: > >> Thank you Guido, Chris, Matt and Richard for your feedback to my last >> email. >> >> Here is an updated version called "Template Literals". >> >> I am looking for a core developer who can sponsor this PEP. >> >> Please speak up if you want to help me. >> >> Regards, >> Thomas Güttler >> >> Source and updates: Pre-PEP 9999 >> <https://github.com/guettli/peps/blob/master/pep-9999.rst> >> >> PEP: 9999 >> Title: Template Literals >> Author: Thomas Güttler <info at thomas-guettler.de> >> Sponsor: TODO >> Status: Draft >> Type: Standards Track >> Content-Type: text/x-rst <http:///dev/peps/pep-0012> >> Created: 08-Jun-2021 >> Python-Version: TODO >> Post-History: 08-Jun-2021 >> ------------------------------ >> >> Contents >> >> - Abstract <#m_2818986526677889823_m_-138379983175526697_abstract> >> - Motivation <#m_2818986526677889823_m_-138379983175526697_motivation> >> - Rationale <#m_2818986526677889823_m_-138379983175526697_rationale> >> - Specification >> <#m_2818986526677889823_m_-138379983175526697_specification> >> - Security Implications >> <#m_2818986526677889823_m_-138379983175526697_security-implications> >> - Reference Implementation >> <#m_2818986526677889823_m_-138379983175526697_reference-implementation> >> - Alternative Ideas >> <#m_2818986526677889823_m_-138379983175526697_alternative-ideas> >> - Rejected Ideas >> <#m_2818986526677889823_m_-138379983175526697_rejected-ideas> >> - Open Issues >> <#m_2818986526677889823_m_-138379983175526697_open-issues> >> - References <#m_2818986526677889823_m_-138379983175526697_references> >> - Copyright <#m_2818986526677889823_m_-138379983175526697_copyright> >> >> Abstract <#m_2818986526677889823_m_-138379983175526697_id6> >> >> This PEP adds Template Literals to Python. >> >> To avoid code injection like XSS or SQL-injection Template Literals can >> help you to write save Python code. >> >> Template Literals provide an easy way to access the local and global >> variables (like f-strings), so that passing a dictionary to the Template is >> not necessary. >> Motivation <#m_2818986526677889823_m_-138379983175526697_id7> >> >> In the context of web development Python can do more than providing REST >> APIs via http. With the trend to Server-Side-Rendering, we face a >> fundamental question: >> >> How to create HTML with Python? >> >> If you use the FrOW pattern (HTML fragments over the wire) [1] >> <#m_2818986526677889823_m_-138379983175526697_frow>, then you will be >> writing small methods returning small HTML fragments. >> >> As a developer I want to pass escaped data into template literals to be >> as simple as possible. >> Rationale <#m_2818986526677889823_m_-138379983175526697_id8> >> >> Imagine you want to create a small HTML fragment in Python, and return it >> as HTTP-Response: >> >> HttpResponse(f''' >> <h1>Hi {name}</h1> >> Your messages: {messages}''') >> >> The problem in above example is, that no escaping gets done. >> >> In above example "name" and "messages" should be treated differently. >> >> The variable "name" should get escaped. For example if the name is "Mary >> & Bob", the result should be "Mary & Bob". >> >> The variable "messages" contains HTML which is already escaped. It should >> not be escaped again. >> >> Most frameworks have a way to do this conditional escaping. >> >> For example Django uses conditional_escape() >> <https://docs.djangoproject.com/en/3.2/ref/utils/#django.utils.html.conditional_escape> >> [2] <#m_2818986526677889823_m_-138379983175526697_id2> >> >> With the help of conditional_escape() the above problem could be solved >> like this: >> >> HttpResponse(f''' >> <h1>Hi {conditional_escape(name)}</h1> >> Your messages: {conditional_escape(messages)}''') >> >> This solution has two drawbacks: >> >> 1. It is too verbose. Typing "conditional_escape(...)" again and >> again is cumbersome. >> 2. If a conditional_escape() gets forgotten Cross-site scripting >> attacks could be possible, since malicious users could inject HTML. >> >> Specification <#m_2818986526677889823_m_-138379983175526697_id9> >> >> Template Literals use backticks (like JavaScript Template Literals >> <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals> >> [3] <#m_2818986526677889823_m_-138379983175526697_id4>) >> >> Example: >> >> name = 'Mary & Bob' >> messages = `<ul><li>message1</li><li>message2</li></ul>` >> return HttpResponse(` >> <h1>Hi {name}</h1> >> Your messages: {messages} >> >> Today: {datetime.date.today()}`) >> >> Expressions within curly braces get handled liked in f-strings (PEP-498). >> >> The Template Literal creates an instance of the new class >> types.TemplateLiteral. >> >> types.TemplateLiteral has two attributes: >> >> - template: The raw string inside the backticks. >> - tokens: A list of tuples: (value, is_literal). >> >> For above example this would mean: >> >> template = ''' >> <h1>Hi {name}</h1> >> Your messages: {messages} >> >> Today: {datetime.date.today()}''' >> >> tokens = [ >> ('\n <h1>Hi ', True), >> ('Mary & Bob', False), >> ('</h1>\n Your messages: ', True), >> (<TemplateLiteral "<ul><li>message1</li><li>message2</li></ul>">, False), >> ('\n\n Today: ', True), >> (<datetime.date(2021, 6, 9)>, False) >> ] >> >> It is outside this PEP how a consumer of TemplateLiteral handles this >> data structure. >> >> For example the Django web framework could transform a TemplateLiteral to >> a SafeString like this: >> >> def template_literal_to_safestring(template_literal): >> return mark_safe( >> ''.join( >> [ >> conditional_escape(value) if not is_literal else value >> for (value, is_literal) in template_literal.tokens >> ] >> ) >> ) >> >> This PEP is not related or constraint to the Django framework. It is even >> not related to HTML. It can be used for any kind of templating. >> Security Implications <#m_2818986526677889823_m_-138379983175526697_id10> >> >> Template Literals can execute arbitrary code (like f-strings). >> >> Template Literals get created by Python developers, not by users. If you >> want to make templates available for users (for example if you develop a >> CMS), then please use a different solution. >> Reference Implementation >> <#m_2818986526677889823_m_-138379983175526697_id11> >> >> TODO >> Alternative Ideas <#m_2818986526677889823_m_-138379983175526697_id12> >> >> Instead of backticks for example t'...' could be used. >> Rejected Ideas <#m_2818986526677889823_m_-138379983175526697_id13> >> >> TODO >> Open Issues <#m_2818986526677889823_m_-138379983175526697_id14> >> >> TODO >> References <#m_2818986526677889823_m_-138379983175526697_id15> >> [1] <#m_2818986526677889823_m_-138379983175526697_id1> FrOW, "HTML >> Fragments Over the Wire". Frameworks like Unpoly, Hotwire or htmx. >> [2] <#m_2818986526677889823_m_-138379983175526697_id3> >> https://docs.djangoproject.com/en/3.2/ref/utils/#django.utils.html.conditional_escape >> [3] <#m_2818986526677889823_m_-138379983175526697_id5> >> https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals >> Copyright <#m_2818986526677889823_m_-138379983175526697_id16> >> >> This document is placed in the public domain or under the >> CC0-1.0-Universal license, whichever is more permissive. >> _______________________________________________ >> Python-ideas mailing list -- python-ideas@python.org >> To unsubscribe send an email to python-ideas-le...@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/LYAC7JC5253QISKDLRMUCN27GZVIUWZC/ >> Code of Conduct: http://python.org/psf/codeofconduct/ >> > _______________________________________________ > Python-ideas mailing list -- python-ideas@python.org > To unsubscribe send an email to python-ideas-le...@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/6MMGTZL7VGXXLYL6UZMQ3MRHJW6EA74L/ > Code of Conduct: http://python.org/psf/codeofconduct/ >
_______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@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/XZ22MH2RU643HHYMYYEDOC3F7H22XBBW/ Code of Conduct: http://python.org/psf/codeofconduct/