Feature proposal: Simple block tag

Django’s template system allows creating custom tags, but they don’t allow taking content:

{% mysimpletag foo="bar" %}

However there are plenty of use-cases where it’d be useful to also collect content along with the tag, turning it into a “block” tag:

{% mysimpletag foo="bar" %}
  This content gets captured too
{% endmysimpletag %}

This currently requires using complex internals of the template system (some documented, some not) to achieve. The cache tag is a good example of this kind of “simple” block, which requires some parser internals.

I propose adding a @register.simple_block method to allow easy registering of custom block tags. The API would be similar to simple_tag, however with a required content argument containing the (rendered) template content:

@register.simple_block(takes_context=True)
def mysimpletag(context: Context, content: str, foo: str) -> str:
    return f"foo = {foo}"

I raised a ticket about this, but was pointed here as a better way of collecting interest. I already have a working demo of this working.

1 Like

I’m +1 in the general direction here. (There’s are any number of historical threads asking for related ideas.)

FWIW, assuming some as integration, I think it’s #6378 (Capture arbitrary output as a template variable) – Django revisited :sweat_smile:

1 Like

You can take a look at https://github.com/rails-inspire-django/django-viewcomponent

With the slot feature, you can pass huge HTML to the component and then do some operation.

It has helped me solved similar problems in some projects.

Yes… — that’s a nice package @michael-yin.

There are several in this space. The danger is we get into a never ending discussion about which features to add. (This happens a lot :sweat_smile:)

Simple, to the point, covers the 80% case is probably enough for an addition to Django itself here, leaving space in the ecosystem for folks to explore more advanced options.

+1 from me. I have missed this in the past.

Presumably it will allow both positional and keyword arguments, like simple_tag. They would need to be checked for collision with the name content.

I suggest the name simple_block_tag to retain the naming scheme of simple_tag and inclusion_tag.

Where?

Indeed, this would be called “simple” for that reason.

Absolutely! We can reuse much of the implementation of simple_tag to keep many of the same semantics. Validating the overlap of the content argument is something I’d missed, but assuming simple_tag does the same, I should be able to share some of the implementation.

It was in a private repo when I opened the ticket, but I recently pushed up a branch to start integrating it with Django core. It’s still very rough, and missing “important” things like tests, but the basics are there: GitHub - RealOrangeOne/django at 35535-simple-block-tag. Hoping to get around to finishing it off and writing the related in the next week or so to get a draft PR up.

2 Likes

I’m late but also +1.

It might be useful to document an example use-case for it, so people have an idea when to use it.

et voilà: Fixed #35535 -- Add simple block tag by RealOrangeOne · Pull Request #18343 · django/django · GitHub