Skip to content

Customably extend jinja 2 template namespace #13477

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
ego-thales opened this issue Apr 10, 2025 · 1 comment
Open

Customably extend jinja 2 template namespace #13477

ego-thales opened this issue Apr 10, 2025 · 1 comment
Labels
type:proposal a feature suggestion

Comments

@ego-thales
Copy link

ego-thales commented Apr 10, 2025

Hello,

I'd like to propose a feature to extend the namespace available to jinja2 templates

Currently, the following are available (some only on classes or modules):

name
objname
fullname
objtype
module
class
underline
members
inherited_members
functions
classes
exceptions
methods
attributes
modules

The proposed feature would allow custom extensions of this namespace, base on a extend-autosummary-template-content event. A minimal use case would be the following template.

.. _templates/dataclass.rst

Is this dataclass frozen?
{{ frozen }}

More in the next message (this one was largely edited after further investigation from my side).

@ego-thales ego-thales added the type:proposal a feature suggestion label Apr 10, 2025
@ego-thales
Copy link
Author

ego-thales commented Apr 11, 2025

Hello again,

I looked a bit at the source code and understood the following.

  1. The easiest way to add context is via the autosummary_context dict variable in conf.py, but this is global to the configuration and does not allow per-object spec.

  2. Internally, the namespace for available variables in templates is generated and used here:

    def generate_autosummary_content(

For a class for example, the following snippet does most of the populating:

elif doc.objtype == 'class':
ns['members'] = dir(obj)
ns['inherited_members'] = set(dir(obj)) - set(obj.__dict__.keys())
ns['methods'], ns['all_methods'] = _get_members(
doc,
obj,
{'method'},
config=config,
events=events,
registry=registry,
include_public={'__init__'},
)
ns['attributes'], ns['all_attributes'] = _get_members(
doc,
obj,
{'attribute', 'property'},
config=config,
events=events,
registry=registry,
)

So I think in the end, it would be very easy to add a extend-autosummary-template-content event that would essentially be used in the flavor of

# addition to `sphinx.sphinx.ext.autosummary.generate.generate_autosummary_content`

ns.update(_get_context_extension(
            doc,
            obj,
            what,
            config=config,
            events=events,
            registry=registry,
            imported=imported_members,
        )  # exact signature to figure out
)

that would call a user-defined function:

# conf.py

def extend_template_content(doc, obj, what, options):  # exact signature to figure out
    """Extend template content namespace with custom fields.

    Example: only for dataclasses, add the `frozen` attribute to report class state.
    """
    ext = {}
    if what == "class" and is_dataclass(obj):
        ext["frozen"] = obj.__dataclass_params__.frozen

    return ext


def setup(app):
    app.connect("extend-autosummary-template-content", extend_template_content)

This simple user-side configuration would make the following template possible.

.. _templates/dataclass.rst

Is this dataclass frozen?
{{ frozen }}

What do you think about this feature? I think it would simplify so much customization!

@ego-thales ego-thales changed the title Add any variable to template context Customably extend jinja 2 template namespace Apr 11, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type:proposal a feature suggestion
Projects
None yet
Development

No branches or pull requests

1 participant