Open lorddaedra opened 3 years ago
So my idea: set page_component
on view level or set dict with pairs url_pattern
(or view name
): page_component
and load first level components dynamically for all pages.
I suggest to add this feature:
UNICORN = {
"DEFAULT_COMPONENT_NAME": '', # empty str by default (same behaviour) or in format 'some.module:function', function MUST accept view
}
for example,
settings.py:
UNICORN = {
"DEFAULT_COMPONENT_NAME_GETTER": 'frontend.utils:get_default_component_name',
}
base.html:
{% load static unicorn %}<!doctype html>
<html>
<head>
<meta charset="UTF-8">
{% unicorn_scripts %}
</head>
<body>
{% csrf_token %}
{% unicorn %}
</body>
</html>
urls.py:
path('', views.home_view, name='home'),
frontend.utils.py:
get_default_component_name(view):
return view.request.resolver_match.url_name
Returns 'home' if {% unicorn %}
is used in home_view
template so it's equal to {% unicorn 'home' %}
(It should work because of view is attached by django.views.generic.base.ContextMixin to context_data so you can get view
from context in template layer)
Benefits for users: users can create url patterns with names related to page component names and use single base.html for all pages.
This is way to remove tons of templates like:
{% extends "base.html" %}{% load unicorn %}
{% block body %}
{% unicorn 'home' %}
{% endblock %}
This is an interesting idea! Let me think about it and see what makes the most sense to me. I should have time in a day or two to try out some ideas.
My initial reactions:
DEFAULT_COMPONENT_NAME_GETTER
setting feels to me like it's removing some of the explicitness. Although, I do like that this be an opt-in feature -- just not sure it's worth the complexity in code.One other thought: another approach for this same problem would be something like https://github.com/adamghill/django-unicorn/issues/179, right?
I like idea of dynamic components. Something like https://v3.vuejs.org/api/built-in-components.html#component I think this is required feature for some complex projects.
About DEFAULT_COMPONENT_NAME_GETTER
- it's just one of the possible implementations. May be it's not the best way to do it. It just allows to map url patterns/views to page components without creating page templates for views.
About problem. I think it's about how to implement root node of components tree, page router and page components (next to root node). We may use django default router (urls.py, urlpatterns), why not. But we would like to use components instead of traditional views&templates because of we can reload it without full page refresh.
So if we will try to combine views with components at the end we will see that we do not need templates and move all things to page components. And our templates will be something like
{% extends "base.html" %}{% load unicorn %}
{% block body %}
{% unicorn 'home' %}
{% endblock %}
So just single main/base/home template and helper templates for views. And all other things inside components/component templates.
May be we can somehow do not create these view templates at all and create views directly from components. So, yes, #179 is about it. Another implementation.
I think this is also related topic https://github.com/adamghill/django-unicorn/issues/183
How to load page components by component name stored in variable or returned by function?
views.py:
base.html:
Traceback (most recent call last):