Important update: There has been some major changes in the htmldoom API and best practices. I will post an update soon about the changes. Till then please refer to the README and the API docs (docstrings).

After quite a few benchmarking games, rethinking and re-implementing the entire design, I'm finally satisfied enough to publish this here.

sayanarijit / htmldoom An intuitive, high performance HTML rendering framework htmldoom Introducing htmldoom htmldoom is an HTML rendering framework for Python that helps you define your HTML documents, templates, layouts and contents in an organised way, gives you the flexibility to use many different syntaxes, option to declare and debug different components and pages separately and more... all without making you worry about the runtime performance. How does it work? Understanding the working principle will get pretty intuitive if we go one feature at a time. Let's start with HTML escaping. HTML escaping In the center of htmldoom's functionality is the HTML escaping logic. Texts to be escaped are represented using str , while texts that should not be escaped are represented using bytes . The htmldoom.renders() function receives the texts as inputs, then for each input, it decides whether to escape it or not based on if it is str or bytes and returns the rendered text in str … View on GitHub

If you are a python developer who relies on templating engines to render webpages, consider having a look at this framework.

The performance of web pages written in htmldoom (non-optimized) is comparable to Jinja2 (probably the fastest templating engine available today for Python) and it has a lot of scope for further performance improvements.

Reference:

NOTE: If you by any chance perform any other benchmark tests, please let me know the results by opening an issue here.

A basic tag looks like this:



textarea ( "required" , class_ = "input" )( "text" )

<textarea required class= "input" > text </textarea>

A custom tag looks like this:



clipboard_copy = composite_tag ( "clipboard-copy" ) clipboard_copy ( value = "foo" )( "Copy Me" )

<clipboard-copy value= "foo" > Copy Me </clipboard-copy>

A dynamic component looks like this:



@ renders ( p ()( "{x}" ), p ()( "another {x}" ), ) def render_paras ( data : dict ) -> dict : return { "x" : data [ "x" ]}

<p> awesome paragraph </p><p> another awesome paragraph </p>

A for loop with a switch case (probably useless if you want performance)



>>> from htmldoom import elements as e >>> from htmldoom import functions as fn >>> >>> tuple ( fn . foreach ([ "good" , "bad" , "evil" ])( ... lambda x : fn . switch ({ ... x == "good" : lambda : e . span ( style = "color: green" )( f"this is { x } " ), ... x == "bad" : lambda : e . span ( style = "color: yellow" )( f"this is { x } " ), ... x == "evil" : lambda : e . span ( style = "color: red" )( f"this is { x } " ), ... fn . Case . DEFAULT : lambda : fn . Error . throw ( ValueError ( x )), ... }) ... )) ( b'<span style="color: green">this is good</span>' , b'<span style="color: yellow">this is bad</span>' , b'<span style="color: red">this is evil</span>' )

And what does a page look like?

Let me show you a live demo with live performance debugging?

Live demo: htmldoom-pyramid-example.herokuapp.com

Performance debugging: /_debug_toolbar/

Source code: It's here...

Note that the demo site is using pyramid_jinja2 and pyramid_htmldoom plugins. So the performance doesn't directly relate to the core libraries. Who cares, htmldoom is the clear winner.

Want to try it on your webpages but don't want to rewrite all the tags in Python syntax?

This guy is here to help:

sayanarijit / moodlmth Convert raw HTML pages into python source code moodlmth Convert raw HTML pages into python source code What..? moodlmth is the reverse of htmldoom Usage # Convert web page to Python syntax moodlmth https://google.com # Convert web page into YAML syntax moodlmth -s yaml https://google.com # Convert HTML file and write to another file moodlmth /filepath/index.html -o index.py # Force conversion moodlmth index.html -o index.py --fast --debug View on GitHub

Let me know what you think of it. Or if you find it lacking somewhere, contributers are very welcome to make it even more awesome.