
Молниеносный асинхронный веб-фреймворк рендер html5, python EHTML5
Python HTML generation/templating (no template files) bulma-css and icons. генерация HTML-кода на python/создание шаблонов (без файлов шаблонов) bulma-css и иконки, нативный javascript . Быстро и легко !!!!. Необходимые навыки Bulma-css. Bulma — это бесплатный фреймворк с открытым исходным кодом, предоставляющий готовые к использованию интерфейсные компоненты, которые можно легко комбинировать для создания адаптивных веб-интерфейсов.
Python HTML generation-templating
pip install "git+https://gitverse.ru/rectbyte/ehtml5.git"
Так же со всеми async/await фреймворками Flask (async/await), Tornado.
Как GET так и POST (request).
Быстрый старт.
python -m venv venv && source ./venv/bin/activate pip install "git+https://gitverse.ru/rectbyte/ehtml5.git" #выполнить команду ehtml build #не забудь подключить fast_api static app.mount("/public", StaticFiles(directory="./public"), name="public") #не забудь подключить sanic static app.static("/public", "./public")
ehtml build_fastapi
ehtml build_sanic
Наследуемся от класса (ABCPageRender). Два абстрактных метода (navbar , footer ), которые нужно переопределить. Пример кода на Sanic.
from ehtml5.htmlrender import ABCPageRender, BaseLayout from html5tagger import Document, E ,HTML, Builder from ehtml5.web import ( Card, Modal, Footer, NavBar, Message, icon_text, icon, HeroNavBar, Paginator, PreCode, fasicon, AsideMenu, Login, SrcDoc, Slide, VideoIFrame) from sanic import Request class PageRender(ABCPageRender): def meta_head_append(self): return [ E.meta(name="theme-color", content="#ff0d68"), E.meta(name="author", content="RectByte" ), E.link(rel="manifest", href="/public/assets/manifest.json" ), E.link(rel="icon", href="/public/assets/icons/32.png", sizes="any", type="image/x-png"), ] async def navbar(self, request, builder)->None: nav = NavBar(classes=["is-light", "is-medium"]) nav.navbar_brand(logo="Sanic", data_target="navMenu", classes=["app-menu"]) user_icon = icon(name="fas fa-user") user_icon_text = icon_text(name=fasicon.user, text="главная страница", classes=["has-text-primary"]) start = [ E.a(class_="navbar-item", href="/modal")("modal"), E.a(class_="navbar-item", href="/slide")("slide"), ] st = NavBar.navbar_dropdown(name="примеры сборки ehtml5", href="#link", lst_link=start, classes=["is-hoverable"], sub_classes=["has-text-primary", "is-boxed"], sub_attrs={"data-temp": "tessts"}) box_item = E.div(class_="navbar-item") end = [ box_item( E.a(class_="button is-warning mr-1", href="https://gitverse.ru/")("gitverse"), E.button(class_="button is-black mr-1")("gitflic"), E.button(class_="button is-info ml-1")(user_icon), ) ] nav.navbar_menu(id="navMenu", navbar_start=[st], navbar_end=end, ) builder(nav()) async def footer(self, request, builder)->None: footer = Footer() bod = E.div(class_="has-text-black")("Copyright 2025") footer.footer_body(body=bod, classes=["has-text-centered", "has-background-primary"]) builder(footer()) #переопределив метод вы можете передать туда None. #если не нуждаетесь в данном методе builder(None)
from ehtml5.htmlrender import BaseLayout class PageIndex(BaseLayout): async def layout(self, request: Request, **kw_data): self.render.set_meta_seo(**kw_data) ic = fasicon.__dict__ l = [] for k, v in ic.items(): l.append(E.div(class_="box colomn is-2 m-2")(icon_text(name=v, text=k, classes=["fa-lg"]))) self.builder.div(class_="columns is-multiline m-2 p-2")(*l) self.builder.hr().div(class_="button")(icon(name=fasicon.address_book, classes=["has-text-primary"])) class PageModal(BaseLayout): async def layout(self, request: Request, **kw_data): #self.render.set_meta_seo({"title": " text text text ", "keywords": " test, test, test, test", "description": "page one" }) self.render.set_meta_seo(**kw_data) #self.render.set_meta_property({"og_image": "path/path/img.jpg", "og_description": " page text","og_title": "title title" }) #префикс og_image answer <meta property="og:image" content="/public/assets/icons/256.jpg"> self.render.set_meta_property(**kw_data) #модальное окно #кнопка открытия btn = E.button(class_="button modal-trigger", data_target="modal-example")("open modal") #javascript сработает на modal-trigger и откроет его по data-target="ваше наименование" btn = E.button(class_="button modal-trigger", data_target="modal-example")("open modal") modal = Modal(id="modal-example") #data-target = "modal-example" == Modal(id="modal-example" ) body = E.div(class_="box", style="background:white;" ) l= [] for i in range(20): l.append(E.div(f"test overflow: auto; {i}").br()) # modal.width=98 # modal.top=30 # modal.button_size = "fa-lg" # modal.icon = fasicon.umbrella_beach modal.css_fixed.append("border:solid black 1px") modal.modal_body_fixed(body=body(*l)) section = E.div(class_="section is-medium")(modal(active=False), btn) self.builder(section)
renders = PageRender() renders.rigister_handler_page(PageIndex("index"), PageModal("modal"))
from sanic import Sanic, html from rendering import renders app = Sanic("ehtml") app.static("/public", "./public") @app.route("/") async def handler_index(request): result = await renders(request, "index", title="index page", description="example index") return html(str(result)) @app.route("/modal") async def handler_modal(request): result = await renders(request, "modal", title="modal page", keywords="modal, window", description="example modal") return html(str(result)) if __name__ == '__main__': app.run(host='127.0.0.1', port=8000, workers=1, dev=True)
pip install sanic==23.12.0
Поверьте, попробовав ehtml5, вы больше никогда не вернётесь к Jinja2 или написанию HTML вручную!
python3 app.py