-
Does anyone know of a way to give each JinjaX component its own python module? I'll explain... There's a library called django-components. With that library, each component gets its own python module:
That's great, but I dislike how you use your components with the django-components library:
I prefer how you can use the components as HTML tags with JinjaX (like My use case for that would be suppose I'm using tailwind and I want to create a UI component like a button with many variants. You'll need some logic to build the list of class names for the class attribute. It would be nice to put that logic in the python module of the component. So does anyone have a clean way to do that with JinjaX? |
Beta Was this translation helpful? Give feedback.
Replies: 4 comments
-
The current way to do it is inside the template which, I have to admit, can be very cumbersome. Badge.jinja {#def color="gray", href=None #}
{% if color == "green" %}
{% do attrs.set(
class="bg-green-100 border-green-200 text-green-600" + (" hover:bg-green-200" if href else "")
) %}
{% elif color == "red" %}
{% do attrs.set(
class="bg-red-100 border-red-200 text-red-600" + (" hover:bg-red-200" if href else "")
) %}
{% elif color == "yellow" %}
{% do attrs.set(
class="bg-yellow-100 border-yellow-200 text-yellow-600" + (" hover:bg-yellow-200" if href else "")
) %}
{% elif color == "blue" %}
{% do attrs.set(
class="bg-blue-100 border-blue-200 text-blue-600" + (" hover:bg-blue-200" if href else "")
) %}
{% else %}
{% do attrs.set(
class="bg-gray-100 border-gray-200 text-gray-600" + (" hover:bg-gray-200" if href else "")
) %}
{% endif %}
<a {{ attrs.render(href=href, class="inline-flex items-center p-1 border
rounded-sm text-sm select-none font-medium tracking-tight") }}>{{ content }}</a> However, it can be done a little better using dicts: {#def color="gray", href=None #}
{% set color_ops = {
"green": "bg-green-100 border-green-200 text-green-600",
"red": "bg-red-100 border-red-200 text-red-600",
"yellow": "bg-yellow-100 border-yellow-200 text-yellow-600",
"blue": "bg-blue-100 border-blue-200 text-blue-600",
"default": "bg-gray-100 border-gray-200 text-gray-600",
} %}
{% set href_ops = {
"green": "hover:bg-green-200",
"red": "hover:bg-red-200",
"yellow": "hover:bg-yellow-200",
"blue": "hover:bg-blue-200",
"default": "hover:bg-gray-200",
} %}
{% do attrs.set(class=color_ops.get(color, color_ops["default"])) %}
{% do attrs.set(class=href_ops.get(color, href_ops["default"]) if href else "") %}
<a {{ attrs.render(href=href, class="inline-flex items-center p-1 border
rounded-sm text-sm select-none font-medium tracking-tight") }}>{{ content }}</a> |
Beta Was this translation helpful? Give feedback.
-
I was thinking on searching/writing a Jinja "eval" tag that could run python code (just expressions, no imports) to modify the template context, something like this (currently not real, just an idea): {#def color="gray", href=None #}
{% eval %}
color_ops = {
"green": "bg-green-100 border-green-200 text-green-600",
"red": "bg-red-100 border-red-200 text-red-600",
"yellow": "bg-yellow-100 border-yellow-200 text-yellow-600",
"blue": "bg-blue-100 border-blue-200 text-blue-600",
"default": "bg-gray-100 border-gray-200 text-gray-600",
}
href_ops = {
"green": "hover:bg-green-200",
"red": "hover:bg-red-200",
"yellow": "hover:bg-yellow-200",
"blue": "hover:bg-blue-200",
"default": "hover:bg-gray-200",
}
attrs.set(class=color_ops.get(color, color_ops["default"]))
if href:
attrs.set(class=href_ops.get(color, href_ops["default"]))
{% endeval %}
<a {{ attrs.render(href=href, class="inline-flex items-center p-1 border
rounded-sm text-sm select-none font-medium tracking-tight") }}>{{ content }}</a> |
Beta Was this translation helpful? Give feedback.
-
However, a separated Python file:
... I want to make it optional though, so it would be not like django components where the python file is central... maybe JinjaX could call a function in the python file (is there is one) instead: def get_context(args: dict[str, Any], **globals) -> dict[str, Any]:
"""Return the context data available to the component.
"""
...
return args So, for example Badge.py color_ops = {
"green": "bg-green-100 border-green-200 text-green-600",
"red": "bg-red-100 border-red-200 text-red-600",
"yellow": "bg-yellow-100 border-yellow-200 text-yellow-600",
"blue": "bg-blue-100 border-blue-200 text-blue-600",
"default": "bg-gray-100 border-gray-200 text-gray-600",
}
href_ops = {
"green": "hover:bg-green-200",
"red": "hover:bg-red-200",
"yellow": "hover:bg-yellow-200",
"blue": "hover:bg-blue-200",
"default": "hover:bg-gray-200",
}
def get_context(args: dict[str, Any], **globals) -> dict[str, Any]:
"""Return the context data available to the component.
"""
attrs = args["attrs"]
attrs.set(class=color_ops.get(color, color_ops["default"]))
if href:
attrs.set(class=href_ops.get(color, href_ops["default"]))
return args Any suggestion? |
Beta Was this translation helpful? Give feedback.
-
Thank you for the detailed reply! I like the idea of the separated Python file as opposed to an eval tag for the same reasons. I may want to import something into the Python file to help manage the list of class names. I also like the idea of the Python file not being required, and of course you wouldn't want everyone upgrading to a new version of JinjaX to suddenly have to add Python files to each component. I can't think of any other suggestions besides that. For me it's difficult to think of something until I start using it. Also, I appreciate the suggestions for how I might implement that with the current version of JinajX. I'm coming from the Angular/React world. I'm still a bit new to Python. I will try those suggestions for now to see how far that gets me. |
Beta Was this translation helpful? Give feedback.
The current way to do it is inside the template which, I have to admit, can be very cumbersome.
For example:
Badge.jinja