django-cms-qe 4.0.0__py3-none-any.whl → 4.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
cms_qe/cms_menus.py ADDED
@@ -0,0 +1,134 @@
1
+ from cms.cms_menus import CMSNavigationNode, get_menu_node_for_page, get_visible_nodes
2
+ from cms.models import EmptyPageContent, Page, PageContent, PageUrl
3
+ from cms.toolbar.utils import get_toolbar_from_request
4
+ from cms.utils.i18n import get_fallback_languages, get_public_languages, hide_untranslated, is_valid_site_language
5
+ from cms.utils.page import get_page_queryset
6
+ from django.db.models.query import Prefetch, prefetch_related_objects
7
+ from django.http import HttpRequest
8
+ from menus.base import Menu
9
+
10
+
11
+ # This class i a copy of https://github.com/django-cms/django-cms/blob/4.1.7/cms/cms_menus.py#L199
12
+ # with extra function custom_menu_node.
13
+ class CMSMenu(Menu):
14
+ """Subclass of :class:`menus.base.Menu`. Its :meth:`~menus.base.Menu.get_nodes()` creates a list of NavigationNodes
15
+ based on a site's :class:`cms.models.pagemodel.Page` objects.
16
+ """
17
+
18
+ def get_nodes(self, request):
19
+ site = self.renderer.site
20
+ lang = self.renderer.request_language
21
+ toolbar = get_toolbar_from_request(request)
22
+
23
+ pages = get_page_queryset(site)
24
+
25
+ if is_valid_site_language(lang, site_id=site.pk):
26
+ _valid_language = True
27
+ _hide_untranslated = hide_untranslated(lang, site.pk)
28
+ else:
29
+ _valid_language = False
30
+ _hide_untranslated = False
31
+
32
+ if _valid_language:
33
+ # The request language has been explicitly configured
34
+ # for the current site.
35
+ if _hide_untranslated:
36
+ fallbacks = []
37
+ else:
38
+ fallbacks = get_fallback_languages(lang, site_id=site.pk)
39
+ languages = [lang] + [_lang for _lang in fallbacks if _lang != lang]
40
+ else:
41
+ # The request language is not configured for the current site.
42
+ # Fallback to all configured public languages for the current site.
43
+ languages = get_public_languages(site.pk)
44
+ fallbacks = languages
45
+
46
+ pages = (
47
+ pages.filter(pagecontent_set__language__in=languages)
48
+ .select_related("node")
49
+ .order_by("node__path")
50
+ .distinct()
51
+ )
52
+ pages = get_visible_nodes(request, pages, site)
53
+
54
+ if not pages:
55
+ return []
56
+
57
+ try:
58
+ homepage = [page for page in pages if page.is_home][0]
59
+ except IndexError:
60
+ homepage = None
61
+
62
+ urls_lookup = Prefetch(
63
+ "urls",
64
+ to_attr="filtered_urls",
65
+ queryset=PageUrl.objects.filter(language__in=languages),
66
+ )
67
+ if toolbar.edit_mode_active or toolbar.preview_mode_active:
68
+ # Get all translations visible in the admin for the current page
69
+ translations_qs = PageContent.admin_manager.current_content(language__in=languages)
70
+ else:
71
+ # Only get public translations
72
+ translations_qs = PageContent.objects.filter(language__in=languages)
73
+ translations_lookup = Prefetch(
74
+ "pagecontent_set",
75
+ to_attr="filtered_translations",
76
+ queryset=translations_qs,
77
+ )
78
+ prefetch_related_objects(pages, urls_lookup, translations_lookup)
79
+ # Build the blank title instances only once
80
+ blank_page_content_cache = {language: EmptyPageContent(language=language) for language in languages}
81
+
82
+ # Maps a node id to its page id
83
+ node_id_to_page: dict[int, int] = {}
84
+
85
+ def _page_to_node(page):
86
+ # EmptyPageContent is used to prevent the cms from trying
87
+ # to find a translation in the database
88
+ page.page_content_cache = blank_page_content_cache.copy()
89
+
90
+ for page_url in page.filtered_urls:
91
+ page.urls_cache[page_url.language] = page_url
92
+
93
+ for trans in page.filtered_translations:
94
+ page.page_content_cache[trans.language] = trans
95
+
96
+ menu_node = get_menu_node_for_page(
97
+ self.renderer,
98
+ page,
99
+ language=lang,
100
+ fallbacks=fallbacks,
101
+ endpoint=toolbar.preview_mode_active or toolbar.edit_mode_active,
102
+ )
103
+ return menu_node
104
+
105
+ menu_nodes = []
106
+
107
+ for page in pages:
108
+ node = page.node
109
+ parent_id = node_id_to_page.get(node.parent_id)
110
+
111
+ if node.parent_id and not parent_id:
112
+ # If the parent page is not available (unpublished, etc..)
113
+ # don't bother creating menu nodes for its descendants.
114
+ continue
115
+
116
+ menu_node = _page_to_node(page)
117
+ if menu_node:
118
+ # Only add pages with at least one page content
119
+ cut_homepage = homepage and not homepage.get_in_navigation(lang)
120
+
121
+ if cut_homepage and parent_id == homepage.pk:
122
+ # When the homepage is hidden from navigation,
123
+ # we need to cut all its direct children from it.
124
+ menu_node.parent_id = None
125
+ else:
126
+ menu_node.parent_id = parent_id
127
+ menu_node = self.custom_menu_node(request, page, menu_node)
128
+ node_id_to_page[node.pk] = page.pk
129
+ menu_nodes.append(menu_node)
130
+ return menu_nodes
131
+
132
+ def custom_menu_node(self, request: HttpRequest, page: Page, menu_node: CMSNavigationNode) -> CMSNavigationNode:
133
+ menu_node.attr["page_description"] = page.get_meta_description()
134
+ return menu_node
cms_qe/hooks.py CHANGED
@@ -12,6 +12,8 @@ from django.utils.translation import gettext_lazy as _
12
12
  from djangocms_alias.models import AliasContent
13
13
  from menus.menu_pool import MenuRenderer, menu_pool
14
14
 
15
+ from .cms_menus import CMSMenu
16
+
15
17
 
16
18
  def pg_is_in_recovery():
17
19
  """Return True when database is slave or False when database is master."""
@@ -46,6 +48,10 @@ class PgIsInRecoveryLoginView(LoginView):
46
48
 
47
49
  class PgIsInRecoveryMenuRenderer(MenuRenderer):
48
50
 
51
+ def __init__(self, pool, request):
52
+ pool.menus['CMSMenu'] = CMSMenu
53
+ super().__init__(pool, request)
54
+
49
55
  def get_nodes(self, namespace=None, root_id=None, breadcrumb=False):
50
56
  try:
51
57
  return super().get_nodes(namespace, root_id, breadcrumb)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: django-cms-qe
3
- Version: 4.0.0
3
+ Version: 4.1.0
4
4
  Summary: Django CMS Quick & Easy provides all important modules to run new page withouta lot of coding. Aims to do it very easily and securely.
5
5
  Home-page: https://websites.pages.nic.cz/django-cms-qe
6
6
  Author: CZ.NIC, z.s.p.o.
@@ -1,10 +1,11 @@
1
1
  cms_qe/__init__.py,sha256=do1c4s8BgjukMZMMMhBHs_lG9j8ncnAjR3oTICWEq5w,684
2
2
  cms_qe/admin.py,sha256=eLqAF3UIDWWyA0xE0Ft5WP5_3HImSWk3EYL2cRfL_8A,171
3
3
  cms_qe/apps.py,sha256=AeRcBWwGs7rKLlzHhnV8M_2BEnkoO9959VwesxfHaio,338
4
+ cms_qe/cms_menus.py,sha256=KdgZgvzRZwkpqviv3exizo_Vf5qtJziC7Q2yFRslJSQ,5470
4
5
  cms_qe/constants.py,sha256=YWUWCIabSwcamGZynvkJ9i8OWGtfHf-wFirm8GtqQpI,90
5
6
  cms_qe/export.py,sha256=3MflO_EmaCrlqqa-cTMOiRirsp3r4mxdQNt-Zh5FtzY,8242
6
7
  cms_qe/fixtures.py,sha256=cq_wnZnqBwPBOHpp_0bHk424iCXKvwmN6ZaKwDvguXk,755
7
- cms_qe/hooks.py,sha256=L9gLppl74Gj8euTJ1vWuSlc553ZAFAkj6mZaGw7iaW8,3330
8
+ cms_qe/hooks.py,sha256=Bu8eV2E8wTeOAPET8C_YocwMV6h5XLItPO3ItCkV-yI,3482
8
9
  cms_qe/ldap.py,sha256=2mpFdLoIdT_pAiGJ6ADnE74YXjaC55aNANv0L8DVwqU,188
9
10
  cms_qe/monitoring.py,sha256=5t_o7o0htmAAxVjkN2oz0O0v9XdzfePhSfPGcLNPmE8,769
10
11
  cms_qe/signals.py,sha256=MbuLSxPlJA147LEg-lDWDoUNTV1y0OKjwoI3HzgR97g,1253
@@ -3969,7 +3970,7 @@ cms_qe_video/templates/cms_qe/video/video_source_file.html,sha256=QJF5fs88s9Fznp
3969
3970
  cms_qe_video/templates/cms_qe/video/video_widget.html,sha256=Yumciq6bGlAYI1lYx5j9V6IF8QYrncNYygPTkXEz6Wk,925
3970
3971
  cms_qe_video/templatetags/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3971
3972
  cms_qe_video/templatetags/cms_qe_video.py,sha256=NR_mGv91J0rEreZrQjCzaaXSrZsKvrSas12wMJ-Dg24,1168
3972
- django_cms_qe-4.0.0.dist-info/licenses/LICENSE,sha256=5wLaeUil0gfU9p8C4zn2Yu_PvZBNieUoYl0z9FcFWdA,1521
3973
+ django_cms_qe-4.1.0.dist-info/licenses/LICENSE,sha256=5wLaeUil0gfU9p8C4zn2Yu_PvZBNieUoYl0z9FcFWdA,1521
3973
3974
  test_selenium/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3974
3975
  test_selenium/browser.py,sha256=OcfqxDa9OtL7M5CSwfIxtzToMUEhqGLvditemPeEUNo,1437
3975
3976
  test_selenium/conftest.py,sha256=mAptaAyj7a1hbUPDRWBBs1qL0TJ8Fma7Mch6PZwgtNo,220
@@ -3983,7 +3984,7 @@ test_selenium/pages/cms/__init__.py,sha256=_qe4YZYaQbrXp7Szmmeo4TUSkXlE5Rozu8E3t
3983
3984
  test_selenium/pages/cms/login.py,sha256=UPzJQcYff8NUAT4nvmfQoJQxzOJyPrJ_cKtH35NVfNg,521
3984
3985
  test_selenium/pages/cms/page.py,sha256=YQnpZkopfVnhoyQKpRDGqjNeV6xUl-pEHjEcZ9HRiPk,489
3985
3986
  test_selenium/pages/cms/wizard.py,sha256=yatbXH-rf1ap4O1hY0I13WikM3zkm_NrAiSK6bqENIU,545
3986
- django_cms_qe-4.0.0.dist-info/METADATA,sha256=FPRi3dhCo5NVRqvJF7p5cRCwK_yiYEpii8qtjsNSQYI,6234
3987
- django_cms_qe-4.0.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
3988
- django_cms_qe-4.0.0.dist-info/top_level.txt,sha256=fQYSfQoprw1NXhYY-I8AzsPk-Rgst1REh3iOUvwAbkM,164
3989
- django_cms_qe-4.0.0.dist-info/RECORD,,
3987
+ django_cms_qe-4.1.0.dist-info/METADATA,sha256=Jh_kHri1S4t76H1AAFtTMjvzx56EFXELL2HgwBEtzNI,6234
3988
+ django_cms_qe-4.1.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
3989
+ django_cms_qe-4.1.0.dist-info/top_level.txt,sha256=fQYSfQoprw1NXhYY-I8AzsPk-Rgst1REh3iOUvwAbkM,164
3990
+ django_cms_qe-4.1.0.dist-info/RECORD,,