Skip to main content

View layer for Python VDOMs

Project description

viewdom

Docs and Code

viewdom brings modern frontend templating patterns to Python:

  • tagged to have language-centered templating (like JS tagged templates)

  • htm.py to generate virtual DOM structures from a template run (like the htm JS package)

  • viewdom to render a VDOM to a markup string, along with other modern machinery

Installation

Installation follows the normal Python packaging:

$ pip install viewdom

Quick Examples

Use htm to generate a VDOM, then render to convert to a string:

result = render(html('''<div>Hello World</div>'''))
# '<div>Hello World</div>'

If you’d like, you can split those into two steps:

vdom = html('''<div>Hello World</div>''')
result = render(vdom)
# '<div>Hello World</div>'

Insert variables from the local or global scope:

name = 'viewdom'
result = render(html('<div>Hello {name}</div>'))
# '<div>Hello viewdom</div>'

Expressions aren’t some special language, it’s just Python in inside curly braces:

name = 'viewdom'
result = render(html('<div>Hello {name.upper()}</div>'))
# '<div>Hello VIEWDOM</div>'

Rendering something conditionally is also “just Python”:

message = 'Say Howdy'
not_message = 'So Sad'
show_message = True
result = render(html('''
    <h1>Show?</h1>
    {message if show_message else not_message}
'''))
# '<h1>Show?</h1>Say Howdy'

Looping? Yes, “just Python”:

message = 'Hello'
names = ['World', 'Universe']
result = render(html('''
  <ul title="{message}">
    {[
        html('<li>{name}</li>')
        for name in names
     ] }
  </li>
'''))

Reusable components and subcomponents, passing props and children:

title = 'My Todos'
todos = ['first']


def Todo(label):
    return html('<li>{label}</li>')


def TodoList(todos):
    return html('<ul>{[Todo(label) for label in todos]}</ul>')


result = render(html('''
  <h1>{title}</h1>
  <{TodoList} todos={todos} />
'''))
# '<h1>My Todos</h1><ul><li>first</li></ul>'

Tired of passing props down a deep tree and want something like React context/hooks?

title = 'My Todos'
todos = ['first']


def Todo(label):
    prefix = use_context('prefix')
    return html('<li>{prefix}{label}</li>')


def TodoList(todos):
    return html('<ul>{[Todo(label) for label in todos]}</ul>')


result = render(html('''
  <{Context} prefix="Item: ">
      <h1>{title}</h1>
      <{TodoList} todos={todos} />
  <//>
'''))
# '<h1>My Todos</h1><ul><li>Item: first</li></ul>'

Acknowledgments

The idea and code for viewdom – the rendering, the idea of a theadlocal context, obviously tagged and htm… essentially everything – come from Joachim Viide.

Changelog

Unreleased

  • Allow VDOM to contain any kind of sequence

0.4.1

  • Change typing: VDOM is now the list/node at the top, VDOMNode is the factory and an individual triple

  • Re-organize the examples

0.4.0

  • Switch to a dataclass (frozen, slots) data structure for VDOMs, making it easy to assign type hints, do autocomplete, and have mypy get involved.

  • Add more examples and docs

0.3.0

  • Allow callable subcomponents, e.g. dataclasses with an __call__, to be rendered in html() calls

0.2.0

  • Switch docs to sphinx-book-theme and MyST

  • Publish to PyPI

0.1.0

  • First release.

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

viewdom-0.4.2.tar.gz (22.4 kB view hashes)

Uploaded Source

Built Distribution

viewdom-0.4.2-py2.py3-none-any.whl (5.7 kB view hashes)

Uploaded Python 2 Python 3

Supported by

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