Using a components library? (e.g. django-components or JinjaX) #261
-
|
Hello, on the documentation website under "Related projects" a number of component libraries like django-components and JinjaX are listed as "complementary" packages. The question is, what would be the best way to go about using them? My guess would be to define the components in one place outside the patterns directory, and then in the patterns directory define small wrappers around the components which just call the components. Here is an example using JinjaX: {# components/message.html.jinja #}
{#def class, title #}
<div class="{{ class }}">
<h3>{{ title }}</h3>
<p>{{ content }}</p>
</div>Then the patterns {# pattern/molecules/message_box/warning.html.jinja #}
{% block content %}
{% call catalog.irender("Message", class="warning", title="My warning") %}
This is some warning message
{% endcall %}
{% endblock %}{# pattern/molecules/message_box/error.html.jinja #}
{% block content %}
{% call catalog.irender("Message", class="error", title="My error") %}
This is some error message
{% endcall %}
{% endblock %}This would also allow me to have multiple variants of the same component as separate patterns. In this setup patterns are just for displaying in the pattern library frontend, but not for building actual pages. Is this the way to go or is there a better approach? |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments
-
|
Hey @HiPhish, the original design idea for django-pattern-library was that you would directly point it at the components’ source, and use |
Beta Was this translation helpful? Give feedback.
-
|
Follow-up: I decided to go with storybook-django and skip over django-pattern-library completely. Instead I have a custom app which implements the API of pattern-library, but interprets the request to render the component. This custom adapter consists of just a single URL ( class ComponentRenderOnDemand(View):
"""Renders a django-components component from an HTTP request.
All slots are marked as safe because this app is only meant to be used for
development where we can trust the users.
"""
def post(self, request: HttpRequest) -> HttpResponse:
"""Reads the component and context from the body of the request."""
body = json.loads(request.body)
context = body['config']['context']
[module, class_name] = body['template_name'].rsplit('.', 1)
klass = getattr(import_module(module), class_name)
response: HttpResponse = klass.render_to_response(
args=context.get('args', []),
kwargs=context.get('kwargs', {}),
slots={key: mark_safe(value) for key, value in context.get('slots', {}).items()},
)
return responseIt uses the ability of django-components to render a component to HTML. The template name of the pattern becomes the name of the component. Then I can write my story like this: const context = {
kwargs: {
items: [
{title: 'Foo', url: '#'},
{title: 'Bar', url: '#'}
]
}
};
return <Pattern template="pages.components.molecule.MenuBar" context={context} />;This way I don't have write any YAML files. I think my original idea works well for people who don't want to bring in Storybook, while this custom adapter work better for people who do actually want Storybook. In that case writing both stories and YAML patterns would be redundant. |
Beta Was this translation helpful? Give feedback.
Hey @HiPhish, the original design idea for django-pattern-library was that you would directly point it at the components’ source, and use
.yamlfiles to provide the demo content. However that currently doesn’t support multiple variants – so your approach could be decent!