starndort foto

Молниеносный асинхронный веб-фреймворк рендер 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"
Он превосходно работает , как с фреймворкам Sanic (Sanic — один из самых популярных фреймворков на PyPI и лучший фреймворк с поддержкой асинхронности), так и FastApi (Фреймворк FastAPI, высокая производительность, простота в освоении, быстрый код, готовый к использованию).
Так же со всеми 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")
Пример кода на FastApi.
FastAPI — это современный, быстрый (высокопроизводительный) веб-фреймворк для создания API на Python на основе стандартных подсказок по типам Python.
ehtml build_fastapi
Пример кода на Sanic.
Sanic — один из самых популярных фреймворков на PyPI и лучший фреймворк с поддержкой асинхронности.
Интуитивно понятный API с удобными настройками по умолчанию и без лишних функций позволяет сразу приступить к созданию приложения.
ehtml build_sanic
Пишем свой "render", в принципе здесь ничего сложного.
Наследуемся от класса (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)
Пишем свою первую страницу. Наследуемся от класса ( BaseLayout). Один метода ( layout ).
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)
Я использую, молниеносный асинхронный веб-фреймворк Sanic==23.12.0
pip install sanic==23.12.0
Первый запуск.
Поверьте, попробовав ehtml5, вы больше никогда не вернётесь к Jinja2 или написанию HTML вручную!
python3 app.py