diff --git a/djangocms_conditional/cms_plugins.py b/djangocms_conditional/cms_plugins.py index 726646c..4bbd4d2 100644 --- a/djangocms_conditional/cms_plugins.py +++ b/djangocms_conditional/cms_plugins.py @@ -2,15 +2,17 @@ from cms.plugin_base import CMSPluginBase from cms.plugin_pool import plugin_pool from django.contrib.auth.models import User, AnonymousUser -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from .models import ConditionalPluginModel, MODE_IN_GROUP, MODE_NOT_IN_GROUP, MODE_NOT_IN_GROUP_PLUS_ANON, \ MODE_ANONYMOUS +from .forms import ConditionalPluginForm class ConditionalContainerPlugin(CMSPluginBase): - name = _(u'Conditional content') + name = _('Conditional content') model = ConditionalPluginModel + form = ConditionalPluginForm allow_children = True cache = False render_template = 'djangocms_conditional/conditional.html' @@ -27,17 +29,19 @@ def render(self, context, instance, placeholder): user = AnonymousUser() # Should never happen # This could be coded more efficiently, but is this way for clarity - if instance.mode == MODE_IN_GROUP: + if user.is_superuser: + context['instance'] = instance + elif instance.mode == MODE_IN_GROUP: if user.groups.filter(id=instance.permitted_group.id).exists(): context['instance'] = instance elif instance.mode == MODE_NOT_IN_GROUP: - if not (user.is_anonymous() or user.groups.filter(id=instance.permitted_group.id).exists()): + if not (user.is_anonymous or user.groups.filter(id=instance.permitted_group.id).exists()): context['instance'] = instance elif instance.mode == MODE_ANONYMOUS: - if user.is_anonymous(): + if user.is_anonymous: context['instance'] = instance elif instance.mode == MODE_NOT_IN_GROUP_PLUS_ANON: - if user.is_anonymous() or not user.groups.filter(id=instance.permitted_group.id).exists(): + if user.is_anonymous or not user.groups.filter(id=instance.permitted_group.id).exists(): context['instance'] = instance return context diff --git a/djangocms_conditional/forms.py b/djangocms_conditional/forms.py new file mode 100644 index 0000000..d280407 --- /dev/null +++ b/djangocms_conditional/forms.py @@ -0,0 +1,20 @@ +from django import forms +from django.utils.translation import gettext as _ +from .models import MODE_IN_GROUP, MODE_NOT_IN_GROUP, MODE_NOT_IN_GROUP_PLUS_ANON + + +class ConditionalPluginForm(forms.ModelForm): + fields = "__all__" + + def clean(self): + cleaned_data = super().clean() + permitted_group = cleaned_data.get("permitted_group") + mode = cleaned_data.get("mode") + modes_that_require_group = [ + MODE_IN_GROUP, + MODE_NOT_IN_GROUP, + MODE_NOT_IN_GROUP_PLUS_ANON + ] + + if mode in modes_that_require_group and permitted_group is None: + self.add_error("permitted_group", _("You must choose a group when using this mode.")) diff --git a/djangocms_conditional/locale/fr/LC_MESSAGES/django.mo b/djangocms_conditional/locale/fr/LC_MESSAGES/django.mo new file mode 100644 index 0000000..c8ea0e3 Binary files /dev/null and b/djangocms_conditional/locale/fr/LC_MESSAGES/django.mo differ diff --git a/djangocms_conditional/locale/fr/LC_MESSAGES/django.po b/djangocms_conditional/locale/fr/LC_MESSAGES/django.po new file mode 100644 index 0000000..ec45a6b --- /dev/null +++ b/djangocms_conditional/locale/fr/LC_MESSAGES/django.po @@ -0,0 +1,60 @@ +# djangocms-conditional translations +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2024-04-23 17:17+0200\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" + +#: cms_plugins.py:13 +msgid "Conditional content" +msgstr "Contenu conditionnel" + +#: forms.py:20 +msgid "You must choose a group when using this mode." +msgstr "Vous devez choisir un groupe pour utiliser ce mode." + +#: models.py:16 +msgid "Permitted group" +msgstr "Groupe autorisé" + +#: models.py:19 +msgid "Mode" +msgstr "Mode" + +#: models.py:20 +msgid "Conditional access type" +msgstr "Type d’accès" + +#: models.py:21 +msgid "Users in group" +msgstr "Utilisateurs dans le groupe" + +#: models.py:22 +msgid "Users not in group" +msgstr "Utilisateurs hors du groupe" + +#: models.py:23 +msgid "Anonymous users and users not in group" +msgstr "Utilisateurs anonymes et ceux hors du groupe" + +#: models.py:24 +msgid "Anonymous users" +msgstr "Utilisateurs anonymes" + +#: models.py:29 +#, python-brace-format +msgid "{mode}: {group}" +msgstr "{mode}: {group}" diff --git a/djangocms_conditional/migrations/0003_alter_conditionalpluginmodel_cmsplugin_ptr_and_more.py b/djangocms_conditional/migrations/0003_alter_conditionalpluginmodel_cmsplugin_ptr_and_more.py new file mode 100644 index 0000000..e0c1c32 --- /dev/null +++ b/djangocms_conditional/migrations/0003_alter_conditionalpluginmodel_cmsplugin_ptr_and_more.py @@ -0,0 +1,53 @@ +# Generated by Django 4.2.11 on 2024-04-23 14:49 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + dependencies = [ + ("auth", "0012_alter_user_first_name_max_length"), + ("cms", "0022_auto_20180620_1551"), + ("djangocms_conditional", "0002_conditionalpluginmodel_mode"), + ] + + operations = [ + migrations.AlterField( + model_name="conditionalpluginmodel", + name="cmsplugin_ptr", + field=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", + ), + ), + migrations.AlterField( + model_name="conditionalpluginmodel", + name="mode", + field=models.CharField( + choices=[ + ("in_group", "Users in group"), + ("not_in_group", "Users not in group"), + ( + "not_in_group_plus_anon", + "Anonymous users and users not in group", + ), + ("anonymous", "Anonymous users"), + ], + default="in_group", + help_text="Conditional access type", + max_length=40, + ), + ), + migrations.AlterField( + model_name="conditionalpluginmodel", + name="permitted_group", + field=models.ForeignKey( + null=True, blank=True, on_delete=django.db.models.deletion.SET_NULL, to="auth.group" + ), + ), + ] diff --git a/djangocms_conditional/models.py b/djangocms_conditional/models.py index a6abbcc..a38ea08 100644 --- a/djangocms_conditional/models.py +++ b/djangocms_conditional/models.py @@ -2,8 +2,7 @@ from cms.models import CMSPlugin from django.contrib.auth.models import Group from django.db import models -from django.utils.encoding import python_2_unicode_compatible -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ MODE_IN_GROUP = 'in_group' @@ -12,21 +11,24 @@ MODE_ANONYMOUS = 'anonymous' -@python_2_unicode_compatible class ConditionalPluginModel(CMSPlugin): - permitted_group = models.ForeignKey(Group, null=False, blank=False) + permitted_group = models.ForeignKey(Group, null=True, blank=True, on_delete=models.SET_NULL, verbose_name=_("Permitted group")) mode = models.CharField(max_length=40, default='in_group', - help_text=_(u"Conditional access type"), - choices=((MODE_IN_GROUP, _(u'Users in group')), - (MODE_NOT_IN_GROUP, _(u'Users not in group')), + verbose_name=_("Mode"), + help_text=_("Conditional access type"), + choices=((MODE_IN_GROUP, _('Users in group')), + (MODE_NOT_IN_GROUP, _('Users not in group')), (MODE_NOT_IN_GROUP_PLUS_ANON, _('Anonymous users and users not in group')), (MODE_ANONYMOUS, _('Anonymous users')), )) def __str__(self): - return _(u'Conditional access %s group="%s"') % ( - self.mode, - self.permitted_group.name, - ) + if self.permitted_group is not None: + return _('{mode}: {group}').format( + mode=self.get_mode_display(), + group=self.permitted_group.name, + ) + else: + return self.get_mode_display() diff --git a/docs/conf.py b/docs/conf.py index 555338e..42e97bc 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -46,8 +46,8 @@ master_doc = 'index' # General information about the project. -project = u'djangocms-conditional' -copyright = u'2017, Roy Hooper' +project = 'djangocms-conditional' +copyright = '2017, Roy Hooper' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the @@ -192,8 +192,8 @@ # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, author, documentclass [howto/manual]). latex_documents = [ - ('index', 'djangocms-conditional.tex', u'djangocms-conditional Documentation', - u'Iacopo Spalletti', 'manual'), + ('index', 'djangocms-conditional.tex', 'djangocms-conditional Documentation', + 'Iacopo Spalletti', 'manual'), ] # The name of an image file (relative to this directory) to place at the top of @@ -222,8 +222,8 @@ # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ - ('index', 'djangocms-conditional', u'djangocms-conditional Documentation', - [u'Iacopo Spalletti'], 1) + ('index', 'djangocms-conditional', 'djangocms-conditional Documentation', + ['Iacopo Spalletti'], 1) ] # If true, show URL addresses after external links. @@ -236,8 +236,8 @@ # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ - ('index', 'djangocms-conditional', u'djangocms-conditional Documentation', - u'Iacopo Spalletti', 'djangocms-conditional', 'One line description of project.', + ('index', 'djangocms-conditional', 'djangocms-conditional Documentation', + 'Iacopo Spalletti', 'djangocms-conditional', 'One line description of project.', 'Miscellaneous'), ] diff --git a/tests/test_models.py b/tests/test_models.py index 4793620..05a971e 100644 --- a/tests/test_models.py +++ b/tests/test_models.py @@ -24,14 +24,14 @@ def setup_plugin(self, group, mode='in_group'): parent_plugin = add_plugin( placeholder, ConditionalContainerPlugin, - u'en', + 'en', permitted_group=group, mode=mode ) parent_plugin.save() - text_content = u"Child plugin" - text_plugin = add_plugin(placeholder, u"TextPlugin", u"en", body=text_content, target=parent_plugin,) + text_content = "Child plugin" + text_plugin = add_plugin(placeholder, "TextPlugin", "en", body=text_content, target=parent_plugin,) text_plugin.save() parent_plugin.child_plugin_instances = [text_plugin]