diff --git a/district/management/commands/octopus_people_import.py b/district/management/commands/octopus_people_import.py index 48ee4ca9c9c86a90c2a17ce9e926c442495f705b..330a0613db2f645828925d3faea69be12cbf43b4 100644 --- a/district/management/commands/octopus_people_import.py +++ b/district/management/commands/octopus_people_import.py @@ -52,9 +52,10 @@ class Command(BaseCommand): for person_page in DistrictManualOctopusPersonPage.objects.all(): import_manual_person.delay( - person_page.id, ( + person_page.id, + ( person_page.root_page.image_collection_id if hasattr(person_page.root_page, "image_collection_id") else 0 - ) + ), ) diff --git a/district/migrations/0319_auto_20250508_1642.py b/district/migrations/0319_auto_20250508_1642.py index 3a9cbf538e5e3262e67a16f8b040d8fd07640155..2d5382061581d6777d89592b8522b8423863e8c9 100644 --- a/district/migrations/0319_auto_20250508_1642.py +++ b/district/migrations/0319_auto_20250508_1642.py @@ -4,13 +4,12 @@ from django.db import migrations def add_district_search_pages(apps, schema_editor): - from district.models import DistrictHomePage - from district.models import DistrictSearchPage + from district.models import DistrictHomePage, DistrictSearchPage for home_page in DistrictHomePage.objects.all(): if DistrictSearchPage.objects.descendant_of(home_page).exists(): unlive_page = DistrictSearchPage.objects.descendant_of(home_page).first() - + if unlive_page is None: continue @@ -18,7 +17,7 @@ def add_district_search_pages(apps, schema_editor): unlive_page.save_revision().publish() continue - + search_page = DistrictSearchPage( title="Vyhledávací stránka", slug="search", @@ -31,11 +30,8 @@ def add_district_search_pages(apps, schema_editor): class Migration(migrations.Migration): - dependencies = [ - ('district', '0318_districthomepage_ecomail_newsletter_list_source'), + ("district", "0318_districthomepage_ecomail_newsletter_list_source"), ] - operations = [ - migrations.RunPython(add_district_search_pages) - ] + operations = [migrations.RunPython(add_district_search_pages)] diff --git a/shared/models/main.py b/shared/models/main.py index 817293efff587c05249e70c9d9a735523b9f503e..a9e5279d3aa04d42a9e81099b6b5e0936df13f85 100644 --- a/shared/models/main.py +++ b/shared/models/main.py @@ -1,5 +1,6 @@ import datetime import logging +import random from collections import namedtuple from enum import Enum from functools import cached_property, reduce @@ -321,10 +322,9 @@ class PageInMenuMixin(Page): def get_menu_title(self, parent_instance=None) -> str: instance = self if parent_instance is None else parent_instance - menu_iterator = ( - getattr(getattr(instance, "root_page", None), "menu", None) - or getattr(instance, "menu", []) - ) + menu_iterator = getattr( + getattr(instance, "root_page", None), "menu", None + ) or getattr(instance, "menu", []) for menu in menu_iterator: if menu.block_type == "menu_item": @@ -1723,6 +1723,87 @@ class MainArticlePageMixin( ### END Relations + ### BEGIN Custom serving + + def serve(self, request, *args, **kwargs): + NUM_ARTICLES = 4 + + get_related_articles = request.GET.get("get_related_articles") + + all_articles_in_same_web = ( + type(self.specific) + .objects.filter(~Q(id=self.specific.id)) + .live() + .descendant_of(self.root_page.articles_page) + ) + + if get_related_articles: + # Make a while True loop here so we can break whenever + # instead of making nested if-else statements. + + while True: + ### Enough with same tag in this web + articles_with_same_tags = list( + all_articles_in_same_web.filter( + tags__in=self.get_tags, + ).all() + ) + + picked_articles = [] + + if len(articles_with_same_tags) == NUM_ARTICLES: + picked_articles = random.sample( + articles_with_same_tags, + min(NUM_ARTICLES, len(articles_with_same_tags)), + ) + break + + ### Enough in this web, just without same tags + needed_extra_articles_num = NUM_ARTICLES - len(articles_with_same_tags) + + articles_without_same_tags = list(all_articles_in_same_web.all()) + picked_articles_without_same_tags = random.sample( + articles_without_same_tags, + min(needed_extra_articles_num, len(articles_without_same_tags)), + ) + + picked_articles = ( + articles_with_same_tags + picked_articles_without_same_tags + ) + + if len(picked_articles) == NUM_ARTICLES: + break + else: + ### Use MainArticlePages to supplement if there aren't even enough articles + ### in this web. If there are no MainArticlePages, we're in a testing env + ### where it doesn't matter much. + from main.models import MainArticlePage + + needed_supplementary_articles_num = NUM_ARTICLES - len( + picked_articles + ) + main_web_articles = list( + MainArticlePage.objects.all()[ + : needed_supplementary_articles_num - 1 + ] + ) + + picked_articles += main_web_articles + + # Always break here so this only loops once no matter what, + # even if for some reason conditions aren't met. + break + + return render( + request, + "styleguide2/includes/organisms/articles/article_links_block.html", + {"articles": picked_articles}, + ) + + return super().serve(request, *args, **kwargs) + + ### END Custom serving + ### BEGIN Pages @property diff --git a/shared/templates/styleguide2/article_page.html b/shared/templates/styleguide2/article_page.html index b69c07599fad0129a285cd600f51cbc6d7dafbe9..5608a4fbd67861b2194e179517d3d12b1853566d 100644 --- a/shared/templates/styleguide2/article_page.html +++ b/shared/templates/styleguide2/article_page.html @@ -28,12 +28,49 @@ {% include_block block %} {% endfor %} - <div class="flex justify-start"> - {% include 'styleguide2/includes/atoms/buttons/round_button.html' with url=page.root_page.articles_page.url text='Zpět na aktuality' show_arrow_on_hover=True %} + <div class="flex justify-start gap-4"> + {% include 'styleguide2/includes/atoms/buttons/round_button.html' with classes="bg-pirati-yellow text-black" fill="black" id="similar-articles" text='Související články' show_arrow_on_hover=True %} + {% include 'styleguide2/includes/atoms/buttons/round_button.html' with url=page.root_page.articles_page.url text='Zpět na seznam aktualit' show_arrow_on_hover=True %} </div> + + <div id="similar-articles-container"></div> </div> </main> +<script> + let similarArticlesOpen = false; + + document.getElementById("similar-articles").addEventListener( + "click", + async function (event) { + const container = document.getElementById("similar-articles-container"); + + if (!similarArticlesOpen) { + this.disabled = true; + + const articlesResponse = await fetch("./?get_related_articles=1") + + if (!articlesResponse.ok) { + throw new Error(`Could not get articles: status ${articlesResponse.status}. Check network logs`); + similarArticlesOpen = !similarArticlesOpen; + } + + container.innerHTML = await articlesResponse.text(); + container.style.display = "block"; + + this.disabled = false; + document.getElementById(`${this.id}-inner-text`).innerHTML = "Zavřít související články"; + this.scrollIntoView(); + } else { + container.style.display = "none"; + document.getElementById(`${this.id}-inner-text`).innerHTML = "Související články"; + } + + similarArticlesOpen = !similarArticlesOpen; + } + ) +</script> + {% include 'styleguide2/includes/organisms/main_section/newsletter_section.html' %} {% endblock %} diff --git a/shared/templates/styleguide2/includes/organisms/articles/article_links_block.html b/shared/templates/styleguide2/includes/organisms/articles/article_links_block.html index aeb85444f5ae424c537325f423998608c51ddffe..3627f97fa922055ceb5b87793d26326e168bb5d0 100644 --- a/shared/templates/styleguide2/includes/organisms/articles/article_links_block.html +++ b/shared/templates/styleguide2/includes/organisms/articles/article_links_block.html @@ -1,3 +1,14 @@ +{# Allow either "articles" or "self.articles" to be used in the same way. #} +{# TODO Make this cleaner #} + +{% if articles|length != 0 %} + <div class="grid grid-cols-1 md:grid-cols-2 gap-12"> + {% for article in articles %} + {% include 'styleguide2/includes/molecules/articles/article_title_preview.html' %} + {% endfor %} + </div> +{% endif %} + {% if self.articles|length != 0 %} <div class="grid grid-cols-1 md:grid-cols-2 gap-12"> {% for article in self.articles %} diff --git a/uniweb/migrations/0138_auto_20250508_1752.py b/uniweb/migrations/0138_auto_20250508_1752.py index 2fefb91dec57e4149060d0bed303f1ae8fa95a01..953f53cafaa0cb26b2242ca46baf40b67f8df9a9 100644 --- a/uniweb/migrations/0138_auto_20250508_1752.py +++ b/uniweb/migrations/0138_auto_20250508_1752.py @@ -4,13 +4,12 @@ from django.db import migrations def add_uniweb_search_pages(apps, schema_editor): - from uniweb.models import UniwebHomePage - from uniweb.models import UniwebSearchPage + from uniweb.models import UniwebHomePage, UniwebSearchPage for home_page in UniwebHomePage.objects.all(): if UniwebSearchPage.objects.descendant_of(home_page).exists(): unlive_page = UniwebSearchPage.objects.descendant_of(home_page).first() - + if unlive_page is None: continue @@ -18,7 +17,7 @@ def add_uniweb_search_pages(apps, schema_editor): unlive_page.save_revision().publish() continue - + search_page = UniwebSearchPage( title="Vyhledávací stránka", slug="search", @@ -31,11 +30,8 @@ def add_uniweb_search_pages(apps, schema_editor): class Migration(migrations.Migration): - dependencies = [ - ('uniweb', '0137_uniwebformpage_submission_button_text'), + ("uniweb", "0137_uniwebformpage_submission_button_text"), ] - operations = [ - migrations.RunPython(add_uniweb_search_pages) - ] + operations = [migrations.RunPython(add_uniweb_search_pages)]