viewdom_wired: Container and DI for viewdom
¶
Pluggability for Templates and Components
Let’s say you share some nice components. You want them to work in different systems: Sphinx, Pelican, Flask, etc. You also want to make it easy to extend or customize without having to fork.
viewdom_wired
brings pluggability and flexibility to viewdom templates and components.
With dependency injection and containers from wired, the components in your pluggable apps are now swappable, easier to write and test, and less brittle.
Note
This is for people who want to make or consume a pluggable system. If that’s not you, then it’s unneeded complexity/magic.
Installation¶
For Python 3.7+:
$ pip install viewdom_wired
For Python 3.6, you’ll need the dataclasses
backport.
Minimum Example¶
Let’s write a Greeting
component.
It expects to be passed a first_name
:
@component()
@dataclass
class Greeting:
first_name: str
def __call__(self) -> VDOM:
return html('<h1>Hello {self.first_name}</h1>')
You can then render a template which passes in first_name
as a string:
result = render(html('<{Greeting} first_name="World"/>'), container)
Don’t want to pass data down long component trees? Tell the injector to use a pipeline to get it:
first_name: Annotated[str, Get(Settings, attr='first_name')]
Want to use that, but some of the time, manually pass in a prop to the component to override the injected value? Do so, and use an expression as the prop value:
first_name = "Prop" # noqa: F841
result = render(html('<{Greeting} first_name={first_name} />'), container)
How It Works¶
viewdom_wired
changes the viewdom
rendering to use the wired_injector
.
It transparently wires up an InjectorContainer
for the rendering, provides a @component
decorator to turn on use_props
, and pass long system_props
such as children
, parent_component
, and whatever you pass into the render.