forked from ungleich-public/dynamicweb
107 lines
3.3 KiB
Python
107 lines
3.3 KiB
Python
|
|
from django.contrib.sites.models import Site
|
||
|
|
from django.db.models import Prefetch
|
||
|
|
from django.db.models.signals import post_delete, post_save
|
||
|
|
from django.utils.html import escape
|
||
|
|
from django.utils.safestring import mark_safe
|
||
|
|
|
||
|
|
from cms.cache.choices import (
|
||
|
|
_page_cache_key,
|
||
|
|
_site_cache_key,
|
||
|
|
clean_page_choices_cache,
|
||
|
|
clean_site_choices_cache,
|
||
|
|
)
|
||
|
|
from cms.models import Page
|
||
|
|
from cms.utils import i18n
|
||
|
|
|
||
|
|
|
||
|
|
def get_sites():
|
||
|
|
sites = (
|
||
|
|
Site
|
||
|
|
.objects
|
||
|
|
.filter(djangocms_pages__isnull=False)
|
||
|
|
.order_by('name')
|
||
|
|
.distinct()
|
||
|
|
)
|
||
|
|
return sites
|
||
|
|
|
||
|
|
|
||
|
|
def get_page_choices_for_site(site, language):
|
||
|
|
from cms.models import PageContent
|
||
|
|
|
||
|
|
fallbacks = i18n.get_fallback_languages(language, site_id=site.pk)
|
||
|
|
languages = [language] + fallbacks
|
||
|
|
translation_lookup = Prefetch(
|
||
|
|
'pagecontent_set',
|
||
|
|
to_attr='filtered_translations',
|
||
|
|
queryset=PageContent.objects.filter(language__in=languages).only('pk', 'page', 'language', 'title')
|
||
|
|
)
|
||
|
|
pages = (
|
||
|
|
Page
|
||
|
|
.objects
|
||
|
|
.on_site(site)
|
||
|
|
.prefetch_related(translation_lookup)
|
||
|
|
.order_by('path')
|
||
|
|
.only('pk')
|
||
|
|
)
|
||
|
|
|
||
|
|
for page in pages:
|
||
|
|
translations = page.filtered_translations
|
||
|
|
pagecontent_by_language = {trans.language: trans.title for trans in translations}
|
||
|
|
|
||
|
|
for lang in languages:
|
||
|
|
# EmptyPageContent is used to prevent the cms from trying
|
||
|
|
# to find a translation in the database
|
||
|
|
if lang in pagecontent_by_language:
|
||
|
|
title = pagecontent_by_language[lang]
|
||
|
|
indent = " " * (page.depth - 1)
|
||
|
|
label = mark_safe(f"{indent}{escape(title)}")
|
||
|
|
yield (page.pk, label)
|
||
|
|
break
|
||
|
|
|
||
|
|
|
||
|
|
def update_site_and_page_choices(language=None):
|
||
|
|
if language is None:
|
||
|
|
language = i18n.get_current_language()
|
||
|
|
|
||
|
|
site_choices = []
|
||
|
|
page_choices = [('', '----')]
|
||
|
|
site_choices_key = _site_cache_key(language)
|
||
|
|
page_choices_key = _page_cache_key(language)
|
||
|
|
|
||
|
|
for site in get_sites():
|
||
|
|
_page_choices = list(get_page_choices_for_site(site, language))
|
||
|
|
site_choices.append((site.pk, site.name))
|
||
|
|
page_choices.append((site.name, _page_choices))
|
||
|
|
|
||
|
|
from django.core.cache import cache
|
||
|
|
|
||
|
|
# We set it to 1 day here because we actively invalidate this cache.
|
||
|
|
cache.set(site_choices_key, site_choices, 86400)
|
||
|
|
cache.set(page_choices_key, page_choices, 86400)
|
||
|
|
return site_choices, page_choices
|
||
|
|
|
||
|
|
|
||
|
|
def get_site_choices(lang=None):
|
||
|
|
from django.core.cache import cache
|
||
|
|
|
||
|
|
lang = lang or i18n.get_current_language()
|
||
|
|
site_choices = cache.get(_site_cache_key(lang))
|
||
|
|
if site_choices is None:
|
||
|
|
site_choices, _ = update_site_and_page_choices(lang)
|
||
|
|
return site_choices
|
||
|
|
|
||
|
|
|
||
|
|
def get_page_choices(lang=None):
|
||
|
|
from django.core.cache import cache
|
||
|
|
|
||
|
|
lang = lang or i18n.get_current_language()
|
||
|
|
page_choices = cache.get(_page_cache_key(lang))
|
||
|
|
if page_choices is None:
|
||
|
|
_, page_choices = update_site_and_page_choices(lang)
|
||
|
|
return page_choices
|
||
|
|
|
||
|
|
|
||
|
|
post_save.connect(clean_page_choices_cache, sender=Page)
|
||
|
|
post_save.connect(clean_site_choices_cache, sender=Site)
|
||
|
|
post_delete.connect(clean_page_choices_cache, sender=Page)
|
||
|
|
post_delete.connect(clean_site_choices_cache, sender=Site)
|