wagtail-cjkcms 23.9.2__py2.py3-none-any.whl → 23.10.2__py2.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.
Files changed (45) hide show
  1. cjkcms/__init__.py +1 -1
  2. cjkcms/blocks/__init__.py +6 -0
  3. cjkcms/blocks/content/events.py +16 -0
  4. cjkcms/migrations/0015_eventcalendar.py +49 -0
  5. cjkcms/migrations/0016_layoutsettings_breadcrumb_icon_and_more.py +32 -0
  6. cjkcms/models/admin_sidebar.py +12 -1
  7. cjkcms/models/snippet_models.py +47 -1
  8. cjkcms/models/wagtailsettings_models.py +22 -2
  9. cjkcms/static/cjkcms/css/cjkcms-front.css +6 -0
  10. cjkcms/static/cjkcms/images/icons/calendar-day.svg +1 -0
  11. cjkcms/static/cjkcms/images/icons/caret-right-fill.svg +3 -0
  12. cjkcms/static/cjkcms/images/icons/caret-right.svg +3 -0
  13. cjkcms/static/cjkcms/images/icons/chevron-right.svg +3 -0
  14. cjkcms/static/cjkcms/images/icons/slash.svg +3 -0
  15. cjkcms/static/cjkcms/images/icons/world.svg +3 -0
  16. cjkcms/templates/cjkcms/blocks/event_calendar_block.html +6 -0
  17. cjkcms/templates/cjkcms/blocks/public_event_block.html +14 -3
  18. cjkcms/templates/cjkcms/pages/base.html +5 -0
  19. cjkcms/templates/cjkcms/pages/search.html +2 -2
  20. cjkcms/templates/cjkcms/pages/web_page_notitle.html +4 -0
  21. cjkcms/templates/cjkcms/snippets/breadcrumbs.html +27 -0
  22. cjkcms/templates/cjkcms/snippets/navbar_search.html +2 -5
  23. cjkcms/templatetags/cjkcms_tags.py +24 -1
  24. cjkcms/tests/manage.py +10 -0
  25. cjkcms/tests/settings.py +88 -0
  26. cjkcms/tests/test_advsettings.py +198 -0
  27. cjkcms/tests/test_templatetags.py +41 -2
  28. cjkcms/tests/testapp/__init__.py +0 -0
  29. cjkcms/tests/testapp/apps.py +6 -0
  30. cjkcms/tests/testapp/migrations/0001_initial.py +144 -0
  31. cjkcms/tests/testapp/migrations/0002_create_homepage.py +62 -0
  32. cjkcms/tests/testapp/migrations/__init__.py +0 -0
  33. cjkcms/tests/testapp/models.py +19 -0
  34. cjkcms/tests/urls.py +26 -0
  35. cjkcms/utils.py +5 -2
  36. cjkcms/wagtail_hooks.py +2 -1
  37. {wagtail_cjkcms-23.9.2.dist-info → wagtail_cjkcms-23.10.2.dist-info}/METADATA +3 -2
  38. {wagtail_cjkcms-23.9.2.dist-info → wagtail_cjkcms-23.10.2.dist-info}/RECORD +44 -25
  39. cjkcms/draftail/draftail_icons.py +0 -17
  40. /cjkcms/{media → tests/media}/images/test.original.png +0 -0
  41. /cjkcms/{media → tests/media}/original_images/test.png +0 -0
  42. {wagtail_cjkcms-23.9.2.dist-info → wagtail_cjkcms-23.10.2.dist-info}/LICENSE +0 -0
  43. {wagtail_cjkcms-23.9.2.dist-info → wagtail_cjkcms-23.10.2.dist-info}/WHEEL +0 -0
  44. {wagtail_cjkcms-23.9.2.dist-info → wagtail_cjkcms-23.10.2.dist-info}/entry_points.txt +0 -0
  45. {wagtail_cjkcms-23.9.2.dist-info → wagtail_cjkcms-23.10.2.dist-info}/top_level.txt +0 -0
cjkcms/__init__.py CHANGED
@@ -1,4 +1,4 @@
1
- VERSION = (23, 9, 2, "")
1
+ VERSION = (23, 10, 2, "")
2
2
 
3
3
  __version_info__ = VERSION
4
4
  __version__ = ".".join(map(str, VERSION[:3])) + (f"-{VERSION[3]}" if VERSION[3] else "")
cjkcms/blocks/__init__.py CHANGED
@@ -32,6 +32,7 @@ from .content_blocks import ( # noqa
32
32
  PriceListBlock,
33
33
  ReusableContentBlock,
34
34
  )
35
+ from .content.events import PublicEventBlock, EventCalendarBlock
35
36
  from .layout_blocks import CardGridBlock, GridBlock, HeroBlock
36
37
  from cjkcms.settings import cms_settings
37
38
 
@@ -73,6 +74,7 @@ CONTENT_STREAMBLOCKS = HTML_STREAMBLOCKS + [
73
74
  ("modal", ModalBlock(HTML_STREAMBLOCKS)),
74
75
  ("pricelist", PriceListBlock()),
75
76
  ("reusable_content", ReusableContentBlock()),
77
+ ("event_calendar", EventCalendarBlock()),
76
78
  ]
77
79
 
78
80
  NAVIGATION_STREAMBLOCKS = [
@@ -81,6 +83,10 @@ NAVIGATION_STREAMBLOCKS = [
81
83
  ("document_link", NavDocumentLinkWithSubLinkBlock()),
82
84
  ]
83
85
 
86
+ PUBLIC_EVENT_STREAMBLOCKS = [
87
+ ("event", PublicEventBlock()),
88
+ ]
89
+
84
90
  BASIC_LAYOUT_STREAMBLOCKS = [
85
91
  ("row", GridBlock(HTML_STREAMBLOCKS)),
86
92
  (
@@ -1,6 +1,7 @@
1
1
  from cjkcms.blocks.base_blocks import BaseBlock
2
2
  from wagtail import blocks
3
3
  from django.utils.translation import gettext_lazy as _
4
+ from wagtail.snippets.blocks import SnippetChooserBlock
4
5
 
5
6
 
6
7
  class PublicEventBlock(BaseBlock):
@@ -57,4 +58,19 @@ class PublicEventBlock(BaseBlock):
57
58
  template = "cjkcms/blocks/public_event_block.html"
58
59
  icon = "view"
59
60
  label = "Public Event"
61
+ ordering = ["start_date"]
60
62
  label_format = _("{title} (Event)")
63
+
64
+
65
+ class EventCalendarBlock(BaseBlock):
66
+ """
67
+ Allows selecting an event calendar snippet
68
+ """
69
+
70
+ event_calendar = SnippetChooserBlock("cjkcms.EventCalendar")
71
+
72
+ class Meta:
73
+ template = "cjkcms/blocks/event_calendar_block.html"
74
+ icon = "calendar"
75
+ label = _("Event calendar")
76
+ label_format = _("Event calendar")
@@ -0,0 +1,49 @@
1
+ # Generated by Django 4.2.5 on 2023-09-30 21:11
2
+
3
+ import cjkcms.fields
4
+ from django.db import migrations, models
5
+
6
+
7
+ class Migration(migrations.Migration):
8
+ dependencies = [
9
+ ("cjkcms", "0014_navbar_alignment"),
10
+ ]
11
+
12
+ operations = [
13
+ migrations.CreateModel(
14
+ name="EventCalendar",
15
+ fields=[
16
+ (
17
+ "id",
18
+ models.BigAutoField(
19
+ auto_created=True,
20
+ primary_key=True,
21
+ serialize=False,
22
+ verbose_name="ID",
23
+ ),
24
+ ),
25
+ ("name", models.CharField(max_length=255, verbose_name="Name")),
26
+ (
27
+ "custom_css_class",
28
+ models.CharField(
29
+ blank=True, max_length=255, verbose_name="Custom CSS Class"
30
+ ),
31
+ ),
32
+ (
33
+ "custom_id",
34
+ models.CharField(
35
+ blank=True, max_length=255, verbose_name="Custom ID"
36
+ ),
37
+ ),
38
+ (
39
+ "events",
40
+ cjkcms.fields.CjkcmsStreamField(
41
+ use_json_field=True, verbose_name="Events"
42
+ ),
43
+ ),
44
+ ],
45
+ options={
46
+ "verbose_name": "Event calendar",
47
+ },
48
+ ),
49
+ ]
@@ -0,0 +1,32 @@
1
+ # Generated by Django 4.2.6 on 2023-10-07 09:55
2
+
3
+ from django.db import migrations, models
4
+
5
+
6
+ class Migration(migrations.Migration):
7
+ dependencies = [
8
+ ("cjkcms", "0015_eventcalendar"),
9
+ ]
10
+
11
+ operations = [
12
+ migrations.AddField(
13
+ model_name="layoutsettings",
14
+ name="breadcrumb_icon",
15
+ field=models.CharField(
16
+ blank=True,
17
+ default="slash",
18
+ help_text="Bootstrap icon name. See docs for built-in options.",
19
+ max_length=32,
20
+ verbose_name="Breadcrumb icon",
21
+ ),
22
+ ),
23
+ migrations.AddField(
24
+ model_name="layoutsettings",
25
+ name="breadcrumbs",
26
+ field=models.BooleanField(
27
+ default=False,
28
+ help_text="Show breadcrumbs in page header",
29
+ verbose_name="Breadcrumbs",
30
+ ),
31
+ ),
32
+ ]
@@ -1,4 +1,4 @@
1
- from .snippet_models import Navbar
1
+ from .snippet_models import Navbar, EventCalendar
2
2
  from wagtail.snippets.views.snippets import SnippetViewSet
3
3
 
4
4
 
@@ -15,3 +15,14 @@ class NavbarSnippet(SnippetViewSet):
15
15
  search_fields = [
16
16
  "name",
17
17
  ]
18
+
19
+
20
+ class EventCalendarSnippet(SnippetViewSet):
21
+ model = EventCalendar
22
+ menu_label = "Public Events"
23
+ menu_icon = "calendar" # change as required
24
+ # add_to_admin_menu = True
25
+ list_display = ("name",)
26
+ search_fields = [
27
+ "name",
28
+ ]
@@ -18,6 +18,7 @@ from cjkcms.blocks import (
18
18
  HTML_STREAMBLOCKS,
19
19
  LAYOUT_STREAMBLOCKS,
20
20
  NAVIGATION_STREAMBLOCKS,
21
+ PUBLIC_EVENT_STREAMBLOCKS,
21
22
  )
22
23
  from cjkcms.settings import cms_settings
23
24
  from django.conf import settings
@@ -301,7 +302,6 @@ class FilmPanel(Orderable, models.Model):
301
302
  ]
302
303
 
303
304
 
304
- # @register_snippet
305
305
  class Navbar(models.Model):
306
306
  """
307
307
  Snippet for site navigation bars (header, main menu, etc.)
@@ -589,3 +589,49 @@ class CjkcmsEmail(ClusterableModel):
589
589
 
590
590
  def __str__(self):
591
591
  return self.subject
592
+
593
+
594
+ class EventCalendar(models.Model):
595
+ """
596
+ Snippet for site event calendars
597
+ """
598
+
599
+ class Meta:
600
+ verbose_name = _("Event calendar")
601
+
602
+ name = models.CharField(
603
+ max_length=255,
604
+ verbose_name=_("Name"),
605
+ )
606
+ custom_css_class = models.CharField(
607
+ max_length=255,
608
+ blank=True,
609
+ verbose_name=_("Custom CSS Class"),
610
+ )
611
+ custom_id = models.CharField(
612
+ max_length=255,
613
+ blank=True,
614
+ verbose_name=_("Custom ID"),
615
+ )
616
+
617
+ events = CjkcmsStreamField(
618
+ PUBLIC_EVENT_STREAMBLOCKS,
619
+ verbose_name=_("Events"),
620
+ use_json_field=True,
621
+ )
622
+
623
+ panels = [
624
+ FieldPanel("name"),
625
+ MultiFieldPanel(
626
+ [
627
+ FieldPanel("custom_css_class"),
628
+ FieldPanel("custom_id"),
629
+ ],
630
+ heading=_("Attributes"),
631
+ classname="collapsed",
632
+ ),
633
+ FieldPanel("events"),
634
+ ]
635
+
636
+ def __str__(self):
637
+ return self.name
@@ -197,6 +197,19 @@ class LayoutSettings(ClusterableModel, BaseSiteSetting):
197
197
  help_text=_("Choose lang choice selector"),
198
198
  )
199
199
 
200
+ breadcrumbs = models.BooleanField(
201
+ default=False,
202
+ verbose_name=_("Breadcrumbs"),
203
+ help_text=_("Show breadcrumbs in page header"),
204
+ )
205
+ breadcrumb_icon = models.CharField(
206
+ blank=True,
207
+ max_length=32,
208
+ default="slash",
209
+ verbose_name=_("Breadcrumb icon"),
210
+ help_text=_("Bootstrap icon name. See docs for built-in options."),
211
+ )
212
+
200
213
  frontend_theme = models.CharField(
201
214
  blank=True,
202
215
  max_length=50,
@@ -289,6 +302,13 @@ class LayoutSettings(ClusterableModel, BaseSiteSetting):
289
302
  ],
290
303
  heading=_("Site Navbar Layout"),
291
304
  ),
305
+ MultiFieldPanel(
306
+ [
307
+ FieldPanel("breadcrumbs"),
308
+ FieldPanel("breadcrumb_icon"),
309
+ ],
310
+ heading=_("Site Header / Breadcrumbs"),
311
+ ),
292
312
  InlinePanel(
293
313
  "site_footer",
294
314
  help_text=_("Choose one or more footers"),
@@ -354,7 +374,7 @@ class LayoutSettings(ClusterableModel, BaseSiteSetting):
354
374
  class NavbarOrderable(Orderable, models.Model):
355
375
  navbar_chooser = ParentalKey(
356
376
  LayoutSettings, related_name="site_navbar", verbose_name=_("Site Navbars")
357
- )
377
+ ) # type: ignore
358
378
  navbar = models.ForeignKey(
359
379
  Navbar,
360
380
  blank=True,
@@ -368,7 +388,7 @@ class NavbarOrderable(Orderable, models.Model):
368
388
  class FooterOrderable(Orderable, models.Model):
369
389
  footer_chooser = ParentalKey(
370
390
  LayoutSettings, related_name="site_footer", verbose_name=_("Site Footers")
371
- )
391
+ ) # type: ignore
372
392
  footer = models.ForeignKey(
373
393
  Footer,
374
394
  blank=True,
@@ -292,4 +292,10 @@ License: https://github.com/coderedcorp/coderedcms/blob/dev/LICENSE
292
292
  .modal {
293
293
  max-width: none;
294
294
  margin: 1.75rem auto;
295
+ }
296
+
297
+ #id_s {
298
+ margin-bottom: 0;
299
+ margin-top: 0;
300
+ border: gray 1px solid;
295
301
  }
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" height="1em" viewBox="0 0 448 512"><!--! Font Awesome Free 6.4.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M128 0c17.7 0 32 14.3 32 32V64H288V32c0-17.7 14.3-32 32-32s32 14.3 32 32V64h48c26.5 0 48 21.5 48 48v48H0V112C0 85.5 21.5 64 48 64H96V32c0-17.7 14.3-32 32-32zM0 192H448V464c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V192zm80 64c-8.8 0-16 7.2-16 16v96c0 8.8 7.2 16 16 16h96c8.8 0 16-7.2 16-16V272c0-8.8-7.2-16-16-16H80z"/></svg>
@@ -0,0 +1,3 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-caret-right-fill" viewBox="0 0 16 16">
2
+ <path d="m12.14 8.753-5.482 4.796c-.646.566-1.658.106-1.658-.753V3.204a1 1 0 0 1 1.659-.753l5.48 4.796a1 1 0 0 1 0 1.506z"/>
3
+ </svg>
@@ -0,0 +1,3 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-caret-right" viewBox="0 0 16 16">
2
+ <path d="M6 12.796V3.204L11.481 8 6 12.796zm.659.753 5.48-4.796a1 1 0 0 0 0-1.506L6.66 2.451C6.011 1.885 5 2.345 5 3.204v9.592a1 1 0 0 0 1.659.753z"/>
3
+ </svg>
@@ -0,0 +1,3 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-chevron-right" viewBox="0 0 16 16">
2
+ <path fill-rule="evenodd" d="M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z"/>
3
+ </svg>
@@ -0,0 +1,3 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-slash-lg" viewBox="0 0 16 16">
2
+ <path fill-rule="evenodd" d="M13.854 2.146a.5.5 0 0 1 0 .708l-11 11a.5.5 0 0 1-.708-.708l11-11a.5.5 0 0 1 .708 0Z"/>
3
+ </svg>
@@ -0,0 +1,3 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-globe" viewBox="0 0 16 16">
2
+ <path d="M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8zm7.5-6.923c-.67.204-1.335.82-1.887 1.855A7.97 7.97 0 0 0 5.145 4H7.5V1.077zM4.09 4a9.267 9.267 0 0 1 .64-1.539 6.7 6.7 0 0 1 .597-.933A7.025 7.025 0 0 0 2.255 4H4.09zm-.582 3.5c.03-.877.138-1.718.312-2.5H1.674a6.958 6.958 0 0 0-.656 2.5h2.49zM4.847 5a12.5 12.5 0 0 0-.338 2.5H7.5V5H4.847zM8.5 5v2.5h2.99a12.495 12.495 0 0 0-.337-2.5H8.5zM4.51 8.5a12.5 12.5 0 0 0 .337 2.5H7.5V8.5H4.51zm3.99 0V11h2.653c.187-.765.306-1.608.338-2.5H8.5zM5.145 12c.138.386.295.744.468 1.068.552 1.035 1.218 1.65 1.887 1.855V12H5.145zm.182 2.472a6.696 6.696 0 0 1-.597-.933A9.268 9.268 0 0 1 4.09 12H2.255a7.024 7.024 0 0 0 3.072 2.472zM3.82 11a13.652 13.652 0 0 1-.312-2.5h-2.49c.062.89.291 1.733.656 2.5H3.82zm6.853 3.472A7.024 7.024 0 0 0 13.745 12H11.91a9.27 9.27 0 0 1-.64 1.539 6.688 6.688 0 0 1-.597.933zM8.5 12v2.923c.67-.204 1.335-.82 1.887-1.855.173-.324.33-.682.468-1.068H8.5zm3.68-1h2.146c.365-.767.594-1.61.656-2.5h-2.49a13.65 13.65 0 0 1-.312 2.5zm2.802-3.5a6.959 6.959 0 0 0-.656-2.5H12.18c.174.782.282 1.623.312 2.5h2.49zM11.27 2.461c.247.464.462.98.64 1.539h1.835a7.024 7.024 0 0 0-3.072-2.472c.218.284.418.598.597.933zM10.855 4a7.966 7.966 0 0 0-.468-1.068C9.835 1.897 9.17 1.282 8.5 1.077V4h2.355z"/>
3
+ </svg>
@@ -0,0 +1,6 @@
1
+ {% load wagtailcore_tags %}
2
+
3
+ <div {% if self.settings.custom_id %}id="{{self.settings.custom_id}}"{% endif %} class="block-html {{ self.settings.custom_css_class }}">
4
+ {% if self.event_calendar.name %}<h4>{{ self.event_calendar.name }}</h4>{% endif %}
5
+ {% include_block self.event_calendar.events %}
6
+ </div>
@@ -1,15 +1,26 @@
1
+ {% load static cjkcms_tags %}
1
2
  {% block block_render %}
2
- <div class="border {{self.settings.custom_css_class}}"
3
+ {% if not self.hide_after_end_date or self.start_date|is_in_future %}
4
+ <div class="border {{self.settings.custom_css_class}} mb-2 p-1 rounded position-relative hover-shadow"
3
5
  {% if self.settings.custom_id %} id="{{self.settings.custom_id}}"{% endif %}>
4
6
  <p class="mb-0">{{self.title}}</p>
5
- <footer class="blockquote-footer mt-1">
7
+ <footer class="mt-1 small">
8
+ <div class="align-items-center d-flex">
9
+ <object data="{% static 'cjkcms/images/icons/calendar-day.svg' %}" class="me-1 opacity-50"></object>
10
+ <strong>
6
11
  {{self.start_date}}
7
12
  {% if self.end_date %}
8
13
  - {{ self.end_date }}
9
14
  {% endif %}
15
+ </strong>
16
+ </div>
10
17
  {% if self.url %}
11
- | <a href="{{ self.url }}" target="_blank">{{ self.url }}</a>
18
+ <div class="align-items-center d-flex">
19
+ <object data="{% static 'cjkcms/images/icons/world.svg' %}" class="me-1 opacity-50"></object>
20
+ <a href="{{ self.url }}" target="_blank" class="stretched-link link-body-emphasis">{{ self.url }}</a>
21
+ </div>
12
22
  {% endif %}
13
23
  </footer>
14
24
  </div>
25
+ {% endif %}
15
26
  {% endblock %}
@@ -91,6 +91,11 @@
91
91
  </div>
92
92
  {% endif %}
93
93
  {% endblock %}
94
+
95
+ {% if settings.cjkcms.LayoutSettings.breadcrumbs %}
96
+ {% block breadcrumbs %}{% endblock %}
97
+ {% endif %}
98
+
94
99
  {% block content_pre_body %}{% endblock %}
95
100
 
96
101
  {% block content_body %}
@@ -24,7 +24,7 @@
24
24
  <form class="mt-5" action="{% url 'cjkcms_search' %}" method="GET">
25
25
  <div class="row">
26
26
  <div class="col-sm-9">
27
- {% bootstrap_form form size='large' layout='inline' %}
27
+ {% bootstrap_form form size='lg' layout='inline' %}
28
28
  </div>
29
29
  <div class="col-sm-3">
30
30
  <div class="form-group">
@@ -46,7 +46,7 @@
46
46
  {% for pt in pagetypes %}
47
47
  <li class="nav-item">
48
48
  {% query_update qs_nop 't' pt.content_type.model as qs_t %}
49
- <a class="nav-link {% if form.t.value == pt.content_type.model %}active{% endif %}" href="?{{qs_t.urlencode}}">{{pt.search_name_plural}}</a>
49
+ <a class="nav-link {% if form.t.value == pt.content_type.model %}active{% endif %}" href="?{{qs_t.urlencode}}">{{pt|get_plural_name_of_class}}</a>
50
50
  </li>
51
51
  {% endfor %}
52
52
  </ul>
@@ -8,6 +8,10 @@
8
8
  {% include 'cjkcms/snippets/actionbar.html' %}
9
9
  {% endblock %}
10
10
 
11
+ {% block breadcrumbs %}
12
+ {% include 'cjkcms/snippets/breadcrumbs.html' %}
13
+ {% endblock %}
14
+
11
15
  {% block footer %}
12
16
  {% include 'cjkcms/snippets/footer.html' %}
13
17
  {% endblock %}
@@ -0,0 +1,27 @@
1
+ {% load static wagtailcore_tags wagtailimages_tags cjkcms_tags wagtailsettings_tags %}
2
+ <!-- ========================= breadcrumbs-section start ========================= -->
3
+ {% if self.get_ancestors|length > 1 %}
4
+ <div class="container py-1">
5
+ <nav aria-label="breadcrumb">
6
+ <ol class="breadcrumb d-flex align-items-center">
7
+ {% block breadcrumb_title %}
8
+ {% for p in self.get_ancestors %}
9
+ {% if p.is_root == False %}
10
+ <li class="none">
11
+ <object type="image/svg+xml" data="{% static 'cjkcms/images/icons/'|add:settings.cjkcms.LayoutSettings.breadcrumb_icon|add:'.svg' %}"
12
+ class="opacity-75" style="margin-bottom:-2px;"></object>
13
+ <a href="{{ p.url }}">{{ p.title }}</a>
14
+ </li>
15
+
16
+ {% endif %}
17
+ {% endfor %}
18
+ <li class="breadcrumb-item active ms-1" aria-current="page">
19
+ <object type="image/svg+xml" data="{% static 'cjkcms/images/icons/'|add:settings.cjkcms.LayoutSettings.breadcrumb_icon|add:'.svg' %}"
20
+ class="opacity-75" style="margin-bottom:-2px;"></object>
21
+ {{ page.title }}</li>
22
+ {% endblock %}
23
+ </ol>
24
+ </nav>
25
+ </div>
26
+ {% endif %}
27
+ <!-- ========================= breadcrumbs-section end ========================= -->
@@ -1,9 +1,6 @@
1
- {% load cjkcms_tags i18n %}
1
+ {% load cjkcms_tags django_bootstrap5 i18n %}
2
2
  <form action="{% url 'cjkcms_search' %}" method="GET">
3
- {% load django_bootstrap5 %}
3
+ {% csrf_token %}
4
4
  {% get_searchform request as form %}
5
5
  {% bootstrap_form form layout='inline' %}
6
- <!-- div class="form-group">
7
- <button class="btn btn-outline-primary ml-2" type="submit">{% trans 'Search' %}</button>
8
- </div -->
9
6
  </form>
@@ -18,7 +18,7 @@ from cjkcms.blocks.base_blocks import CjkcmsAdvSettings
18
18
  from cjkcms.forms import SearchForm
19
19
  from cjkcms.models import Footer, Navbar
20
20
  from cjkcms.settings import cms_settings
21
- from datetime import datetime
21
+ from datetime import datetime, date
22
22
 
23
23
  from cjkcms.models.wagtailsettings_models import LayoutSettings
24
24
 
@@ -253,3 +253,26 @@ def get_plural_name_of_class(class_type):
253
253
  def define(val=None):
254
254
  """Allows defining a new variable in the template"""
255
255
  return val
256
+
257
+
258
+ @register.filter(name="is_in_future")
259
+ def is_in_future(the_date):
260
+ """Checks if given date or datetime is in future"""
261
+ if isinstance(the_date, datetime):
262
+ return the_date >= datetime.now()
263
+ elif isinstance(the_date, date):
264
+ # Convert date to datetime with time set to midnight
265
+ datetime_date = datetime(the_date.year, the_date.month, the_date.day)
266
+ return datetime_date >= datetime.now()
267
+ return False
268
+
269
+
270
+ @register.filter(name="is_in_past")
271
+ def is_in_past(the_date):
272
+ if isinstance(the_date, datetime):
273
+ return the_date < datetime.now()
274
+ elif isinstance(the_date, date):
275
+ # Convert date to datetime with time set to midnight
276
+ datetime_date = datetime(the_date.year, the_date.month, the_date.day)
277
+ return datetime_date < datetime.now()
278
+ return False
cjkcms/tests/manage.py ADDED
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env python
2
+ import os
3
+ import sys
4
+
5
+ if __name__ == "__main__":
6
+ os.environ.setdefault("DJANGO_SETTINGS_MODULE", "settings")
7
+
8
+ from django.core.management import execute_from_command_line
9
+
10
+ execute_from_command_line(sys.argv)
@@ -0,0 +1,88 @@
1
+ """
2
+ Settings for running tests
3
+ """
4
+ import os
5
+
6
+ BASE_DIR = os.path.abspath(os.path.dirname(__file__))
7
+ BASE_URL = "http://localhost"
8
+
9
+ DEBUG = True
10
+ SECRET_KEY = "mysecretkey4testing"
11
+ ALLOWED_HOSTS = ["*"]
12
+ INSTALLED_APPS = [
13
+ "cjkcms.tests.testapp.apps.TestAppConfig", # replace `myapp` with your app name
14
+ # --- wagtail-cjkcms + requirements #
15
+ "cjkcms",
16
+ "wagtailseo",
17
+ "wagtailcache",
18
+ "wagtail.contrib.table_block",
19
+ "wagtail.contrib.settings",
20
+ "wagtail_color_panel",
21
+ "django_bootstrap5",
22
+ # --- end-wagtail-cjkcms #
23
+ "wagtail.contrib.forms",
24
+ "wagtail.contrib.redirects",
25
+ "wagtail.contrib.sitemaps",
26
+ "django.contrib.sitemaps",
27
+ "wagtail.embeds",
28
+ "wagtail.sites",
29
+ "wagtail.users",
30
+ "wagtail.snippets",
31
+ "wagtail.documents",
32
+ "wagtail.images",
33
+ "wagtail.search",
34
+ "wagtail.admin",
35
+ "wagtail",
36
+ "taggit",
37
+ "modelcluster",
38
+ "django.contrib.admin",
39
+ "django.contrib.auth",
40
+ "django.contrib.contenttypes",
41
+ "django.contrib.sessions",
42
+ "django.contrib.messages",
43
+ "django.contrib.staticfiles",
44
+ ]
45
+ MIDDLEWARE = [
46
+ "django.contrib.sessions.middleware.SessionMiddleware",
47
+ "django.middleware.common.CommonMiddleware",
48
+ "django.middleware.csrf.CsrfViewMiddleware",
49
+ "django.contrib.auth.middleware.AuthenticationMiddleware",
50
+ "django.contrib.messages.middleware.MessageMiddleware",
51
+ "django.middleware.clickjacking.XFrameOptionsMiddleware",
52
+ "django.middleware.security.SecurityMiddleware",
53
+ "wagtail.contrib.redirects.middleware.RedirectMiddleware",
54
+ ]
55
+ ROOT_URLCONF = "cjkcms.tests.urls"
56
+ TEMPLATES = [
57
+ {
58
+ "BACKEND": "django.template.backends.django.DjangoTemplates",
59
+ "DIRS": [
60
+ os.path.join(BASE_DIR, "templates"),
61
+ ],
62
+ "APP_DIRS": True,
63
+ "OPTIONS": {
64
+ "context_processors": [
65
+ "django.template.context_processors.debug",
66
+ "django.template.context_processors.request",
67
+ "django.contrib.auth.context_processors.auth",
68
+ "django.contrib.messages.context_processors.messages",
69
+ ],
70
+ },
71
+ },
72
+ ]
73
+ WAGTAILADMIN_BASE_URL = BASE_URL
74
+ STATIC_ROOT = os.path.join(BASE_DIR, "static")
75
+ STATIC_URL = "/static/"
76
+ MEDIA_ROOT = os.path.join(BASE_DIR, "media")
77
+ MEDIA_URL = "/media/"
78
+ DATABASES = {
79
+ "default": {
80
+ "ENGINE": "django.db.backends.sqlite3",
81
+ "NAME": ":memory:",
82
+ # "NAME": os.path.join(BASE_DIR, "db.sqlite3"),
83
+ }
84
+ }
85
+ LANGUAGE_CODE = "en-us"
86
+ TIME_ZONE = "UTC"
87
+ USE_I18N = True
88
+ USE_TZ = True