From 6c06df7994e19fd8dad5cfb87cbc5cf5f1216b4a Mon Sep 17 00:00:00 2001
From: Jarmil <jarmil.halamicek@seznam.cz>
Date: Wed, 7 Oct 2020 10:36:45 +0200
Subject: [PATCH] Shared model Article (clanek), zobrazeni nahledu clanku

---
 district/models.py                            |  10 +-
 .../district/district_home_page.html          |   9 ++
 shared/migrations/0001_initial.py             | 100 ++++++++++++++++++
 shared/migrations/0002_auto_20201007_0933.py  |  53 ++++++++++
 shared/migrations/0003_auto_20201007_0944.py  |  36 +++++++
 shared/migrations/0004_article_author.py      |  18 ++++
 shared/migrations/0005_auto_20201007_1028.py  |  57 ++++++++++
 shared/migrations/__init__.py                 |   0
 shared/models.py                              |  45 ++++++++
 shared/templates/shared/article_preview.html  |  62 +++++++++++
 10 files changed, 388 insertions(+), 2 deletions(-)
 create mode 100644 shared/migrations/0001_initial.py
 create mode 100644 shared/migrations/0002_auto_20201007_0933.py
 create mode 100644 shared/migrations/0003_auto_20201007_0944.py
 create mode 100644 shared/migrations/0004_article_author.py
 create mode 100644 shared/migrations/0005_auto_20201007_1028.py
 create mode 100644 shared/migrations/__init__.py
 create mode 100644 shared/models.py
 create mode 100644 shared/templates/shared/article_preview.html

diff --git a/district/models.py b/district/models.py
index b904ffcf..a09eab04 100644
--- a/district/models.py
+++ b/district/models.py
@@ -11,6 +11,7 @@ from wagtail.core.fields import StreamField
 from wagtail.core.models import Page
 from wagtailmetadata.models import MetadataPageMixin
 
+from shared.models import Article
 from tuning import help
 
 
@@ -49,14 +50,19 @@ class DistrictHomePage(MetadataPageMixin, Page):
     ]
 
     ### RELATIONS
-
-    subpage_types = []
+    subpage_types = [
+        "shared.Article",
+    ]
 
     ### OTHERS
 
     class Meta:
         verbose_name = "Web mĂ­stnĂ­ho sdruĹľenĂ­"
 
+    @property
+    def articles(self):
+        return self.get_descendants().type(Article).live().specific()
+
     @property
     def root_page(self):
         return self
diff --git a/district/templates/district/district_home_page.html b/district/templates/district/district_home_page.html
index f9ddc78e..b4a0b209 100644
--- a/district/templates/district/district_home_page.html
+++ b/district/templates/district/district_home_page.html
@@ -4,6 +4,15 @@
 {% block content %}
 <main>
 
+    <h1 class="head-alt-md md:head-alt-lg pb-4 lg:pb-8">Aktuální témata</h1>
+
+    <!--  list of articles -->
+    <div class="article-card-list grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4 lg:gap-8">
+        {% for a in page.articles %}
+            {% include "shared/article_preview.html" with article=a %}
+        {% endfor %}
+    </div>
+
   <div class="d-flex">
 
       <a href="{{page.facebook}}" class="super-button bg-brands-facebook text-white container-padding--zero lg:container-padding--auto lg:w-full m-2" >
diff --git a/shared/migrations/0001_initial.py b/shared/migrations/0001_initial.py
new file mode 100644
index 00000000..495fb8cb
--- /dev/null
+++ b/shared/migrations/0001_initial.py
@@ -0,0 +1,100 @@
+# Generated by Django 3.1.1 on 2020-10-07 07:27
+
+import django.db.models.deletion
+import wagtail.core.blocks
+import wagtail.core.fields
+import wagtail.images.blocks
+import wagtailmetadata.models
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    initial = True
+
+    dependencies = [
+        ("wagtailcore", "0052_pagelogentry"),
+        ("wagtailimages", "0022_uploadedimage"),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name="SharedArticle",
+            fields=[
+                (
+                    "page_ptr",
+                    models.OneToOneField(
+                        auto_created=True,
+                        on_delete=django.db.models.deletion.CASCADE,
+                        parent_link=True,
+                        primary_key=True,
+                        serialize=False,
+                        to="wagtailcore.page",
+                    ),
+                ),
+                (
+                    "content",
+                    wagtail.core.fields.StreamField(
+                        [
+                            (
+                                "title",
+                                wagtail.core.blocks.CharBlock(
+                                    icon="title", label="nadpis"
+                                ),
+                            ),
+                            ("perex", wagtail.core.blocks.CharBlock(label="perex")),
+                            (
+                                "text",
+                                wagtail.core.blocks.RichTextBlock(
+                                    features=[
+                                        "h2",
+                                        "h3",
+                                        "h4",
+                                        "h5",
+                                        "bold",
+                                        "italic",
+                                        "ol",
+                                        "ul",
+                                        "hr",
+                                        "link",
+                                        "document-link",
+                                        "image",
+                                        "superscript",
+                                        "subscript",
+                                        "strikethrough",
+                                        "blockquote",
+                                    ],
+                                    label="text",
+                                ),
+                            ),
+                            (
+                                "image",
+                                wagtail.images.blocks.ImageChooserBlock(
+                                    label="obrázek"
+                                ),
+                            ),
+                        ],
+                        blank=True,
+                        verbose_name="obsah stránky",
+                    ),
+                ),
+                (
+                    "search_image",
+                    models.ForeignKey(
+                        blank=True,
+                        null=True,
+                        on_delete=django.db.models.deletion.SET_NULL,
+                        related_name="+",
+                        to="wagtailimages.image",
+                        verbose_name="Search image",
+                    ),
+                ),
+            ],
+            options={"verbose_name": "Článek",},
+            bases=(
+                wagtailmetadata.models.MetadataMixin,
+                "wagtailcore.page",
+                models.Model,
+            ),
+        ),
+    ]
diff --git a/shared/migrations/0002_auto_20201007_0933.py b/shared/migrations/0002_auto_20201007_0933.py
new file mode 100644
index 00000000..b1e5d69c
--- /dev/null
+++ b/shared/migrations/0002_auto_20201007_0933.py
@@ -0,0 +1,53 @@
+# Generated by Django 3.1.1 on 2020-10-07 07:33
+
+import django.db.models.deletion
+import wagtailmetadata.models
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ("wagtailforms", "0004_add_verbose_name_plural"),
+        ("wagtailcore", "0052_pagelogentry"),
+        ("wagtailimages", "0022_uploadedimage"),
+        ("wagtailredirects", "0006_redirect_increase_max_length"),
+        ("shared", "0001_initial"),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name="Article",
+            fields=[
+                (
+                    "page_ptr",
+                    models.OneToOneField(
+                        auto_created=True,
+                        on_delete=django.db.models.deletion.CASCADE,
+                        parent_link=True,
+                        primary_key=True,
+                        serialize=False,
+                        to="wagtailcore.page",
+                    ),
+                ),
+                (
+                    "search_image",
+                    models.ForeignKey(
+                        blank=True,
+                        null=True,
+                        on_delete=django.db.models.deletion.SET_NULL,
+                        related_name="+",
+                        to="wagtailimages.image",
+                        verbose_name="Search image",
+                    ),
+                ),
+            ],
+            options={"verbose_name": "Článek",},
+            bases=(
+                wagtailmetadata.models.MetadataMixin,
+                "wagtailcore.page",
+                models.Model,
+            ),
+        ),
+        migrations.DeleteModel(name="SharedArticle",),
+    ]
diff --git a/shared/migrations/0003_auto_20201007_0944.py b/shared/migrations/0003_auto_20201007_0944.py
new file mode 100644
index 00000000..d8dbec5a
--- /dev/null
+++ b/shared/migrations/0003_auto_20201007_0944.py
@@ -0,0 +1,36 @@
+# Generated by Django 3.1.1 on 2020-10-07 07:44
+
+import django.db.models.deletion
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ("wagtailimages", "0022_uploadedimage"),
+        ("shared", "0002_auto_20201007_0933"),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name="article",
+            name="image",
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.PROTECT,
+                to="wagtailimages.image",
+                verbose_name="obrázek",
+            ),
+        ),
+        migrations.AddField(
+            model_name="article",
+            name="perex",
+            field=models.CharField(blank=True, max_length=250, verbose_name="perex"),
+        ),
+        migrations.AddField(
+            model_name="article",
+            name="text",
+            field=models.TextField(blank=True, verbose_name="text článku"),
+        ),
+    ]
diff --git a/shared/migrations/0004_article_author.py b/shared/migrations/0004_article_author.py
new file mode 100644
index 00000000..4840c03c
--- /dev/null
+++ b/shared/migrations/0004_article_author.py
@@ -0,0 +1,18 @@
+# Generated by Django 3.1.1 on 2020-10-07 08:16
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ("shared", "0003_auto_20201007_0944"),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name="article",
+            name="author",
+            field=models.TextField(blank=True, verbose_name="autor článku"),
+        ),
+    ]
diff --git a/shared/migrations/0005_auto_20201007_1028.py b/shared/migrations/0005_auto_20201007_1028.py
new file mode 100644
index 00000000..6a714662
--- /dev/null
+++ b/shared/migrations/0005_auto_20201007_1028.py
@@ -0,0 +1,57 @@
+# Generated by Django 3.1.1 on 2020-10-07 08:28
+
+import django.db.models.deletion
+import modelcluster.contrib.taggit
+import modelcluster.fields
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ("taggit", "0003_taggeditem_add_unique_index"),
+        ("shared", "0004_article_author"),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name="ArticleTag",
+            fields=[
+                (
+                    "id",
+                    models.AutoField(
+                        auto_created=True,
+                        primary_key=True,
+                        serialize=False,
+                        verbose_name="ID",
+                    ),
+                ),
+                (
+                    "content_object",
+                    modelcluster.fields.ParentalKey(
+                        on_delete=django.db.models.deletion.CASCADE, to="shared.article"
+                    ),
+                ),
+                (
+                    "tag",
+                    models.ForeignKey(
+                        on_delete=django.db.models.deletion.CASCADE,
+                        related_name="shared_articletag_items",
+                        to="taggit.tag",
+                    ),
+                ),
+            ],
+            options={"abstract": False,},
+        ),
+        migrations.AddField(
+            model_name="article",
+            name="tags",
+            field=modelcluster.contrib.taggit.ClusterTaggableManager(
+                blank=True,
+                help_text="A comma-separated list of tags.",
+                through="shared.ArticleTag",
+                to="taggit.Tag",
+                verbose_name="Tags",
+            ),
+        ),
+    ]
diff --git a/shared/migrations/__init__.py b/shared/migrations/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/shared/models.py b/shared/models.py
new file mode 100644
index 00000000..5b2e5b9c
--- /dev/null
+++ b/shared/models.py
@@ -0,0 +1,45 @@
+from django.db import models
+from modelcluster.contrib.taggit import ClusterTaggableManager
+from modelcluster.fields import ParentalKey
+from taggit.models import TaggedItemBase
+from wagtail.admin.edit_handlers import FieldPanel
+from wagtail.core.models import Page
+from wagtail.images.edit_handlers import ImageChooserPanel
+from wagtailmetadata.models import MetadataPageMixin
+
+
+class ArticleTag(TaggedItemBase):
+    content_object = ParentalKey("shared.Article", on_delete=models.CASCADE)
+
+
+class Article(MetadataPageMixin, Page):
+    """ Univerzalni clanek pro vsechny weby """
+
+    ### FIELDS
+
+    perex = models.CharField("perex", max_length=250, blank=True)
+    text = models.TextField("text článku", blank=True)
+    image = models.ForeignKey(
+        "wagtailimages.Image",
+        on_delete=models.PROTECT,
+        blank=True,
+        null=True,
+        verbose_name="obrázek",
+    )
+    author = models.TextField("autor článku", blank=True)
+    tags = ClusterTaggableManager(through=ArticleTag, blank=True)
+
+    ### PANELS
+
+    content_panels = Page.content_panels + [
+        FieldPanel("perex"),
+        FieldPanel("text"),
+        FieldPanel("author"),
+        ImageChooserPanel("image"),
+        FieldPanel("tags"),
+    ]
+
+    ### OTHERS
+
+    class Meta:
+        verbose_name = "Článek"
diff --git a/shared/templates/shared/article_preview.html b/shared/templates/shared/article_preview.html
new file mode 100644
index 00000000..73b95c7a
--- /dev/null
+++ b/shared/templates/shared/article_preview.html
@@ -0,0 +1,62 @@
+{% load wagtailcore_tags wagtailimages_tags %}
+
+<article itemtype="http://schema.org/BlogPosting" class="card card--hoveractive article-card bg-black" itemscope="">
+
+  <link itemprop="mainEntityOfPage" href="{{ article.url }}">
+
+  <div class="article-card-cover">
+    <a href="{{ article.url }}" itemprop="image" itemtype="http://schema.org/ImageObject" itemscope="">
+      {% image article.image width-2000 as img %}
+      <img src="{{ img.url }}" alt="{{ article.title }}">
+      <meta itemprop="url" content="{{ img.url }}">
+    </a>
+
+    <div class="article-card-cover__details">
+      <div class="article-card-sharing">
+        <div class="social-icon-group">
+          <a
+            href="https://www.facebook.com/sharer/sharer.php?u={{ article.url }}"
+            onclick="window.open(this.href, 'pop-up', 'left=20,top=20,width=500,height=500,toolbar=1,resizable=0'); return false;"
+            class="social-icon social-icon--fill bg-brands-facebook text-white text-sm social-icon--4"
+          ><i class="ico--facebook"></i></a>
+          <a
+            href="https://twitter.com/intent/tweet?text={{ article.title }}&url={{ article.url }}"
+            onclick="window.open(this.href, 'pop-up', 'left=20,top=20,width=500,height=500,toolbar=1,resizable=0'); return false;"
+            class="social-icon social-icon--fill bg-brands-twitter text-white text-sm social-icon--4"
+          ><i class="ico--twitter"></i></a>
+        </div>
+      </div>
+
+      <div class="article-card-meta"  class="c-metadata-block-section__item" >
+        <span itemprop="description" class="article-card-meta__item">
+          {{ article.last_published_at|date:"SHORT_DATE_FORMAT" }}
+          <meta itemprop="datePublished" content="{{ article.last_published_at }}" />
+        </span>
+        <span class="article-card-meta__item" itemprop="author" itemtype="http://schema.org/Person" itemscope="">
+          <span itemprop="name">{{ article.author }}</span>
+        </span>
+      </div>
+
+    </div>
+  </div>
+
+  <div class="card__body article-card__body">
+    <a href="{{ article.url }}" class="hover:line-white"><h1 class="card-headline mb-4 text-white">{{article.title}}</h1></a>
+    <p class="card-body-text flex-grow text-white">{{article.perex}}</p>
+    <div class="inline-block-nogap mt-4">
+          {% for tag in article.tags.all %}
+            <a href="/tags/#{{ tag }}" class="btn article-card__category-button btn--condensed text-sm font-light btn--grey-700 p-0"   >
+              <div class="btn__body">{{ tag }}</div>
+            </a>
+          {% endfor %}
+    </div>
+  </div>
+
+  <div itemprop="publisher" itemtype="http://schema.org/Organization" class="hidden" itemscope="">
+    <div itemprop="logo" itemtype="http://schema.org/ImageObject" itemscope="">
+      <meta itemprop="url" content="/assets/img/brand/logo.svg">
+    </div>
+    <meta itemprop="name" content="Česká pirátská strana">
+  </div>
+
+</article>
-- 
GitLab