Skip to content

Support for __html__ method and marking variables as safe to use in templates to avoid escaping #3583

@bhch

Description

@bhch

Feature

Something like Django's safestring or the markupsafe library.

A lot of libraries (wtforms, django, jinja, etc.) follow a convention for autoescaping that if an object implements a special method called __html__, the value returned by this method should be assumed as safe to use in templates and not be escaped.

e.g.:

class SafeString(str): 
    def __html__(self):
        return self

# escape function
def escape(value):
    if hasattr(value, "__html__"):
        return value.__html__()
    else:
        # escape normally
        ...

Obstacle

Although Tornado makes it easy to use a a custom autoescape function, the trouble is that tornado's template system converts str (and its subclass) instances to bytes. And during this conversion the information that it is a safe-marked variable (i.e. it has the __html__ method) is lost and the escape function has no way of knowing.

Possible solutions

1. Preserve the __html__ method during conversion

Can be done possibly in template.py or in escape.utf8 function.

This will allow interoperability with third party libs that inherit their SafeString class from str.

2. Provide a custom implementation of SafeString that inherits from bytes instead of str

This is what I'm currently doing in my project.

But to work with 3rd party libs I have to explicitly convert their safe str to my custom safe bytes, something like this:

{{ mark_safe(third_party_safe_str) }}

I think it's an essential feature for any template system. I don't see a reason why Tornado shouldn't have it built-in.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions