Guides

Components

Declaring and using components.

class jinjax.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
ArgumentDescription
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.

The object that manages the components and their global settings.

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.

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

attr tmpl_globals property  

method 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
ArgumentDescription
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.

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

method 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
ArgumentDescription
module

A Python module.

prefix

An optional prefix that replaces the one the module might include.

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

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.

method 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'
ArgumentDescription
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".

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

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.

method get_source  

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

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

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

method 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

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

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

method 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

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

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

method 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

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.


class jinjax.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

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

class jinjax.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

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.

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.

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.

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 

method add_class  

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

add_class(*values: str) -> None

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

Example:

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

method 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

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

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 

method prepend_class  

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

prepend_class(*values: str) -> None

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

Example:

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

method remove_class  

Removes one or more classes from the list of classes.

remove_class(*names: str) -> None

Removes one or more classes from the list of classes.

Example:

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

method render  

Renders the attributes and properties as a string.

render(**kw) -> str

Renders the attributes and properties as a string.

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"' 

method set  

Sets an attribute or property

set(**kw) -> None

Sets an attribute or property

  • 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"} 

method setdefault  

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

setdefault(**kw) -> None

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

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 jinjax.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

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

class jinjax.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

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

class jinjax.DuplicateDefDeclaration  

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

DuplicateDefDeclaration(component: str) -> None

Bases: Exception

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

class jinjax.InvalidArgument  

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

InvalidArgument(/, *args, **kwargs)

Bases: Exception

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

class jinjax.UnknownPrefix  

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

UnknownPrefix(name: str) -> None

Bases: Exception

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