Metadata-Version: 2.1
Name: viewdom
Version: 0.4.2
Summary: View layer for Python VDOMs
Home-page: https://viewdom.readthedocs.io
Author: Paul Everitt
Author-email: pauleveritt@me.com
License: UNKNOWN
Keywords: web,html,components,templates
Platform: UNKNOWN
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Natural Language :: English
Classifier: Programming Language :: Python :: 3.6
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Programming Language :: Python :: Implementation :: PyPy
Requires-Python: >=3.6
Description-Content-Type: text/x-rst
Requires-Dist: tagged
Requires-Dist: htm
Requires-Dist: MarkupSafe
Requires-Dist: typing-extensions (>=3.7.4) ; python_version < "3.8"
Provides-Extra: dev
Requires-Dist: mypy ; extra == 'dev'
Requires-Dist: coverage ; extra == 'dev'
Requires-Dist: pytest-coverage ; extra == 'dev'
Requires-Dist: tox ; extra == 'dev'
Requires-Dist: black ; extra == 'dev'
Requires-Dist: flake8 ; extra == 'dev'
Requires-Dist: twine ; extra == 'dev'
Requires-Dist: pre-commit ; extra == 'dev'
Requires-Dist: check-manifest ; extra == 'dev'
Provides-Extra: docs
Requires-Dist: Sphinx ; extra == 'docs'
Requires-Dist: sphinx-book-theme ; extra == 'docs'
Requires-Dist: myst-parser ; extra == 'docs'
Provides-Extra: tests
Requires-Dist: pytest ; extra == 'tests'

viewdom
=======

`Docs <https://viewdom.readthedocs.io/en/latest/>`_ and `Code <https://github.com/pauleveritt/viewdom>`_


``viewdom`` brings modern frontend templating patterns to Python:

- `tagged <https://github.com/jviide/tagged>`_ to have language-centered templating (like JS tagged templates)
- `htm.py <https://github.com/jviide/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:

.. code-block:: bash

  $ pip install viewdom

.. note::

    ``viewdom`` depends on `htm` which depends on ``tagged``.
    No other dependencies, although some of the optional ``viewdom``
    integrations pull in other packages.

Quick Examples
==============

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

.. code-block:: python

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

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

.. code-block:: python

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

Insert variables from the local or global scope:

.. code-block:: python

    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:

.. code-block:: python

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

Rendering something conditionally is also "just Python":

.. code-block:: 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":

.. code-block:: 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:

.. code-block:: python

    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?

.. code-block:: python

    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 <https://github.com/jviide>`_.


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.


