From 72cd4eac710725dfaaffc8f4fce0a6c14b911cd5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Valenta?= <git@imaniti.org>
Date: Mon, 21 Aug 2023 21:13:34 +0200
Subject: [PATCH] add colored tags

---
 home/admin.py                                 |  15 +++
 ...aggedarticle_delete_articletag_and_more.py | 119 ++++++++++++++++++
 ...5_alter_tag_bg_color_alter_tag_fg_color.py |  27 ++++
 .../0036_alter_taggedarticle_tag.py           |  22 ++++
 .../0037_remove_homearticlepage_tags.py       |  16 +++
 home/migrations/0038_homearticlepage_tags.py  |  24 ++++
 ...ove_taggedarticle_content_type_and_more.py |  20 +++
 home/models.py                                |  24 +++-
 home/templates/home/home_article_page.html    |   6 +-
 home/templates/home/home_articles_page.html   |   5 +-
 home/templates/home/home_page.html            |   5 +-
 institut/settings/base.py                     |   2 +
 requirements/base.txt                         |   1 +
 13 files changed, 280 insertions(+), 6 deletions(-)
 create mode 100644 home/admin.py
 create mode 100644 home/migrations/0034_tag_taggedarticle_delete_articletag_and_more.py
 create mode 100644 home/migrations/0035_alter_tag_bg_color_alter_tag_fg_color.py
 create mode 100644 home/migrations/0036_alter_taggedarticle_tag.py
 create mode 100644 home/migrations/0037_remove_homearticlepage_tags.py
 create mode 100644 home/migrations/0038_homearticlepage_tags.py
 create mode 100644 home/migrations/0039_remove_taggedarticle_content_type_and_more.py

diff --git a/home/admin.py b/home/admin.py
new file mode 100644
index 0000000..c8a5531
--- /dev/null
+++ b/home/admin.py
@@ -0,0 +1,15 @@
+from wagtail.contrib.modeladmin.options import ModelAdmin, modeladmin_register
+
+from .models import Tag
+
+
+class TagAdmin(ModelAdmin):
+    model = Tag
+    menu_label = "Ĺ tĂ­tky"
+    menu_icon = "tag"
+    menu_order = 290
+    add_to_settings_menu = False
+    exclude_from_explorer = False
+
+
+modeladmin_register(TagAdmin)
diff --git a/home/migrations/0034_tag_taggedarticle_delete_articletag_and_more.py b/home/migrations/0034_tag_taggedarticle_delete_articletag_and_more.py
new file mode 100644
index 0000000..11a9821
--- /dev/null
+++ b/home/migrations/0034_tag_taggedarticle_delete_articletag_and_more.py
@@ -0,0 +1,119 @@
+# Generated by Django 4.2.4 on 2023-08-21 18:21
+
+import django.db.models.deletion
+import modelcluster.contrib.taggit
+import modelcluster.fields
+import wagtail_color_panel.fields
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+    dependencies = [
+        ("contenttypes", "0002_remove_content_type_name"),
+        ("home", "0033_merge_20230820_1844"),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name="Tag",
+            fields=[
+                (
+                    "id",
+                    models.BigAutoField(
+                        auto_created=True,
+                        primary_key=True,
+                        serialize=False,
+                        verbose_name="ID",
+                    ),
+                ),
+                (
+                    "name",
+                    models.CharField(max_length=100, unique=True, verbose_name="name"),
+                ),
+                (
+                    "slug",
+                    models.SlugField(
+                        allow_unicode=True,
+                        max_length=100,
+                        unique=True,
+                        verbose_name="slug",
+                    ),
+                ),
+                (
+                    "bg_color",
+                    wagtail_color_panel.fields.ColorField(
+                        blank=True, max_length=7, null=True, verbose_name="Barva pozadĂ­"
+                    ),
+                ),
+                (
+                    "fg_color",
+                    wagtail_color_panel.fields.ColorField(
+                        blank=True, max_length=7, null=True, verbose_name="Barva textu"
+                    ),
+                ),
+            ],
+            options={
+                "abstract": False,
+            },
+        ),
+        migrations.CreateModel(
+            name="TaggedArticle",
+            fields=[
+                (
+                    "id",
+                    models.BigAutoField(
+                        auto_created=True,
+                        primary_key=True,
+                        serialize=False,
+                        verbose_name="ID",
+                    ),
+                ),
+                (
+                    "object_id",
+                    models.IntegerField(db_index=True, verbose_name="object ID"),
+                ),
+                (
+                    "content_object",
+                    modelcluster.fields.ParentalKey(
+                        on_delete=django.db.models.deletion.CASCADE,
+                        related_name="tagged_items",
+                        to="home.homearticlepage",
+                    ),
+                ),
+                (
+                    "content_type",
+                    models.ForeignKey(
+                        on_delete=django.db.models.deletion.CASCADE,
+                        related_name="%(app_label)s_%(class)s_tagged_items",
+                        to="contenttypes.contenttype",
+                        verbose_name="content type",
+                    ),
+                ),
+                (
+                    "tag",
+                    models.ForeignKey(
+                        on_delete=django.db.models.deletion.CASCADE,
+                        related_name="%(app_label)s_%(class)s_items",
+                        to="home.tag",
+                    ),
+                ),
+            ],
+            options={
+                "abstract": False,
+            },
+        ),
+        migrations.DeleteModel(
+            name="ArticleTag",
+        ),
+        migrations.AlterField(
+            model_name="homearticlepage",
+            name="tags",
+            field=modelcluster.contrib.taggit.ClusterTaggableManager(
+                blank=True,
+                help_text="A comma-separated list of tags.",
+                through="home.TaggedArticle",
+                to="home.Tag",
+                verbose_name="Ĺ tĂ­tky",
+            ),
+        ),
+    ]
diff --git a/home/migrations/0035_alter_tag_bg_color_alter_tag_fg_color.py b/home/migrations/0035_alter_tag_bg_color_alter_tag_fg_color.py
new file mode 100644
index 0000000..71bc07c
--- /dev/null
+++ b/home/migrations/0035_alter_tag_bg_color_alter_tag_fg_color.py
@@ -0,0 +1,27 @@
+# Generated by Django 4.2.4 on 2023-08-21 18:26
+
+import wagtail_color_panel.fields
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+    dependencies = [
+        ("home", "0034_tag_taggedarticle_delete_articletag_and_more"),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name="tag",
+            name="bg_color",
+            field=wagtail_color_panel.fields.ColorField(
+                default="#fafafa", max_length=7, verbose_name="Barva pozadĂ­"
+            ),
+        ),
+        migrations.AlterField(
+            model_name="tag",
+            name="fg_color",
+            field=wagtail_color_panel.fields.ColorField(
+                default="#000000", max_length=7, verbose_name="Barva textu"
+            ),
+        ),
+    ]
diff --git a/home/migrations/0036_alter_taggedarticle_tag.py b/home/migrations/0036_alter_taggedarticle_tag.py
new file mode 100644
index 0000000..47095fe
--- /dev/null
+++ b/home/migrations/0036_alter_taggedarticle_tag.py
@@ -0,0 +1,22 @@
+# Generated by Django 4.2.4 on 2023-08-21 18:44
+
+import django.db.models.deletion
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+    dependencies = [
+        ("home", "0035_alter_tag_bg_color_alter_tag_fg_color"),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name="taggedarticle",
+            name="tag",
+            field=models.ForeignKey(
+                on_delete=django.db.models.deletion.CASCADE,
+                related_name="article_tags",
+                to="home.tag",
+            ),
+        ),
+    ]
diff --git a/home/migrations/0037_remove_homearticlepage_tags.py b/home/migrations/0037_remove_homearticlepage_tags.py
new file mode 100644
index 0000000..54a9d30
--- /dev/null
+++ b/home/migrations/0037_remove_homearticlepage_tags.py
@@ -0,0 +1,16 @@
+# Generated by Django 4.2.4 on 2023-08-21 19:06
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+    dependencies = [
+        ("home", "0036_alter_taggedarticle_tag"),
+    ]
+
+    operations = [
+        migrations.RemoveField(
+            model_name="homearticlepage",
+            name="tags",
+        ),
+    ]
diff --git a/home/migrations/0038_homearticlepage_tags.py b/home/migrations/0038_homearticlepage_tags.py
new file mode 100644
index 0000000..d6165dc
--- /dev/null
+++ b/home/migrations/0038_homearticlepage_tags.py
@@ -0,0 +1,24 @@
+# Generated by Django 4.2.4 on 2023-08-21 19:06
+
+import modelcluster.contrib.taggit
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+    dependencies = [
+        ("home", "0037_remove_homearticlepage_tags"),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name="homearticlepage",
+            name="tags",
+            field=modelcluster.contrib.taggit.ClusterTaggableManager(
+                blank=True,
+                help_text="A comma-separated list of tags.",
+                through="home.TaggedArticle",
+                to="home.Tag",
+                verbose_name="Ĺ tĂ­tky",
+            ),
+        ),
+    ]
diff --git a/home/migrations/0039_remove_taggedarticle_content_type_and_more.py b/home/migrations/0039_remove_taggedarticle_content_type_and_more.py
new file mode 100644
index 0000000..fbefe01
--- /dev/null
+++ b/home/migrations/0039_remove_taggedarticle_content_type_and_more.py
@@ -0,0 +1,20 @@
+# Generated by Django 4.2.4 on 2023-08-21 19:09
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+    dependencies = [
+        ("home", "0038_homearticlepage_tags"),
+    ]
+
+    operations = [
+        migrations.RemoveField(
+            model_name="taggedarticle",
+            name="content_type",
+        ),
+        migrations.RemoveField(
+            model_name="taggedarticle",
+            name="object_id",
+        ),
+    ]
diff --git a/home/models.py b/home/models.py
index f3f57c0..70b59e0 100644
--- a/home/models.py
+++ b/home/models.py
@@ -2,7 +2,7 @@ from django.db import models
 from django.utils import timezone
 from modelcluster.contrib.taggit import ClusterTaggableManager
 from modelcluster.fields import ParentalKey
-from taggit.models import TaggedItemBase
+from taggit.models import ItemBase, TagBase
 from wagtail.admin.panels import (
     FieldPanel,
     InlinePanel,
@@ -16,17 +16,33 @@ from wagtail.contrib.settings.models import BaseSiteSetting, register_setting
 from wagtail.documents import get_document_model
 from wagtail.fields import RichTextField, StreamField
 from wagtail.models import Page
+from wagtail_color_panel.edit_handlers import NativeColorPanel
+from wagtail_color_panel.fields import ColorField
 
 from .blocks import PersonBlock
 
 # --- BEGIN Tags ---
 
 
-class ArticleTag(TaggedItemBase):
+class Tag(TagBase):
+    bg_color = ColorField(verbose_name="Barva pozadĂ­", default="#fafafa")
+    fg_color = ColorField(verbose_name="Barva textu", default="#000000")
+
+    panels = [
+        FieldPanel("name"),
+        FieldPanel("slug"),
+        NativeColorPanel("bg_color"),
+        NativeColorPanel("fg_color"),
+    ]
+
+
+class TaggedArticle(ItemBase):
     content_object = ParentalKey(
         "home.HomeArticlePage", on_delete=models.CASCADE, related_name="tagged_items"
     )
 
+    tag = models.ForeignKey(Tag, on_delete=models.CASCADE, related_name="article_tags")
+
 
 # --- END Tags ---
 
@@ -428,7 +444,9 @@ class HomeArticlePage(HomeContentPageMixin):
         default=False,
     )
 
-    tags = ClusterTaggableManager(through=ArticleTag, blank=True, verbose_name="Ĺ tĂ­tky")
+    tags = ClusterTaggableManager(
+        through=TaggedArticle, blank=True, verbose_name="Ĺ tĂ­tky"
+    )
 
     perex = models.TextField(verbose_name="Perex")
 
diff --git a/home/templates/home/home_article_page.html b/home/templates/home/home_article_page.html
index b3f3ccf..3889a99 100644
--- a/home/templates/home/home_article_page.html
+++ b/home/templates/home/home_article_page.html
@@ -8,7 +8,11 @@
 
         <small class="text-pii-cyan uppercase font-bold">
             {% for tag in page.tags.all %}
-                <a href="/clanky?tag={{ tag.name }}">{{ tag.name }}</a>&nbsp;
+                <a
+                    href="/clanky?tag={{ tag.name }}"
+                    class="px-2 py-0.5 rounded-sm"
+                    style="background-color:{{ tag.bg_color }};color:{{ tag.fg_color }}"
+                >{{ tag.name }}</a>&nbsp;
             {% endfor %}
         </small>
 
diff --git a/home/templates/home/home_articles_page.html b/home/templates/home/home_articles_page.html
index 19193d9..4da9088 100644
--- a/home/templates/home/home_articles_page.html
+++ b/home/templates/home/home_articles_page.html
@@ -39,7 +39,10 @@
                         <div class="p-7 flex flex-col gap-2 h-full">
                             <small class="text-white uppercase font-bold">
                                 {% for tag in article.tags.all %}
-                                    {{ tag.name }}&nbsp;
+                                    <span
+                                        class="px-2 py-0.5 rounded-sm"
+                                        style="background-color:{{ tag.bg_color }};color:{{ tag.fg_color }}"
+                                    >{{ tag.name }}</span>&nbsp;
                                 {% endfor %}
                             </small>
                             <h3 class="font-serif text-xl leading-6 font-bold">{{ article.title }}</h3>
diff --git a/home/templates/home/home_page.html b/home/templates/home/home_page.html
index 47215f0..92af4c3 100644
--- a/home/templates/home/home_page.html
+++ b/home/templates/home/home_page.html
@@ -40,7 +40,10 @@
                             <div class="p-7 flex flex-col gap-2 h-full">
                                 <small class="text-pii-cyan uppercase font-bold">
                                     {% for tag in article.tags.all %}
-                                        {{ tag.name }}&nbsp;
+                                        <span
+                                            class="px-2 py-0.5 rounded-sm"
+                                            style="background-color:{{ tag.bg_color }};color:{{ tag.fg_color }}"
+                                        >{{ tag.name }}</span>&nbsp;
                                     {% endfor %}
                                 </small>
                                 <h3 class="font-serif text-xl leading-6 font-bold">{{ article.title }}</h3>
diff --git a/institut/settings/base.py b/institut/settings/base.py
index e2ebb9e..a1648f2 100644
--- a/institut/settings/base.py
+++ b/institut/settings/base.py
@@ -40,6 +40,7 @@ INSTALLED_APPS = [
     "wagtail.contrib.redirects",
     "wagtail.contrib.routable_page",
     "wagtail.contrib.settings",
+    "wagtail.contrib.modeladmin",
     "wagtail.embeds",
     "wagtail.sites",
     "wagtail.users",
@@ -52,6 +53,7 @@ INSTALLED_APPS = [
     "wagtail",
     "modelcluster",
     "taggit",
+    "wagtail_color_panel",
     "django.contrib.admin",
     "django.contrib.auth",
     "django.contrib.contenttypes",
diff --git a/requirements/base.txt b/requirements/base.txt
index 5d8f90c..7f3edb7 100644
--- a/requirements/base.txt
+++ b/requirements/base.txt
@@ -5,3 +5,4 @@ django-modelcluster==6.0
 psycopg2-binary==2.9.6
 wagtail==5.0.2
 wagtail-footnotes==0.10.0
+wagtail-color-panel==1.4.1
-- 
GitLab