leforestier / yattag

Python library to generate HTML or XML in a readable, concise and pythonic way.
328 stars 31 forks source link

Added AsIs for inserting un-escaped strings as attribute values. #82

Closed abingham closed 1 month ago

abingham commented 1 month ago

This is the core idea discussed in #81.

While this works, it's limited in a small way. Since yattag always uses double-quotes around attribute values, people can't use unescaped double-quotes in the AsIs value. I think I see how to account for this, but I figured it might be a step too far for this PR.

leforestier commented 1 month ago

I think we should modify the dict_to_attrs function rather than attr_escape. This would allow to bypass attr_escape completely.

Note that when using AsIs, you'd then have to explicitly write the external quotes, like this:

with tag("body", settings=AsIs("'{\"scrollBehavior\":\"auto\"}'"):
    text("hello")

to get this:

<body content='{"scrollBehavior":"auto"}'>hello</body>

What do you think? I think that the total freedom is worth the little inconvenience of adding the two external quotes.

By the way, are you sure that HTMX doesn't work if you pass the json settings as a regular HTML attribute (escaped using " and between double quotes) ? I haven't worked with HTMX so far.

abingham commented 1 month ago

I've reverted attr_escape() and updated dict_to_attrs() to call the new format_attr_value(). This new function distinguishes between AsIs instances and everything else, adding surrounding quotes as necessary.

What do you think? I think that the total freedom is worth the little inconvenience of adding the two external quotes.

I think this is the right move. AsIs should be as un-clever as possibe, allowing the user to get exactly what they ask for.

By the way, are you sure that HTMX doesn't work if you pass the json settings as a regular HTML attribute (escaped using " and between double quotes) ? I haven't worked with HTMX so far.

I'm not 100% certain, but I've had no luck getting any version other than what I'm using to work.

leforestier commented 1 month ago

That is perfect! Thanks for your contribution.

leforestier commented 1 month ago

Now available on Pypi (yattag version 1.16.0).

abingham commented 1 month ago

Works perfectly, thanks for packaging it up!