Easy and quick html builder with natural syntax correspondence (python->html). No templates needed. Serves pure pythonic library with no dependencies.
Project description
Airium
Bidirectional HTML
-python
translator.
Key features:
- simple, straight-forward
- template-less (just the python, you may say goodbye to all the templates)
- DOM structure is strictly represented by python indentation (with context-managers)
- gives much cleaner
HTML
than regular templates - equipped with reverse translator:
HTML
to python
Generating HTML
code in python using airium
Basic HTML
page (hello world)
from airium import Airium
a = Airium()
a('<!DOCTYPE html>')
with a.html(lang="pl"):
with a.head():
a.meta(charset="utf-8")
a.title(_t="Airium example")
with a.body():
with a.h3(id="id23409231", klass='main_header'):
a("Hello World.")
html = str(a) # casting to string extracts the value
# or directly to UTF-8 encoded bytes:
html_bytes = bytes(a) # casting to bytes is a shortcut to str(a).encode('utf-8')
print(html)
Prints such a string:
<!DOCTYPE html>
<html lang="pl">
<head>
<meta charset="utf-8" />
<title>Airium example</title>
</head>
<body>
<h3 id="id23409231" class="main_header">
Hello World.
</h3>
</body>
</html>
In order to store it as a file, just:
with open('that/file/path.html', 'wb') as f:
f.write(bytes(html))
Simple image in a div
from airium import Airium
a = Airium()
with a.div():
a.img(src='source.png', alt='alt text')
a('the text')
html_str = str(a)
print(html_str)
<div>
<img src="source.png" alt="alt text" />
the text
</div>
Table
from airium import Airium
a = Airium()
with a.table(id='table_372'):
with a.tr(klass='header_row'):
a.th(_t='no.')
a.th(_t='Firstname')
a.th(_t='Lastname')
with a.tr():
a.td(_t='1.')
a.td(id='jbl', _t='Jill')
a.td(_t='Smith') # can use _t or text
with a.tr():
a.td(_t='2.')
a.td(_t='Roland', id='rmd')
a.td(_t='Mendel')
table_str = str(a)
print(table_str)
# To store it to a file:
with open('/tmp/airium_www.example.com.py') as f:
f.write(table_str)
Now table_str
contains such a string:
<table id="table_372">
<tr class="header_row">
<th>no.</th>
<th>Firstname</th>
<th>Lastname</th>
</tr>
<tr>
<td>1.</td>
<td id="jbl">Jill</td>
<td>Smith</td>
</tr>
<tr>
<td>2.</td>
<td id="rmd">Roland</td>
<td>Mendel</td>
</tr>
</table>
Chaining shortcut for elements with only one child
New in version 0.2.2
Having a structure with large number of with
statements:
from airium import Airium
a = Airium()
with a.article():
with a.table():
with a.thead():
with a.tr():
a.th(_t='Column 1')
a.th(_t='Column 2')
with a.tbody():
with a.tr():
with a.td():
a.strong(_t='Value 1')
a.td(_t='Value 2')
table_str = str(a)
print(table_str)
You may use a shortcut that is equivalent to:
from airium import Airium
a = Airium()
with a.article().table():
with a.thead().tr():
a.th(_t="Column 1")
a.th(_t="Column 2")
with a.tbody().tr():
a.td().strong(_t="Value 1")
a.td(_t="Value 2")
table_str = str(a)
print(table_str)
<article>
<table>
<thead>
<tr>
<th>Column 1</th>
<th>Column 2</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<strong>Value 1</strong>
</td>
<td>Value 2</td>
</tr>
</tbody>
</table>
</article>
Using airium with web-frameworks
Airium can be used with frameworks like Flask or Django. It can completely replace template engines, reducing code-files scater, which may bring better code organization, and some other reasons.
Here is an example of using airium with django. It implements reusable basic_body
and a view called index
.
# file: your_app/views.py
import contextlib
import inspect
from airium import Airium
from django.http import HttpResponse
@contextlib.contextmanager
def basic_body(a: Airium, useful_name: str = ''):
"""Works like a Django/Ninja template."""
a('<!DOCTYPE html>')
with a.html(lang='en'):
with a.head():
a.meta(charset='utf-8')
a.meta(content='width=device-width, initial-scale=1', name='viewport')
# do not use CSS from this URL in a production, it's just for an educational purpose
a.link(href='https://unpkg.com/@picocss/pico@1.4.1/css/pico.css', rel='stylesheet')
a.title(_t=f'Hello World')
with a.body():
with a.div():
with a.nav(klass='container-fluid'):
with a.ul():
with a.li():
with a.a(klass='contrast', href='./'):
a.strong(_t="⌨ Foo Bar")
with a.ul():
with a.li():
a.a(klass='contrast', href='#', **{'data-theme-switcher': 'auto'}, _t='Auto')
with a.li():
a.a(klass='contrast', href='#', **{'data-theme-switcher': 'light'}, _t='Light')
with a.li():
a.a(klass='contrast', href='#', **{'data-theme-switcher': 'dark'}, _t='Dark')
with a.header(klass='container'):
with a.hgroup():
a.h1(_t=f"You're on the {useful_name}")
a.h2(_t="It's a page made by our automatons with a power of steam engines.")
with a.main(klass='container'):
yield # This is the point where main content gets inserted
with a.footer(klass='container'):
with a.small():
margin = 'margin: auto 10px;'
a.span(_t='© Airium HTML generator example', style=margin)
# do not use JS from this URL in a production, it's just for an educational purpose
a.script(src='https://picocss.com/examples/js/minimal-theme-switcher.js')
def index(request) -> HttpResponse:
a = Airium()
with basic_body(a, f'main page: {request.path}'):
with a.article():
a.h3(_t="Hello World from Django running Airium")
with a.p().small():
a("This bases on ")
with a.a(href="https://picocss.com/examples/company/"):
a("Pico.css / Company example")
with a.p():
a("Instead of a HTML template, airium has been used.")
a("The whole body is generated by a template "
"and the article code looks like that:")
with a.code().pre():
a(inspect.getsource(index))
return HttpResponse(bytes(a)) # from django.http import HttpResponse
Route it in urls.py
just like a regular view:
# file: your_app/urls.py
from django.contrib import admin
from django.urls import path
import your_app
urlpatterns = [
path('index/', your_app.views.index),
path('admin/', admin.site.urls),
]
The result ing web page on my machine looks like that:
Reverse translation
Airium is equipped with a transpiler [HTML -> py]
.
It generates python code out of a given HTML
string.
Using reverse translator as a binary:
Ensure you have installed [parse]
extras. Then call in command line:
airium http://www.example.com
That will fetch the document and translate it to python code.
The code calls airium
statements that reproduce the HTML
document given.
It may give a clue - how to define HTML
structure for a given
web page using airium
package.
To store the translation's result into a file:
airium http://www.example.com > /tmp/airium_example_com.py
You can also parse local HTML
files:
airium /path/to/your_file.html > /tmp/airium_my_file.py
You may also try to parse your Django templates. I'm not sure if it works, but there will be probably not much to fix.
Using reverse translator as python code:
from airium import from_html_to_airium
# assume we have such a page given as a string:
html_str = """\
<!DOCTYPE html>
<html lang="pl">
<head>
<meta charset="utf-8" />
<title>Airium example</title>
</head>
<body>
<h3 id="id23409231" class="main_header">
Hello World.
</h3>
</body>
</html>
"""
# to convert the html into python, just call:
py_str = from_html_to_airium(html_str)
# airium tests ensure that the result of the conversion is equal to the string:
assert py_str == """\
#!/usr/bin/env python
# File generated by reverse AIRIUM translator (version 0.2.3).
# Any change will be overridden on next run.
# flake8: noqa E501 (line too long)
from airium import Airium
a = Airium()
a('<!DOCTYPE html>')
with a.html(lang='pl'):
with a.head():
a.meta(charset='utf-8')
a.title(_t='Airium example')
with a.body():
a.h3(klass='main_header', id='id23409231', _t='Hello World.')
"""
Transpiler limitations
so far in version 0.2.2:
-
result of translation does not keep exact amount of leading whitespaces within
<pre>
tags. They come over-indented in python code.This is not however an issue when code is generated from python to
HTML
. -
although it keeps the proper tags structure, the transpiler does not chain all the
with
statements, so in some cases the generated code may be much indented. -
it's not too fast
Installation
If you need a new virtual environment, call:
virtualenv venv
source venv/bin/activate
Having it activated - you may install airium like this:
pip install airium
In order to use reverse translation - two additional packages are needed, run:
pip install airium[parse]
Then check if the transpiler works by calling:
airium --help
Enjoy!
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.