-
Notifications
You must be signed in to change notification settings - Fork 86
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This won't make it because djangocms-text-ckeditor has a bug with inline forms, newly added item does not properly initialize the CKEditor Javascript django-cms/djangocms-text-ckeditor#680 So finally we need to make slide item through children plugin of SliderPlugin.
- Loading branch information
Showing
12 changed files
with
439 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
from django.contrib import admin | ||
from django.utils.translation import gettext_lazy as _ | ||
|
||
from .models import SlideItem | ||
from .forms import SlideItemForm | ||
|
||
|
||
class SlideItemAdmin(admin.StackedInline): | ||
""" | ||
Plugin admin form to enable inline mode inside SliderPlugin | ||
""" | ||
model = SlideItem | ||
form = SlideItemForm | ||
extra = 0 | ||
verbose_name = _("Slide") | ||
ordering = ["order"] | ||
fieldsets = [ | ||
(None, { | ||
"fields": ( | ||
"slider", | ||
), | ||
}), | ||
(_("Content"), { | ||
"fields": ( | ||
"title", | ||
"image", | ||
"link_url", | ||
"content", | ||
), | ||
}), | ||
(_("Options"), { | ||
"fields": ( | ||
"order", | ||
"link_open_blank", | ||
), | ||
}), | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
""" | ||
Slider CMS plugin | ||
""" | ||
|
||
from django.utils.translation import gettext_lazy as _ | ||
|
||
from cms.plugin_base import CMSPluginBase | ||
from cms.plugin_pool import plugin_pool | ||
|
||
from richie.apps.core.defaults import PLUGINS_GROUP | ||
|
||
from .admin import SlideItemAdmin | ||
from .forms import SliderForm | ||
from .models import Slider | ||
|
||
|
||
@plugin_pool.register_plugin | ||
class SliderPlugin(CMSPluginBase): | ||
""" | ||
Slider interface is able to add/edit/remove slide items as inline forms. | ||
""" | ||
cache = True | ||
module = PLUGINS_GROUP | ||
name = _("Slider") | ||
model = Slider | ||
form = SliderForm | ||
inlines = (SlideItemAdmin,) | ||
render_template = "richie/slider/slider.html" | ||
fieldsets = ( | ||
(None, {"fields": ["title"]}), | ||
) | ||
|
||
def render(self, context, instance, placeholder): | ||
context.update({ | ||
"instance": instance, | ||
"placeholder": placeholder, | ||
"slides": instance.slide_item.all().order_by("order") | ||
}) | ||
return context |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
""" | ||
Slider CMS plugin factories | ||
""" | ||
|
||
import factory | ||
import faker | ||
|
||
from .models import Slider, SlideItem | ||
|
||
|
||
class SliderFactory(factory.django.DjangoModelFactory): | ||
""" | ||
Factory to create instance of a Slider. | ||
""" | ||
title = factory.Faker("text", max_nb_chars=20) | ||
|
||
class Meta: | ||
model = Slider | ||
|
||
|
||
class SlideItemFactory(factory.django.DjangoModelFactory): | ||
""" | ||
Factory to create instance of a SlideItem. | ||
""" | ||
slider = factory.SubFactory(SliderFactory) | ||
title = factory.Faker("text", max_nb_chars=20) | ||
content = factory.Faker("text", max_nb_chars=42) | ||
order = factory.Sequence(lambda n: 10 * n) | ||
image = factory.SubFactory("richie.apps.core.factories.FilerImageFactory") | ||
link_open_blank = factory.Faker("pybool") | ||
|
||
class Meta: | ||
model = SlideItem | ||
|
||
@factory.lazy_attribute | ||
def link_url(self): | ||
""" | ||
Set a random url | ||
""" | ||
Faker = faker.Faker() | ||
return Faker.url() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
""" | ||
Slider plugin forms | ||
""" | ||
|
||
from django import forms | ||
|
||
from djangocms_text_ckeditor.widgets import TextEditorWidget | ||
|
||
from .models import Slider, SlideItem | ||
|
||
CKEDITOR_CONFIGURATION_NAME = "CKEDITOR_SETTINGS" | ||
|
||
|
||
class SliderForm(forms.ModelForm): | ||
class Meta: | ||
model = Slider | ||
exclude = [] | ||
fields = [ | ||
"title", | ||
] | ||
|
||
|
||
class SlideItemForm(forms.ModelForm): | ||
class Meta: | ||
model = SlideItem | ||
exclude = [] | ||
fields = [ | ||
"slider", | ||
"title", | ||
"order", | ||
"image", | ||
"content", | ||
"link_url", | ||
"link_open_blank", | ||
] | ||
widgets = { | ||
"content": TextEditorWidget, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
# Generated by Django 4.2.16 on 2024-11-20 02:07 | ||
|
||
from django.conf import settings | ||
from django.db import migrations, models | ||
import django.db.models.deletion | ||
import filer.fields.image | ||
|
||
|
||
class Migration(migrations.Migration): | ||
|
||
initial = True | ||
|
||
dependencies = [ | ||
('cms', '0022_auto_20180620_1551'), | ||
migrations.swappable_dependency(settings.FILER_IMAGE_MODEL), | ||
] | ||
|
||
operations = [ | ||
migrations.CreateModel( | ||
name='Slider', | ||
fields=[ | ||
('cmsplugin_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, related_name='%(app_label)s_%(class)s', serialize=False, to='cms.cmsplugin')), | ||
('title', models.CharField(max_length=255, verbose_name='title')), | ||
], | ||
options={ | ||
'verbose_name': 'Slider', | ||
'verbose_name_plural': 'Sliders', | ||
}, | ||
bases=('cms.cmsplugin',), | ||
), | ||
migrations.CreateModel( | ||
name='SlideItem', | ||
fields=[ | ||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), | ||
('title', models.CharField(default='', max_length=150, verbose_name='title')), | ||
('content', models.TextField(blank=True, default='', verbose_name='content')), | ||
('order', models.IntegerField(default=0, verbose_name='order')), | ||
('link_url', models.URLField(blank=True, help_text='Make the slide as a link with an URL.', max_length=255, null=True, verbose_name='link URL')), | ||
('link_open_blank', models.BooleanField(default=False, help_text='If checked the link will be open in a new window', verbose_name='open new window')), | ||
('image', filer.fields.image.FilerImageField(default=None, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='slide_image', to=settings.FILER_IMAGE_MODEL, verbose_name='image')), | ||
('slider', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='slide_item', to='slider.slider')), | ||
], | ||
options={ | ||
'verbose_name': 'Slide item', | ||
'verbose_name_plural': 'Slide items', | ||
}, | ||
), | ||
] |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
""" | ||
Slider plugin models | ||
""" | ||
|
||
from django.conf import settings | ||
from django.db import models | ||
from django.utils.html import strip_tags | ||
from django.utils.text import Truncator | ||
from django.utils.translation import gettext_lazy as _ | ||
|
||
from cms.models.pluginmodel import CMSPlugin | ||
from filer.fields.image import FilerImageField | ||
|
||
|
||
class Slider(CMSPlugin): | ||
""" | ||
Slide container for items. | ||
.. Note:: | ||
We did slide item with common foreign key for slides instead of by the way of | ||
child plugins. | ||
The first is more natural and efficient but the latter has natural drag-n-drop | ||
ordering (in CMS content structure) and maybe less huge form (since slide form | ||
is delegate to child plugin form instead of including slide items as inline | ||
forms). | ||
""" | ||
title = models.CharField(_("title"), max_length=255) | ||
|
||
def __str__(self): | ||
return Truncator(self.title).words(6, truncate="...") | ||
|
||
def copy_relations(self, oldinstance): | ||
""" | ||
Copy FK relations when plugin object is copied as another object | ||
""" | ||
super().copy_relations(oldinstance) | ||
|
||
self.slide_item.all().delete() | ||
|
||
for slide_item in oldinstance.slide_item.all(): | ||
slide_item.pk = None | ||
slide_item.slider = self | ||
slide_item.save() | ||
|
||
class Meta: | ||
verbose_name = _("Slider") | ||
verbose_name_plural = _("Sliders") | ||
|
||
|
||
class SlideItem(models.Model): | ||
""" | ||
Slide item to include in container. | ||
.. Note:: | ||
Glimpse plugin has similar link feature but: | ||
* It contains both external free link and CMS page link; | ||
* It does not have option field to enable opening link a blank window (option | ||
is enabled automatically for external links only); | ||
Should we harmonize with Glimpse or does this implementation is better like | ||
this? | ||
""" | ||
slider = models.ForeignKey( | ||
Slider, | ||
related_name="slide_item", | ||
on_delete=models.CASCADE | ||
) | ||
title = models.CharField( | ||
_("title"), | ||
max_length=150, | ||
default="", | ||
) | ||
image = FilerImageField( | ||
related_name="slide_image", | ||
verbose_name=_("image"), | ||
on_delete=models.SET_NULL, | ||
null=True, | ||
default=None, | ||
) | ||
content = models.TextField( | ||
_("content"), | ||
blank=True, | ||
default="", | ||
) | ||
order = models.IntegerField( | ||
_("order"), | ||
default=0 | ||
) | ||
link_url = models.URLField( | ||
verbose_name=_("link URL"), | ||
blank=True, | ||
null=True, | ||
max_length=255, | ||
help_text=_("Make the slide as a link with an URL."), | ||
) | ||
link_open_blank = models.BooleanField( | ||
_("open new window"), | ||
default=False, | ||
help_text=_("If checked the link will be open in a new window"), | ||
) | ||
|
||
def __str__(self): | ||
return Truncator(self.title).words(6, truncate="...") | ||
|
||
class Meta: | ||
verbose_name = _("Slide item") | ||
verbose_name_plural = _("Slide items") |
27 changes: 27 additions & 0 deletions
27
src/richie/plugins/slider/templates/richie/slider/slider.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
{% load i18n thumbnail %}{% spaceless %} | ||
|
||
<div class="slider"> | ||
<div class="slider__items" count="{{ slides }}"> | ||
{% for item in slides %} | ||
<div class="slider-item" | ||
style="background-image: url('{% thumbnail item.image 1400x800 replace_alpha='#FFFFFF' crop=',0' %}');"> | ||
|
||
<p class="slider-item__title">{{ item.title }}</p> | ||
|
||
{% if item.content %} | ||
<div class="slider-item__content">{{ item.content|safe }}</div> | ||
{% endif %} | ||
|
||
{% if item.link_url %} | ||
<p class="slider-item__link"> | ||
<a href="{{ item.link_url }}"{% if item.link_open_blank %} target="_blank"{% endif %}> | ||
{% if item.link_name %}{{ item.link_name }}{% else %}{% trans "Read more" %}{% endif %} | ||
</a> | ||
</p> | ||
{% endif %} | ||
</div> | ||
{% endfor %} | ||
</div> | ||
</div> | ||
|
||
{% endspaceless %} |
Oops, something went wrong.