Skip to main content

具有自然语法对应的简单快速的 html 构建器 (python->html)。不需要模板。提供没有依赖关系的纯 pythonic 库。

项目描述

空气馆

双向HTML-python翻译器。

PyPI 版本 管道状态 覆盖率报告 PyPI 版本 PyPI 许可证 PyPI 状态

主要特征:

  • 简单,直接
  • 无模板(只是 python,你可以告别所有模板)
  • DOM 结构由 python 缩进严格表示(带有上下文管理器)
  • HTML比常规模板更干净
  • 配备反向翻译器:HTMLto python

HTML在 python 中使用生成代码airium

基本HTML页面(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)

打印这样一个字符串:

<!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>

为了将其存储为文件,只需:

with open('that/file/path.html', 'wb') as f:
    f.write(bytes(html))

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>

桌子

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)

现在table_str包含这样一个字符串:

<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>

只有一个孩子的元素的链接快捷方式

0.2.2 版中的新功能

具有包含大量with语句的结构:

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)

您可以使用相当于以下内容的快捷方式:

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>

将 airium 与 web 框架一起使用

Airium 可以与 Flask 或 Django 等框架一起使用。它可以完全替代模板引擎,减少代码文件分散,这可能会带来更好的代码组织,以及其他一些原因。

这是一个在 django 中使用 airium 的例子。它实现了可重用basic_body和一个名为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

urls.py像常规视图一样路由它:

# 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),
]

我机器上生成的网页如下所示:

Airium/Django 无模板示例

反向翻译

Airium 配备了转译器[HTML -> py]。它从给定的HTML字符串生成 python 代码。

将反向翻译器用作二进制文件:

确保您已安装 [parse]附加组件。然后在命令行中调用:

airium http://www.example.com

这将获取文档并将其转换为 python 代码。代码调用重现给定文档airium的语句。HTML它可能会提供一个线索——如何使用 package.json 定义HTML给定网页的结构airium

要将翻译结果存储到文件中:

airium http://www.example.com > /tmp/airium_example_com.py

您还可以解析本地HTML文件:

airium /path/to/your_file.html > /tmp/airium_my_file.py

你也可以尝试解析你的 Django 模板。我不确定它是否有效,但可能没有太多需要修复的地方。

使用反向翻译器作为 python 代码:

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.4).
# 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.')
"""

转译器限制

到目前为止在 0.2.2 版中:

  • 翻译结果不会在<pre>标签中保留准确数量的前导空格。它们在 python 代码中过度缩进。

    然而,当代码从 python 生成到HTML.

  • 尽管它保留了正确的标签结构,但转译器并未链接所有with语句,因此在某些情况下,生成的代码可能会缩进很多。

  • 这不是太快

安装

如果您需要新的虚拟环境,请致电:

virtualenv venv
source venv/bin/activate

激活它 - 您可以像这样安装 airium:

pip install airium

为了使用反向翻译 - 需要两个额外的包,运行:

pip install airium[parse]

然后通过调用检查转译器是否工作:

airium --help

享受!