Skip to content
Snippets Groups Projects
Commit fbada802 authored by Tomáš Valenta's avatar Tomáš Valenta Committed by josef.bouse
Browse files

tag filtering

parent 3adcf582
No related branches found
No related tags found
2 merge requests!861Release: New homepage design,!841Feat/new homepage
Showing
with 135 additions and 207 deletions
# Generated by Django 4.1.10 on 2023-12-19 20:40
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('main', '0088_alter_mainhomepage_europarl_section_tag'),
]
operations = [
migrations.RemoveField(
model_name='mainarticlepage',
name='section_tags',
),
migrations.RemoveField(
model_name='mainhomepage',
name='europarl_section_tag',
),
migrations.RemoveField(
model_name='mainhomepage',
name='main_section_tag',
),
migrations.DeleteModel(
name='MainArticleSectionTagged',
),
migrations.DeleteModel(
name='SectionTag',
),
]
...@@ -10,7 +10,7 @@ from django.shortcuts import render ...@@ -10,7 +10,7 @@ from django.shortcuts import render
from django.utils import timezone from django.utils import timezone
from modelcluster.contrib.taggit import ClusterTaggableManager from modelcluster.contrib.taggit import ClusterTaggableManager
from modelcluster.fields import ParentalKey from modelcluster.fields import ParentalKey
from taggit.models import TagBase, TaggedItemBase from taggit.models import Tag, TaggedItemBase
from wagtail.admin.panels import ( from wagtail.admin.panels import (
FieldPanel, FieldPanel,
HelpPanel, HelpPanel,
...@@ -124,24 +124,6 @@ class MainHomePage( ...@@ -124,24 +124,6 @@ class MainHomePage(
null=True, null=True,
) )
main_section_tag = models.ForeignKey(
"main.SectionTag",
verbose_name="Tag pro rozdělení - Hlavní stránka",
on_delete=models.PROTECT,
related_name="+",
blank=True,
null=True,
)
europarl_section_tag = models.ForeignKey(
"main.SectionTag",
verbose_name="Tag pro rozdělení - Eurovolby",
on_delete=models.PROTECT,
related_name="+",
blank=True,
null=True,
)
matomo_id = models.IntegerField( matomo_id = models.IntegerField(
"Matomo ID pro sledování návštěvnosti", blank=True, null=True "Matomo ID pro sledování návštěvnosti", blank=True, null=True
) )
...@@ -171,13 +153,6 @@ class MainHomePage( ...@@ -171,13 +153,6 @@ class MainHomePage(
FieldPanel("donation_page_text"), FieldPanel("donation_page_text"),
FieldPanel("social_links"), FieldPanel("social_links"),
FieldPanel("matomo_id"), FieldPanel("matomo_id"),
MultiFieldPanel(
[
FieldPanel("europarl_section_tag"),
FieldPanel("main_section_tag"),
],
heading="Tagy",
),
] ]
### EDIT HANDLERS ### EDIT HANDLERS
...@@ -223,10 +198,7 @@ class MainHomePage( ...@@ -223,10 +198,7 @@ class MainHomePage(
context = super().get_context(request, args, kwargs) context = super().get_context(request, args, kwargs)
context["article_data_list"] = ( context["article_data_list"] = (
MainArticlePage.objects.filter( MainArticlePage.objects
models.Q(section_tags__isnull=True)
| models.Q(section_tags=self.main_section_tag)
)
.live() .live()
.order_by("-date")[:3] .order_by("-date")[:3]
) )
...@@ -404,9 +376,18 @@ class MainArticlesPage( ...@@ -404,9 +376,18 @@ class MainArticlesPage(
class Meta: class Meta:
verbose_name = "Rozcestník článků" verbose_name = "Rozcestník článků"
def get_article_data_list(self, months_back: int = 1): def get_article_data_list(
self,
months_back: int = 1,
filtered_tag: Tag|None = None,
):
tag_filter = models.Q()
if filtered_tag is not None:
tag_filter = tag_filter & models.Q(tags=filtered_tag)
target_date_list = ( target_date_list = (
MainArticlePage.objects.order_by("-date") MainArticlePage.objects.filter(tag_filter).order_by("-date")
.live() .live()
.values_list("date", flat=True) .values_list("date", flat=True)
) )
...@@ -417,10 +398,10 @@ class MainArticlesPage( ...@@ -417,10 +398,10 @@ class MainArticlesPage(
target_date = target_date_list[0] - relativedelta(months=months_back) target_date = target_date_list[0] - relativedelta(months=months_back)
first_day_of_target_month = target_date.replace(day=1) first_day_of_target_month = target_date.replace(day=1)
filter = models.Q(date__gt=first_day_of_target_month) & tag_filter
sorted_article_qs = ( sorted_article_qs = (
MainArticlePage.objects.filter( MainArticlePage.objects.filter(filter)
date__gt=first_day_of_target_month,
)
.live() .live()
.order_by("-date") .order_by("-date")
) )
...@@ -440,11 +421,29 @@ class MainArticlesPage( ...@@ -440,11 +421,29 @@ class MainArticlesPage(
return article_data_list return article_data_list
def get_filtered_tag(self, request):
if "tag_id" in request.GET:
try:
tag = Tag.objects.filter(id=int(request.GET["tag_id"])).first()
except Exception:
tag = None
if tag is not None:
return tag
return None
def get_context(self, request, get_articles: bool = True, *args, **kwargs): def get_context(self, request, get_articles: bool = True, *args, **kwargs):
ctx = super().get_context(request, args, kwargs) ctx = super().get_context(request, args, kwargs)
if get_articles: if get_articles:
article_timeline_list = self.get_article_data_list(1) filtered_tag = self.get_filtered_tag(request)
if filtered_tag is not None:
ctx["filtered_tag"] = filtered_tag
article_timeline_list = self.get_article_data_list(1, filtered_tag)
ctx["article_timeline_list"] = article_timeline_list ctx["article_timeline_list"] = article_timeline_list
ctx[ ctx[
"show_next_timeline_articles" "show_next_timeline_articles"
...@@ -463,7 +462,7 @@ class MainArticlesPage( ...@@ -463,7 +462,7 @@ class MainArticlesPage(
tags = [] tags = []
for article in MainArticlePage.objects.all()[:50]: for article in MainArticlePage.objects.all()[:50]:
for tag in article.tags.names(): for tag in article.tags.all():
if tag in tags: if tag in tags:
continue continue
...@@ -471,6 +470,8 @@ class MainArticlesPage( ...@@ -471,6 +470,8 @@ class MainArticlesPage(
ctx["tags"] = tags ctx["tags"] = tags
# meow
return ctx return ctx
def get_timeline_articles_response(self, request): def get_timeline_articles_response(self, request):
...@@ -479,7 +480,9 @@ class MainArticlesPage( ...@@ -479,7 +480,9 @@ class MainArticlesPage(
except ValueError: except ValueError:
months = 1 months = 1
article_list = self.get_article_data_list(months) filtered_tag = self.get_filtered_tag(request)
article_list = self.get_article_data_list(months, filtered_tag)
context = {"article_timeline_list": article_list} context = {"article_timeline_list": article_list}
data = { data = {
"html": render( "html": render(
...@@ -570,26 +573,6 @@ class MainArticleTag(TaggedItemBase): ...@@ -570,26 +573,6 @@ class MainArticleTag(TaggedItemBase):
) )
class SectionTag(TagBase):
class Meta:
verbose_name = "Tag pro rozdělení do sekcí"
verbose_name_plural = "Tagy pro rozdělení do sekcí"
class MainArticleSectionTagged(TaggedItemBase):
tag = models.ForeignKey(
SectionTag,
on_delete=models.CASCADE,
related_name="%(app_label)s_%(class)s_items",
)
content_object = ParentalKey(
"main.MainArticlePage",
on_delete=models.CASCADE,
related_name="section_tagged_items",
)
class MainArticlePage( class MainArticlePage(
ArticleMixin, ExtendedMetadataPageMixin, SubpageMixin, MetadataPageMixin, Page ArticleMixin, ExtendedMetadataPageMixin, SubpageMixin, MetadataPageMixin, Page
): ):
...@@ -624,14 +607,6 @@ class MainArticlePage( ...@@ -624,14 +607,6 @@ class MainArticlePage(
blank=True, blank=True,
) )
section_tags = ClusterTaggableManager(
through=MainArticleSectionTagged,
verbose_name="Tagy pro rozdělení do sekcí",
help_text="Používá se například pro oddělení článků do sekce pro eurovolby. Pokud chceš, aby se články zobrazovaly pouze na hlavní stránce, nepřidávej žádné tagy.",
related_name="sectioned_articles",
blank=True,
)
search_fields = ArticleMixin.search_fields + [ search_fields = ArticleMixin.search_fields + [
index.SearchField("author_page"), index.SearchField("author_page"),
index.FilterField("slug"), index.FilterField("slug"),
...@@ -642,7 +617,6 @@ class MainArticlePage( ...@@ -642,7 +617,6 @@ class MainArticlePage(
content_panels = ArticleMixin.content_panels + [ content_panels = ArticleMixin.content_panels + [
FieldPanel("author_page"), FieldPanel("author_page"),
FieldPanel("tags"), FieldPanel("tags"),
FieldPanel("section_tags"),
FieldPanel("shared_tags"), FieldPanel("shared_tags"),
] ]
......
This diff is collapsed.
This diff is collapsed.
<a href="#" class="text px-4 py-2 text-black bg-yellow-500 duration-200 hover:bg-yellow-600 hover:no-underline"> <a
href="{% if tags_are_selectable %}?tag_id={{ id }}{% endif %}"
class="text px-4 py-2 text-black bg-yellow-500 duration-200 hover:bg-yellow-600 hover:no-underline"
style="
{% if filtered_tag.id == id %}
background:white!important;
text-color:black
{% endif %}
"
>
{{ text }} {{ text }}
</a> </a>
<div class="flex grow flex-col gap-0 md:flex-row md:gap-8"> <div class="flex grow flex-col gap-0 md:flex-row md:gap-8">
<div class="md:shrink-0"> <div class="md:shrink-0">
<a href="#"> <a href="{{ url }}">
<img <img
class="h-full w-36 object-cover rounded-full" class="h-36 w-36 object-cover rounded-full"
src="../../../../static/images/person-table.png" src="{{ image.url }}"
alt="{{ name }}" alt="{{ name }}"
> >
</a> </a>
...@@ -17,24 +17,30 @@ ...@@ -17,24 +17,30 @@
md:text-2xl md:text-2xl
xl:text-3xl xl:text-3xl
" "
href="#" href="{{ url }}"
><h4>{{ name }}</h4></a> ><h4>{{ name }}</h4></a>
{% if function %}
<span class="leading-6 mb-4 md:mb-6 w-10/12 text-grey-200"> <span class="leading-6 mb-4 md:mb-6 w-10/12 text-grey-200">
{{ function }} {{ function }}
</span> </span>
{% endif %}
</div> </div>
<div class="flex flex-col items-start"> <div class="flex flex-col items-start">
{% if telephone %}
<a <a
class="mb-2" class="mb-2"
href="tel:{{ telephone }}" href="tel:{{ telephone }}"
>{{ telephone }}</a> >{{ telephone }}</a>
{% endif %}
{% if mail %}
<a <a
class="text-pirati-yellow" class="text-pirati-yellow"
href="mailto:{{ mail }}" href="mailto:{{ mail }}"
>{{ mail }}</a> >{{ mail }}</a>
{% endif %}
</div> </div>
</div> </div>
</div> </div>
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
<div class="header-carousel"> <div class="header-carousel">
<div class="h-[700px] xl:h-screen relative"> <div class="h-[700px] xl:h-screen relative">
<img <img
class="header-carousel--image"
src="{% static 'main/images/background-images/bg-flag.webp' %}" src="{% static 'main/images/background-images/bg-flag.webp' %}"
draggable="false" draggable="false"
> >
......
<div class="flex gap-4 flex-wrap max-w-[550px] {{ classes }}"> <div class="flex gap-4 flex-wrap max-w-[550px] {{ classes }}">
{% for tag in tags %} {% for tag in tags %}
{% include 'main/includes/atoms/tags/tag.html' with text=tag %} {% include 'main/includes/atoms/tags/tag.html' with text=tag id=tag.id %}
{% endfor %} {% endfor %}
</div> </div>
{% if filtered_tag %}
<a href="?tag_id=" class="text-white pb-6 underline">
Resetovat tagy
</a>
{% endif %}
{% extends 'main/includes/organisms/header/simple_header_with_tags.html' %} {% extends 'main/includes/organisms/header/simple_header_with_tags.html' %}
{% block after_heading %} {% block after_heading %}
{% include 'main/includes/molecules/tags/tags.html' with classes='mb-4' %} {% include 'main/includes/molecules/tags/tags.html' with classes='mb-4' tags_are_selectable=True %}
<div class="flex justify-start"> <div class="flex justify-start">
<input <input
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
{% block after_description %} {% block after_description %}
<div <div
class=" class="
container--medium flex justify-start pl-[unset] pr-[unset] ml-[unset] mr-[unset] container--medium flex justify-start !pl-[unset] !pr-[unset] !ml-[unset] !mr-[unset]
xl:mb-12 mb-4 xl:mb-12 mb-4
" "
> >
......
{% load wagtailimages_tags %}
<footer class="bg-black text-white __js-root py-4 xl:py-24 pb-8 xl:pb-24"> <footer class="bg-black text-white __js-root py-4 xl:py-24 pb-8 xl:pb-24">
<ui-app inline-template> <ui-app inline-template>
<div <div
...@@ -30,8 +32,15 @@ ...@@ -30,8 +32,15 @@
<section class="flex flex-col xl:items-end"> <section class="flex flex-col xl:items-end">
<div class="flex flex-col gap-12"> <div class="flex flex-col gap-12">
{% include 'main/includes/molecules/contact/contact_footer_box.html' %} {% if page.root_page.footer_person_list %}
{% include 'main/includes/molecules/contact/contact_footer_box.html' %} {% for person in page.root_page.footer_person_list %}
{% image person.value.person.profile_image fill-256x256 as person_profile_image %}
{% firstof person.value.position person.value.person.position as position %}
{% include 'main/includes/molecules/contact/contact_footer_box.html' with image=person_profile_image url=person.value.person.url name=person.value.person.title function=position telephone=person.value.person.phone mail=person.value.person.email %}
{% endfor %}
{% endif %}
</div> </div>
</section> </section>
</div> </div>
......
...@@ -130,7 +130,7 @@ ...@@ -130,7 +130,7 @@
<div class="grid-left-side"> <div class="grid-left-side">
<img <img
class="w-[150px] mt-3" class="w-[150px] mt-3"
src="../../../../static/images/logo-full-black.svg" src="{% static 'main/images/logo-full-black.svg' %}"
alt="" alt=""
> >
</div> </div>
...@@ -166,7 +166,7 @@ ...@@ -166,7 +166,7 @@
href="{{ target }}" href="{{ target }}"
class=" class="
decoration-1 underline-offset-4 decoration-1 underline-offset-4
{% if item == selected_item %}navbar__menu-item--selected{% endif %} {% if menu_item.value.title == selected_item %}navbar__menu-item--selected{% endif %}
" "
>{{ menu_item.value.title }}</a> >{{ menu_item.value.title }}</a>
{% endfor %} {% endfor %}
......
{% extends "main/base.html" %}
{% load wagtailcore_tags wagtailimages_tags shared_filters %}
{% block content %}
{% include 'main/includes/layout/simple_page_header.html' with sub_heading=sub_heading %}
<main role="main">
<div class="__js-root">
<div class="grid-container article-section mb-8">
<div class="grid-full">
<div class="flex justify-center">
<div class="flex flex-col items-end gap-3">
<form
class="flex flex-row"
method="get"
action="{{ page.search_url }}"
>
<input
class="bg-grey-150 w-56 h-10 px-4 text-lg xl:h-14 xl:px-5"
type="text"
id="q"
name="q"
value="{{ query }}"
placeholder="Hledat články..."
aria-label="Vyhledávací box"
>
<button
class="btn btn--yellow-500 btn--to-yellow-600 btn--hoveractive"
aria-label="Vyhledat"
type="submit"
>
<div class="btn__body-wrap h-10 w-12 min-h-0 min-w-0 xl:h-14 xl:w-14">
<div class="btn__body p-0">
<i class="ico--search"></i>
</div>
</div>
</button>
</form>
<a href="{{ page.url }}" class="btn btn--black btn--to-yellow-500 btn--hoveractive uppercase">
<span class="btn__body-wrap">
<span class="btn__body text-lg lg:text-base">
Zpět na seznam
</span>
</span>
</a>
</div>
</div>
</div>
</div>
<section class="mb-3 xl:mb-14">
{% if article_results %}
<div id="searchArticleResultWrapper">
{% include 'main/includes/person_article_preview.html' with article_data_list=article_results %}
</div>
{% if show_more_articles %}
<div class="grid-container">
<div class="grid-content-with-right-side">
<a
onclick="showMoreArticles(event, this)"
href="#"
data-url="{{ page_url }}"
data-page="2"
data-query="{{ query }}"
class="btn btn--black btn--to-yellow-500 btn--hoveractive uppercase"
>
<span class="btn__body-wrap">
<span class="btn__body text-lg lg:text-base">
Zobrazit další
</span>
</span>
</a>
</div>
</div>
{% endif %}
{% else %}
<div class="grid-container article-section mb-8">
<div class="grid-full">
<p class="text-grey-300 text-center">Žádné výsledky.</p>
</div>
</div>
{% endif %}
</section>
{% include "main/includes/newsletter_section.html" %}
</div>
</main>
<script type="text/javascript">
async function showMoreArticles(event, btn) {
event.preventDefault()
let searchArticleResultWrapper = document.getElementById('searchArticleResultWrapper')
let url = (
btn.getAttribute('data-url')
+ `?page=${btn.getAttribute('data-page')}`
+ `&q=${btn.getAttribute('data-query')}`
)
const response = await fetch(url, {
method: "GET",
headers: {"X-Requested-With": "XMLHttpRequest"},
})
const data = await response.json()
searchArticleResultWrapper.innerHTML += data.html;
if (!data.has_next) { btn.style.display = 'none'; }
btn.setAttribute('data-page', parseInt(btn.getAttribute('data-page')) + 1)
}
</script>
{% endblock content %}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment