Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion djangocms_frontend/component_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ def _get_mixin_classes(mixins: list, suffix: str = "") -> list[type]:
(mixin.rsplit(".")[0], f"{mixin.rsplit('.')[-1]}{suffix}Mixin")
if "." in mixin
else ("djangocms_frontend.common", f"{mixin}{suffix}Mixin")
for mixin in mixins
for mixin in reversed(mixins)
]

return [_import_or_empty(module, name) for module, name in mixins]
Expand Down
11 changes: 8 additions & 3 deletions djangocms_frontend/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,8 @@ def add_attribute(self, attr, value=None):

def get_attributes(self):
attributes = self.config.get("attributes", {})
classes = set(attributes.get("class", "").split()) # classes added in attriutes
classes.update(self._additional_classes) # add additional classes
classes = (f'class="{conditional_escape(" ".join(classes))}"') if classes else "" # to string
classes = self.get_classes() # get classes
classes = (f'class="{classes}"') if classes else "" # to string
parts = (
f'{item}="{conditional_escape(value)}"' if value else f"{item}"
for item, value in attributes.items()
Expand All @@ -87,6 +86,12 @@ def get_attributes(self):
attributes_string = (classes + " ".join(parts)).strip()
return mark_safe(" " + attributes_string) if attributes_string else ""

def get_classes(self):
attributes = self.config.get("attributes", {})
classes = set(attributes.get("class", "").split()) # classes added in attriutes
classes.update(self._additional_classes) # add additional classes
return conditional_escape(" ".join(classes))

def save(self, *args, **kwargs):
self.ui_item = self.__class__.__name__
return super().save(*args, **kwargs)
Expand Down
4 changes: 3 additions & 1 deletion docs/source/tutorial/template_components.rst
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,9 @@ The fields declared earlier (``title``, ``slogan``, and ``hero_image``) are now
<img src="{{ hero_image.url }}">

The ``{% childplugins %}`` block allows additional CMS plugins (like buttons) to be added inside the component
in the structure editor.
in the structure editor. Anything in between ``{% childplugins %}`` and ``{% endchildplugins %}`` will only be
rendered if the component has no children.


Make the component available in django CMS
-------------------------------------------
Expand Down
Empty file added examples/__init__.py
Empty file.
Empty file added examples/migrations/__init__.py
Empty file.
32 changes: 32 additions & 0 deletions examples/templates/examples/cms_components/feature_hanging.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{% load frontend cms_component djangocms_link_tags sekizai_tags icon_tags %}

{% cms_component "FeatureHanging" name=_("Feature hanging") module=_("Examples") mixins="Background|Spacing|Attributes"|split %}
{% field "icon" IconPickerField required=True label=_("Icon") initial="chevron-right" %}
{% field "title" forms.CharField required=True label=_("Title") initial=_("Featured title") %}
{% field "description" HTMLFormField required=True label=_("Description") initial=_("<p>Paragraph of text beneath the heading to explain the heading. We'll add onto it with another sentence and probably just keep going until we run out of words.</p>") %}
{% field "call_to_action" forms.CharField required=True label=_("Call to action") initial=_("Call to action") %}
{% field "link" LinkFormField required=True label=_("Link") initial="#"|to_link %}

{% add_css_for_icon icon %}
<div class="d-flex align-items-start {{ instance.get_classes }}">
<div class="icon-square text-body-emphasis bg-body-secondary d-inline-flex align-items-center justify-content-center fs-4 flex-shrink-0 me-3">
{% icon icon %}
</div>
<div>
<h3 class="fs-2 text-body-emphasis">{% inline_field "title" %}</h3>
{% inline_field instance "description" "" "safe" %}
<a href="{{ link|to_url }}" class="btn btn-primary">
{{ call_to_action }}
</a>
</div>
</div>

{% addtoblock "css" %}
<style>
.icon-square {
width: 3rem;
height: 3rem;
border-radius: .75rem;
}
</style>
{% endaddtoblock %}
36 changes: 36 additions & 0 deletions examples/templates/examples/cms_components/feature_icon.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{% load frontend cms_component djangocms_link_tags sekizai_tags icon_tags %}

{% cms_component "FeatureIcon" name=_("Feature with icon") module=_("Examples") mixins="Background|Spacing|Attributes"|split %}
{% field "icon" IconPickerField required=True label=_("Icon") initial="chevron-right" %}
{% field "title" forms.CharField required=True label=_("Title") initial=_("Featured title") %}
{% field "description" HTMLFormField required=True label=_("Description") initial=_("<p>Paragraph of text beneath the heading to explain the heading. We'll add onto it with another sentence and probably just keep going until we run out of words.</p>") %}
{% field "call_to_action" forms.CharField required=True label=_("Call to action") initial=_("Call to action") %}
{% field "link" LinkFormField required=True label=_("Link") initial="#"|to_link %}

{% add_css_for_icon icon %}
<div class="feature {{ instance.get_classes }}">
<div class="feature-icon d-inline-flex align-items-center justify-content-center text-bg-primary bg-gradient fs-2 mb-3">
{% icon icon %}
</div>
<h3 class="fs-2 text-body-emphasis">{% inline_field "title" %}</h3>
{% inline_field instance "description" "" "safe" %}
<a href="{{ link|to_url }}" class="icon-link">
{{ call_to_action }}
<svg class="bi"><use xlink:href="#chevron-right"/></svg>
</a>
</div>

{% addtoblock "css" %}
<svg xmlns="http://www.w3.org/2000/svg" class="d-none">
<symbol id="chevron-right" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708"/>
</symbol>
</svg>
<style>
.feature-icon {
width: 4rem;
height: 4rem;
border-radius: .75rem;
}
</style>
{% endaddtoblock %}
15 changes: 15 additions & 0 deletions examples/templates/examples/cms_components/icon_grid.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{% load frontend cms_component djangocms_link_tags sekizai_tags icon_tags %}

{% cms_component "IconGrid" name=_("Icon grid") module=_("Examples") mixins="Background|Spacing|Attributes"|split %}
{% field "icon" IconPickerField required=True label=_("Icon") %}
{% field "title" forms.CharField required=True label=_("Title") initial=_("Featured title") %}
{% field "description" HTMLFormField required=True label=_("Description") initial=_("<p>Paragraph of text beneath the heading to explain the heading. We'll add onto it with another sentence and probably just keep going until we run out of words.</p>") %}

{% add_css_for_icon icon %}
<div class="col d-flex align-items-start {{ instance.get_classes }}">
<span class="fs-4 me-3">{% icon icon %}</span>
<div>
<h3 class="fw-bold mb-0 fs-4 text-body-emphasis">{% inline_field "title" %}</h3>
{% inline_field instance "description" "" "safe" %}
</div>
</div>