Skip to main content

Build complex websites in pure python with pydzn layout builder, semantic css classes and an extendable components library for server-side rendering.

Project description

pydzn

Pronounced: [paɪ dɪˈzaɪn] — “pie design” (aka py-design)

Design and develop complex websites all in python. Build web components, rendered on the server-side and served up in any python backend web server (flask, django...).

More than just a view layer, pydzn serves as a framework that introduces python developers to front end development with an intuitive approach for layout design, component development and styling.

Who is pydzn for

  • Python fluent programmers who find designing and developing nice looking websites a frustrating task
  • Students learning python who also want to learn how to build websites
  • Backend developers and data scientists who want to build AI-first web applications
  • Front-end developers who value simplicity while maintaining full control over their runtime
  • Professional front-end developers who want to avoid react abstraction bloat and javascript's async chaos

Why pydzn

Creating and serving a webpage is technically easy for most developers. Designing and developing a nice looking website is much more difficult. pydzn offers a framework for breaking up the task of front-end design and development, logically, into layout creation, component creation with the injection of those components into that layout. Where a layout is a grid in a 2-dimensional space containing named regions of which you style and inject components into. A layout is a class which can have an arbitrary number of regions. A region is a placement in a grid layout for which another layout can be inject OR a component.

Introduction

Layouts

A website is a design in a 2-dimensional space, therefore, a design divides that 2-dimensional space into regions. We've made this easy to do in pydzn with the layout_builder. With a little practice you'll start seeing other websites as "grid layouts" and you'll find it easy to recreate them in pydzn. Let's start by creating a generic page layout.

@app.route("/tutorial")
def tutorial():
    from pydzn.grid_builder import layout_builder

    APPBAR_HEIGHT=100
    HERO_HEIGHT=200
    BODY_HEIGHT=400
    FOOTER_HEIGHT=200
    DEBUG=True

    GenericPageLayout = (
        layout_builder()
        .fill_height("100%", property="height")
        .columns(c0="1fr") # for the base layout we only need one column because each row will be it's own region
        .rows(r0=APPBAR_HEIGHT, r1=HERO_HEIGHT, r2=BODY_HEIGHT, r3=FOOTER_HEIGHT) # each row is a section of the web page in this case
        .region("appbar", row="r0", col="c0") # the appbar belongs in row 0 and column 0
        .region("hero", row="r1", col="c0")
        .region("body", row="r2", col="c0")
        .region("footer", row="r3", col="c0")
        .build(name="GenericPageLayout")
    )

    body = GenericPageLayout(debug=DEBUG).render() # set debug=True in order view the layout lines and region names for easier development
    return render_template("index.html", body=body)

mobile

The layout we've created is a common layout containing an appbar, hero, body and footer. Let's now inject the appbar layout into the appbar region.

...
    AppBarLayout = (
        layout_builder()
        .fill_height("100%", property="height")
        .columns(c0="1fr", c1="3fr", c2="1fr", c3="1fr", c4="1fr") # we'll divide the app bar into 5 columns and we'll make c1 a spacer
        .rows(r0=APPBAR_HEIGHT) # we've previously set the appbar height so we'll use it
        .region("brand", row="r0", col="c0")
        .region("spacer0", row="r0", col="c1")
        .region("about", row="r0", col="c2")
        .region("contact", row="r0", col="c3")
        .region("services", row="r0", col="c4")
        .build(name="AppBarLayout")
    )

    body = GenericPageLayout(debug=DEBUG).render(
        appbar=AppBarLayout(debug=DEBUG).render()  # appbar, like hero, body and footer are variables in the render function's signature
    )
    return render_template("index.html", body=body)

mobile

Next let's add some of pydzn pre-made components into the appbar.

...
    from pydzn.components import Text, NavItem

    body = GenericPageLayout(debug=DEBUG).render(
        appbar=AppBarLayout(debug=DEBUG).render(
            brand=Text(
                text="Acme Widgets", 
                dzn="text-[#272727]").render(), # let's give the text a color using pydzn semantic classes
            about=NavItem(
                children=Text(
                    text="About Us", dzn="text-[#272727]").render()
                    ).no_underline().center().as_link("/#").render(),
            contact=NavItem(
                children=Text(text="Contact Us", dzn="text-[#272727]").render()
                ).no_underline().center().as_link("/#").render(),
            services=NavItem(
                children=Text(text="Services", dzn="text-[#272727]").render()
                ).no_underline().center().as_link("/#").render()
        )
    )
    return render_template("index.html", body=body)

mobile

We inject complex components (NavItem composed of Text) into the region slots inside AppBarLayout, however, I don't like how the look inside their respective regions. pydzn provides a dzn controls on layouts in order to define the layout within each region. Let's center each of these components in their respective region.

...
    from pydzn.components import Text, NavItem

    body = GenericPageLayout(
        debug=DEBUG,).render(
        appbar=AppBarLayout(
            debug=DEBUG,
            region_dzn={
            "brand": "flex items-center justify-center", # pydzn provides fine control on individual region styles using the dzn semantic classes
            "about": "flex items-center justify-center",
            "contact": "flex items-center justify-center",
            "services": "flex items-center justify-center"
        }).render(
            brand=Text(text="Acme Widgets", dzn="text-[#272727]").render(), # let's give the text a color using pydzn semantic classes
            about=NavItem(
                children=Text(
                    text="About Us", dzn="text-[#272727]").render()).no_underline().center().as_link("/#").render(),
            contact=NavItem(
                children=Text(
                    text="Contact Us", dzn="text-[#272727]").render()).no_underline().center().as_link("/#").render(),
            services=NavItem(
                children=Text(text="Services", dzn="text-[#272727]").render()).no_underline().center().as_link("/#").render()
        )
    )
    return render_template("index.html", body=body)

mobile

Pydzn offers utilities for serving responsive websites and leverages htmx to provide complex functionality within your web pages. To be continued...

Examples

References

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pydzn-0.1.5.tar.gz (40.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pydzn-0.1.5-py3-none-any.whl (45.7 kB view details)

Uploaded Python 3

File details

Details for the file pydzn-0.1.5.tar.gz.

File metadata

  • Download URL: pydzn-0.1.5.tar.gz
  • Upload date:
  • Size: 40.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.18

File hashes

Hashes for pydzn-0.1.5.tar.gz
Algorithm Hash digest
SHA256 bd0cb79b476ce3dd636717b795993060d39046449c1a839d95aed3c3cad685ec
MD5 b815298ec1d4a7b867e4191eb93b6ee6
BLAKE2b-256 3a3b033621d86cf3b6cecefb870eb0c05060b16b5e2ce5a2c4eaeb35fedf1250

See more details on using hashes here.

File details

Details for the file pydzn-0.1.5-py3-none-any.whl.

File metadata

  • Download URL: pydzn-0.1.5-py3-none-any.whl
  • Upload date:
  • Size: 45.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.18

File hashes

Hashes for pydzn-0.1.5-py3-none-any.whl
Algorithm Hash digest
SHA256 3a8c69d9fbc27a8e3cbc685c6ec2893ff5b1acf82abd1cc1a1c58eda1ba61535
MD5 743cf09bb3a95fa59990aa1fd240e9bd
BLAKE2b-256 56fc2e627ca9cdc777515d539e9b396406c4216717a56a54b52c91acfdceae82

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page