API reference

class Catalog

The object that manages the components and their global settings.

Catalog(
    *,
    globals: dict[str, typing.Any] | None = None,
    filters: dict[str, typing.Any] | None = None,
    tests: dict[str, typing.Any] | None = None,
    extensions: list | None = None,
    jinja_env: jinja2.environment.Environment | None = None,
    root_url: str = '/static/components/',
    file_ext: str = '.jinja',
    use_cache: bool = True,
    auto_reload: bool = True,
    fingerprint: bool = False
) -> None
Argument Description
globals Dictionary of Jinja globals to add to the Catalog's Jinja
environment (or the one passed in jinja_env).
filters Dictionary of Jinja filters to add to the Catalog's Jinja
environment (or the one passed in jinja_env).
tests Dictionary of Jinja tests to add to the Catalog's Jinja environment
(or the one passed in jinja_env).
extensions List of Jinja extensions to add to the Catalog's Jinja environment
(or the one passed in jinja_env). The jinja2.ext.do extension
is always added at the end of these.
jinja_env Custom Jinja environment to use. This argument is useful to reuse
an existing Jinja Environment from your web framework.
root_url Add this prefix to every asset URL of the static middleware.
By default, it is /static/components/, so, for example,
the URL of the CSS file of a Card component is
/static/components/Card.css.

You can also change this argument so the assets are requested from
a Content Delivery Network (CDN) in production, for example,
root_url="https://example.my-cdn.com/".
file_ext The extensions the components files have. By default, ".jinja".
use_cache Cache the metadata of the component in memory.
auto_reload Used with use_cache. If True, the last-modified date of the
component file is checked every time to see if the cache
is up-to-date.

Set to False in production.
fingerprint If True, inserts a hash of the updated time into the URL of the
asset files (after the name but before the extension).

This strategy encourages long-term caching while ensuring that
new copies are only requested when the content changes, as any
modification alters the fingerprint and thus the filename.

WARNING: Only works if the server knows how to filter the
fingerprint to get the real name of the file.

attr collected_css attribute

List of CSS paths collected during a render.

attr collected_js attribute

List of JS paths collected during a render.

attr prefixes attribute

Mapping between folder prefixes and the Jinja loader that uses.

attr collected_css property

attr collected_js property

attr paths property

A helper property that returns a list of all the components folder paths.

attr tmpl_globals property

function add_folder

Add a folder path from which to search for components, optionally under a prefix.

add_folder(
    root_path: str | pathlib._local.Path,
    *,
    prefix: str = ''
) -> None
Argument Description
root_path Absolute path of the folder with component files.
prefix Optional prefix that all the components in the folder will have.
The default is empty.

function add_module

DEPRECATED Reads an absolute path from module.components_path and then calls Catalog.add_folder(path, prefix).

add_module(
    module: Any,
    *,
    prefix: str = ''
) -> None
Argument Description
module A Python module.
prefix An optional prefix that replaces the one the module
might include.

The prefix can also be passed as an argument instead of being read from the module.

This method exists to make it easy and consistent to have components installable as Python libraries.

function get_middleware

Wraps your application with Whitenoise, a static file serving middleware.

get_middleware(
    application: Callable,
    allowed_ext: Optional[Iterable[str]] = ('.css', '.js', '.mjs'),
    **kwargs
) -> 'ComponentsMiddleware'
Argument Description
application A WSGI application
allowed_ext A list of file extensions the static middleware is allowed to
read and return. By default, is just ".css", ".js", and ".mjs".

Technically not necessary if your components don't use static assets or if you serve them by other means. Requires the whitenoise python package to be installed.

function get_source

A helper method that returns the source file of a component.

get_source(
    cname: str,
    file_ext: str = ''
) -> str

function irender

Renders the component and subcomponents inside of it without resetting the collected_css and collected_js lists.

irender(
    /,
    _Catalog__name: str,
    *,
    caller: Optional[Callable] = None,
    **kw
) -> str

This is the method you should call to render individual components that are later inserted into a parent template.

function render

Resets the collected_css and collected_js lists and renders the component and subcomponents inside of it.

render(
    /,
    _Catalog__name: str,
    *,
    caller: Optional[Callable] = None,
    **kw
) -> str
Argument Description
__name The name of the component to render, e.g. "Page" or
"ui.Button".
caller An optional callable that returns the content of the
component, as Jinja's {% call %} does.
_globals An optional dictionary of extra template globals. They are
available to the rendered component and to every component
nested inside it, for the duration of this call only.
Use it for per-request data like the current request or
the current user. Any other keyword argument is passed to
the component as a regular argument.

This is the method you should call to render a parent component from a view/controller in your app.

function render_assets

Placeholder for assets injection. During rendering this emits a unique token; after the full template is rendered, the token is replaced with all collected CSS/JS asset tags, regardless of ordering in the template.

render_assets() -> str

class LazyString

Behave like regular strings, but the actual casting of the initial value is deferred until the value is actually required.

LazyString(
    seq
)

Bases: UserString

class HTMLAttrs

Contains all the HTML attributes/properties (a property is an attribute without a value) passed to a component but that weren't in the declared attributes list.

HTMLAttrs(
    attrs: 'dict[str, t.Any| LazyString]'
) -> None

For HTML classes you can use the name "classes" (instead of "class") if you need to.

NOTE: The string values passed to this class, are not cast to str until the string representation is actually needed, for example when attrs.render() is invoked.

attr as_dict property

An ordered dict of all the attributes and properties, both sorted by name before join.

Example:

attrs = HTMLAttrs({
"class": "lorem ipsum",
"data_test": True,
"hidden": True,
"aria_label": "hello",
"id": "world",
})
attrs.as_dict
{
    "aria-label": "hello",
    "class": "lorem ipsum",
    "id": "world",
    "data-test": True,
    "hidden": True
}

attr classes property

All the HTML classes separated by a space.

Example:

attrs = HTMLAttrs({"class": "italic bold bg-blue wide abcde"})
attrs.set(class="bold text-white")
print(attrs.classes)
italic bold bg-blue wide abcde text-white

function add_class

Adds one or more classes to the end of the list of classes, if not already present.

add_class(
    *values: str
) -> None

Example:

attrs = HTMLAttrs({"class": "a b c"})
attrs.add_class("c d")
attrs.as_dict
{"class": "a b c d"}

function get

Returns the value of the attribute or property, or the default value if it doesn't exists.

get(
    name: str,
    default: Any = None
) -> Any

Example:

attrs = HTMLAttrs({"lorem": "ipsum", "hidden": True})

attrs.get("lorem", defaut="bar")
'ipsum'

attrs.get("foo")
None

attrs.get("foo", defaut="bar")
'bar'

attrs.get("hidden")
True

function prepend_class

Adds one or more classes to the beginning of the list of classes, if not already present.

prepend_class(
    *values: str
) -> None

Example:

attrs = HTMLAttrs({"class": "a b c"})
attrs.prepend_class("c d |")
attrs.as_dict
{"class": "d | a b c"}

function remove_class

Removes one or more classes from the list of classes.

remove_class(
    *names: str
) -> None

Example:

attrs = HTMLAttrs({"class": "a b c"})
attrs.remove_class("c", "d")
attrs.as_dict
{"class": "a b"}

function render

Renders the attributes and properties as a string.

render(
    **kw
) -> str

Any arguments you use with this function are merged with the existing attibutes/properties by the same rules as the HTMLAttrs.set() function:

  • Pass a name and a value to set an attribute (e.g. type="text")
  • Use True as a value to set a property (e.g. disabled)
  • Use False to remove an attribute or property
  • If the attribute is "class", the new classes are appended to the old ones (if not repeated) instead of replacing them.
  • The underscores in the names will be translated automatically to dashes, so aria_selected becomes the attribute aria-selected.

To provide consistent output, the attributes and properties are sorted by name and rendered like this: <sorted attributes> + <sorted properties>.

Example:

attrs = HTMLAttrs({"class": "ipsum", "data_good": True, "width": 42})

attrs.render()
'class="ipsum" width="42" data-good'

attrs.render(class="abc", data_good=False, tabindex=0)
'class="ipsum abc" tabindex="0" width="42"'

function set

Sets an attribute or property

set(
    **kw
) -> None
  • Pass a name and a value to set an attribute (e.g. type="text")
  • Use True as a value to set a property (e.g. disabled)
  • Use False to remove an attribute or property
  • If the attribute is "class", the new classes are appended to the old ones (if not repeated) instead of replacing them.
  • The underscores in the names will be translated automatically to dashes, so aria_selected becomes the attribute aria-selected.

Example:

attrs = HTMLAttrs({"secret": "qwertyuiop"})
attrs.set(secret=False)
attrs.as_dict
{}

attrs.set(unknown=False, lorem="ipsum", count=42, data_good=True)
attrs.as_dict
{"count":42, "lorem":"ipsum", "data-good": True}

attrs = HTMLAttrs({"class": "b c a"})
attrs.set(class="c b f d e")
attrs.as_dict
{"class": "b c a f d e"}

function setdefault

Adds an attribute, but only if it's not already present.

setdefault(
    **kw
) -> None

The underscores in the names will be translated automatically to dashes, so aria_selected becomes the attribute aria-selected.

Example:

attrs = HTMLAttrs({"lorem": "ipsum"})
attrs.setdefault(tabindex=0, lorem="meh")
attrs.as_dict
# "tabindex" changed but "lorem" didn't
{"lorem": "ipsum", tabindex: 0}

Exceptions

class ComponentNotFound

Raised when JinjaX can't find a component by name in none of the added folders, probably because of a typo.

ComponentNotFound(
    name: str,
    file_ext: str
) -> None

Bases: Exception

class MissingRequiredArgument

Raised when a component is used/invoked without passing one or more of its required arguments (those without a default value).

MissingRequiredArgument(
    component: str,
    arg: str
) -> None

Bases: Exception

class DuplicateDefDeclaration

Raised when a component has more then one {#def ... #} declarations.

DuplicateDefDeclaration(
    component: str
) -> None

Bases: Exception

class InvalidArgument

Raised when the arguments passed to the component cannot be parsed by JinjaX because of an invalid syntax.

InvalidArgument(
    /,
    *args,
    **kwargs
)

Bases: Exception

class UnknownPrefix

Raised when a component is used/invoked with a prefix that is not registered.

UnknownPrefix(
    name: str
) -> None

Bases: Exception