I was recently building a Dash app that included a somewhat nontrivial table where I was creating rows from a nested list comprehension, and I was making frequent mistakes such as
html.Tr(html.Td("cell contents", style={...}), html.Td("another cell", className="foo"))
Of course you can spot the error easily here, but when the elements are nested more deeply and there are more attributes, it can be more difficult. (See this comment for a larger example.)
That got me thinking, JavaScript developers have JSX syntax, which mixes html-like elements with inline JavaScript, so something similar should exist for Python. I didn’t find a solution, so here’s my attempt: htexpr. It lets you write code like
app.layout = eval(htexpr.compile("""
<div>
<table style={"margin": "0 auto"}>
<tr><th>char</th><th>name</th><th>category</th></tr>
[
(<tr style={'background-color': '#eee' if line % 2 else '#ccc'}>
<td>{ char }</td>
<td>{ unicodedata.name(char, '???') }</td>
<td>{ unicodedata.category(char) }</td>
</tr>)
for line, char in enumerate(chr(i) for i in range(32, 128))
]
</table>
</div>
"""))
and translates it into calls to the relevant functions html.Div
etc. Note the list comprehension (whose value is spliced into the children
argument to the html.Table
call) and the embedded Python code in <tr style={...}>
and the <td>{...}</td>
items.
You can try this out with pip install htexpr
, the GitHub README has some documentation, and there’s a somewhat larger example. I’m using this library in a private project, but I wouldn’t want to promise that it’s in any way ready for production. There are likely to be some corner cases I haven’t thought about. But I’m interested in hearing if anyone has uses for this.