From 53c3e663aafc20180d6aa68a009caa066f2616d0 Mon Sep 17 00:00:00 2001 From: Edward Williams Date: Mon, 1 Nov 2021 18:32:06 +1300 Subject: [PATCH 01/19] Adds fully customizable main menu - New models for menu items and sub menu items - Old secondary menu models removed - Model Admin for editing and adding menu items and links - tests for menu - tests for blog page next and previous links --- .../migrations/0003_auto_20211101_0113.py | 24 +++ ietf/blog/tests.py | 75 ++++--- ietf/context_processors.py | 12 +- .../migrations/0004_auto_20211101_0113.py | 24 +++ .../migrations/0003_auto_20211101_0113.py | 24 +++ ietf/settings/base.py | 2 + .../migrations/0003_auto_20211101_0113.py | 39 ++++ ietf/templates/includes/header.html | 46 +---- .../migrations/0003_auto_20211101_0113.py | 29 +++ .../migrations/0002_auto_20211101_0113.py | 57 ++++++ ietf/utils/models.py | 188 +++++++++--------- ietf/utils/tests.py | 79 ++++++++ ietf/utils/wagtail_hooks.py | 32 ++- requirements.txt | 1 + 14 files changed, 450 insertions(+), 182 deletions(-) create mode 100644 ietf/blog/migrations/0003_auto_20211101_0113.py create mode 100644 ietf/events/migrations/0004_auto_20211101_0113.py create mode 100644 ietf/iesg_statement/migrations/0003_auto_20211101_0113.py create mode 100644 ietf/standard/migrations/0003_auto_20211101_0113.py create mode 100644 ietf/topics/migrations/0003_auto_20211101_0113.py create mode 100644 ietf/utils/migrations/0002_auto_20211101_0113.py create mode 100644 ietf/utils/tests.py diff --git a/ietf/blog/migrations/0003_auto_20211101_0113.py b/ietf/blog/migrations/0003_auto_20211101_0113.py new file mode 100644 index 00000000..bf92f984 --- /dev/null +++ b/ietf/blog/migrations/0003_auto_20211101_0113.py @@ -0,0 +1,24 @@ +# Generated by Django 2.2.19 on 2021-11-01 01:13 + +from django.db import migrations +import wagtail.contrib.table_block.blocks +import wagtail.core.blocks +import wagtail.core.fields +import wagtail.embeds.blocks +import wagtail.images.blocks +import wagtailmarkdown.blocks + + +class Migration(migrations.Migration): + + dependencies = [ + ('blog', '0002_auto_20210325_0442'), + ] + + operations = [ + migrations.AlterField( + model_name='blogpage', + name='body', + field=wagtail.core.fields.StreamField([('heading', wagtail.core.blocks.CharBlock(icon='title')), ('paragraph', wagtail.core.blocks.RichTextBlock(icon='pilcrow')), ('image', wagtail.images.blocks.ImageChooserBlock(icon='image', template='includes/imageblock.html')), ('markdown', wagtailmarkdown.blocks.MarkdownBlock(icon='code')), ('embed', wagtail.embeds.blocks.EmbedBlock(icon='code')), ('raw_html', wagtail.core.blocks.RawHTMLBlock(icon='placeholder')), ('table', wagtail.contrib.table_block.blocks.TableBlock(table_options={'renderer': 'html'}, template='includes/tableblock.html'))]), + ), + ] diff --git a/ietf/blog/tests.py b/ietf/blog/tests.py index 1ac49235..f01437f4 100644 --- a/ietf/blog/tests.py +++ b/ietf/blog/tests.py @@ -1,14 +1,14 @@ from django.test import TestCase +from datetime import datetime, timedelta from .models import BlogPage, BlogIndexPage from ..home.models import HomePage from wagtail.core.models import Page, Site -class BlogTests(TestCase): - - def test_blog(self): +class BlogTests(TestCase): + def setUp(self): root = Page.get_first_root_node() home = HomePage( @@ -31,53 +31,72 @@ def test_blog(self): site_name='testingsitename', ) - blogindex = BlogIndexPage( + self.blog_index = BlogIndexPage( slug = 'blog', title = 'blog index title', ) - home.add_child(instance = blogindex) + home.add_child(instance = self.blog_index) - nextblog = BlogPage( - slug = 'nextpost', - title = 'next title', - introduction = 'next introduction', - body = 'next body' - ) - blogindex.add_child(instance = nextblog) + now = datetime.utcnow() - otherblog = BlogPage( + self.otherblog = BlogPage( slug = 'otherpost', title = 'other title', introduction = 'other introduction', - body = 'other body' + body = 'other body', + date_published = (now - timedelta(minutes = 10)) ) - blogindex.add_child(instance = otherblog) + self.blog_index.add_child(instance = self.otherblog) + self.otherblog.save - prevblog = BlogPage( + self.prevblog = BlogPage( slug = 'prevpost', title = 'prev title', introduction = 'prev introduction', - body = 'prev body' + body = 'prev body', + date_published = (now - timedelta(minutes = 5)) ) - blogindex.add_child(instance = prevblog) + self.blog_index.add_child(instance = self.prevblog) + self.prevblog.save() - blog = BlogPage( + + self.blog = BlogPage( slug = 'blogpost', title = 'blog title', introduction = 'blog introduction', - body = 'blog body' + body = 'blog body', + first_published_at = (now + timedelta(minutes=1)) ) - blogindex.add_child(instance = blog) + self.blog_index.add_child(instance = self.blog) + self.blog.save() - r = self.client.get(path=blogindex.url) + self.nextblog = BlogPage( + slug = 'nextpost', + title = 'next title', + introduction = 'next introduction', + body = 'next body', + first_published_at = (now + timedelta(minutes=5)) + ) + self.blog_index.add_child(instance = self.nextblog) + self.nextblog.save() + + def test_blog(self): + r = self.client.get(path=self.blog_index.url) self.assertEqual(r.status_code, 200) - r = self.client.get(path=blog.url) + r = self.client.get(path=self.blog.url) self.assertEqual(r.status_code, 200) - self.assertIn(blog.title.encode(), r.content) - self.assertIn(blog.introduction.encode(), r.content) + self.assertIn(self.blog.title.encode(), r.content) + self.assertIn(self.blog.introduction.encode(), r.content) # self.assertIn(blog.body.raw_text.encode(), r.content) - self.assertIn(('href="%s"' % nextblog.url).encode(), r.content) - self.assertIn(('href="%s"' % prevblog.url).encode(), r.content) - self.assertIn(('href="%s"' % otherblog.url).encode(), r.content) + self.assertIn(('href="%s"' % self.nextblog.url).encode(), r.content) + self.assertIn(('href="%s"' % self.prevblog.url).encode(), r.content) + self.assertIn(('href="%s"' % self.otherblog.url).encode(), r.content) + + def test_previous_next_links_correct(self): + self.assertTrue(self.prevblog.date < self.blog.date) + self.assertTrue(self.nextblog.date > self.blog.date) + blog = BlogPage.objects.get(pk=self.blog.pk) + self.assertEquals(self.prevblog, blog.previous) + self.assertEquals(self.nextblog, blog.next) diff --git a/ietf/context_processors.py b/ietf/context_processors.py index f36375e0..ee187842 100644 --- a/ietf/context_processors.py +++ b/ietf/context_processors.py @@ -2,28 +2,20 @@ from ietf.blog.models import BlogIndexPage from ietf.home.models import HomePage +from ietf.utils.models import MenuItem def home_page(): return HomePage.objects.filter(depth=2).first() - -def children(item): - return item and item.get_children().live().in_menu() - - def menu(): - items = children(home_page()) - if items: - for item in items: - item.subitems = children(item) + items = MenuItem.objects.order_by('sort_order').all() return items def global_pages(request): return { 'HOME': home_page(), - 'BLOG_INDEX': BlogIndexPage.objects.first(), 'MENU': menu(), 'BASE_URL': getattr(settings, 'BASE_URL', ""), 'DEBUG': getattr(settings, 'DEBUG', ""), diff --git a/ietf/events/migrations/0004_auto_20211101_0113.py b/ietf/events/migrations/0004_auto_20211101_0113.py new file mode 100644 index 00000000..4f4f8b2e --- /dev/null +++ b/ietf/events/migrations/0004_auto_20211101_0113.py @@ -0,0 +1,24 @@ +# Generated by Django 2.2.19 on 2021-11-01 01:13 + +from django.db import migrations +import wagtail.contrib.table_block.blocks +import wagtail.core.blocks +import wagtail.core.fields +import wagtail.embeds.blocks +import wagtail.images.blocks +import wagtailmarkdown.blocks + + +class Migration(migrations.Migration): + + dependencies = [ + ('events', '0003_auto_20210704_2343'), + ] + + operations = [ + migrations.AlterField( + model_name='eventpage', + name='body', + field=wagtail.core.fields.StreamField([('heading', wagtail.core.blocks.CharBlock(icon='title')), ('paragraph', wagtail.core.blocks.RichTextBlock(icon='pilcrow')), ('image', wagtail.images.blocks.ImageChooserBlock(icon='image', template='includes/imageblock.html')), ('markdown', wagtailmarkdown.blocks.MarkdownBlock(icon='code')), ('embed', wagtail.embeds.blocks.EmbedBlock(icon='code')), ('raw_html', wagtail.core.blocks.RawHTMLBlock(icon='placeholder')), ('table', wagtail.contrib.table_block.blocks.TableBlock(table_options={'renderer': 'html'}, template='includes/tableblock.html'))]), + ), + ] diff --git a/ietf/iesg_statement/migrations/0003_auto_20211101_0113.py b/ietf/iesg_statement/migrations/0003_auto_20211101_0113.py new file mode 100644 index 00000000..c4ab6110 --- /dev/null +++ b/ietf/iesg_statement/migrations/0003_auto_20211101_0113.py @@ -0,0 +1,24 @@ +# Generated by Django 2.2.19 on 2021-11-01 01:13 + +from django.db import migrations +import wagtail.contrib.table_block.blocks +import wagtail.core.blocks +import wagtail.core.fields +import wagtail.embeds.blocks +import wagtail.images.blocks +import wagtailmarkdown.blocks + + +class Migration(migrations.Migration): + + dependencies = [ + ('iesg_statement', '0002_auto_20210325_0442'), + ] + + operations = [ + migrations.AlterField( + model_name='iesgstatementpage', + name='body', + field=wagtail.core.fields.StreamField([('heading', wagtail.core.blocks.CharBlock(icon='title')), ('paragraph', wagtail.core.blocks.RichTextBlock(icon='pilcrow')), ('image', wagtail.images.blocks.ImageChooserBlock(icon='image', template='includes/imageblock.html')), ('markdown', wagtailmarkdown.blocks.MarkdownBlock(icon='code')), ('embed', wagtail.embeds.blocks.EmbedBlock(icon='code')), ('raw_html', wagtail.core.blocks.RawHTMLBlock(icon='placeholder')), ('table', wagtail.contrib.table_block.blocks.TableBlock(table_options={'renderer': 'html'}, template='includes/tableblock.html'))]), + ), + ] diff --git a/ietf/settings/base.py b/ietf/settings/base.py index bd8f0dfb..3dd4d715 100644 --- a/ietf/settings/base.py +++ b/ietf/settings/base.py @@ -59,6 +59,7 @@ "wagtail.contrib.table_block", "wagtail.contrib.postgres_search", "wagtail.contrib.routable_page", + "wagtail.contrib.modeladmin", "modelcluster", "compressor", "taggit", @@ -72,6 +73,7 @@ "mod_wsgi.server", "analytical", "wagtailmarkdown", + "wagtailorderable", ) MIDDLEWARE = [ diff --git a/ietf/standard/migrations/0003_auto_20211101_0113.py b/ietf/standard/migrations/0003_auto_20211101_0113.py new file mode 100644 index 00000000..0d5d9876 --- /dev/null +++ b/ietf/standard/migrations/0003_auto_20211101_0113.py @@ -0,0 +1,39 @@ +# Generated by Django 2.2.19 on 2021-11-01 01:13 + +from django.db import migrations +import wagtail.contrib.table_block.blocks +import wagtail.core.blocks +import wagtail.core.fields +import wagtail.embeds.blocks +import wagtail.images.blocks +import wagtailmarkdown.blocks + + +class Migration(migrations.Migration): + + dependencies = [ + ('standard', '0002_auto_20210325_0442'), + ] + + operations = [ + migrations.AlterField( + model_name='standardindexpage', + name='in_depth', + field=wagtail.core.fields.StreamField([('heading', wagtail.core.blocks.CharBlock(icon='title')), ('paragraph', wagtail.core.blocks.RichTextBlock(icon='pilcrow')), ('image', wagtail.images.blocks.ImageChooserBlock(icon='image', template='includes/imageblock.html')), ('markdown', wagtailmarkdown.blocks.MarkdownBlock(icon='code')), ('embed', wagtail.embeds.blocks.EmbedBlock(icon='code')), ('raw_html', wagtail.core.blocks.RawHTMLBlock(icon='placeholder')), ('table', wagtail.contrib.table_block.blocks.TableBlock(table_options={'renderer': 'html'}, template='includes/tableblock.html'))], blank=True), + ), + migrations.AlterField( + model_name='standardindexpage', + name='key_info', + field=wagtail.core.fields.StreamField([('heading', wagtail.core.blocks.CharBlock(icon='title')), ('paragraph', wagtail.core.blocks.RichTextBlock(icon='pilcrow')), ('image', wagtail.images.blocks.ImageChooserBlock(icon='image', template='includes/imageblock.html')), ('markdown', wagtailmarkdown.blocks.MarkdownBlock(icon='code')), ('embed', wagtail.embeds.blocks.EmbedBlock(icon='code')), ('raw_html', wagtail.core.blocks.RawHTMLBlock(icon='placeholder')), ('table', wagtail.contrib.table_block.blocks.TableBlock(table_options={'renderer': 'html'}, template='includes/tableblock.html'))], blank=True), + ), + migrations.AlterField( + model_name='standardpage', + name='in_depth', + field=wagtail.core.fields.StreamField([('heading', wagtail.core.blocks.CharBlock(icon='title')), ('paragraph', wagtail.core.blocks.RichTextBlock(icon='pilcrow')), ('image', wagtail.images.blocks.ImageChooserBlock(icon='image', template='includes/imageblock.html')), ('markdown', wagtailmarkdown.blocks.MarkdownBlock(icon='code')), ('embed', wagtail.embeds.blocks.EmbedBlock(icon='code')), ('raw_html', wagtail.core.blocks.RawHTMLBlock(icon='placeholder')), ('table', wagtail.contrib.table_block.blocks.TableBlock(table_options={'renderer': 'html'}, template='includes/tableblock.html'))], blank=True), + ), + migrations.AlterField( + model_name='standardpage', + name='key_info', + field=wagtail.core.fields.StreamField([('heading', wagtail.core.blocks.CharBlock(icon='title')), ('paragraph', wagtail.core.blocks.RichTextBlock(icon='pilcrow')), ('image', wagtail.images.blocks.ImageChooserBlock(icon='image', template='includes/imageblock.html')), ('markdown', wagtailmarkdown.blocks.MarkdownBlock(icon='code')), ('embed', wagtail.embeds.blocks.EmbedBlock(icon='code')), ('raw_html', wagtail.core.blocks.RawHTMLBlock(icon='placeholder')), ('table', wagtail.contrib.table_block.blocks.TableBlock(table_options={'renderer': 'html'}, template='includes/tableblock.html'))], blank=True), + ), + ] diff --git a/ietf/templates/includes/header.html b/ietf/templates/includes/header.html index 05e7f7e1..16332ef5 100644 --- a/ietf/templates/includes/header.html +++ b/ietf/templates/includes/header.html @@ -51,12 +51,12 @@ {% for item in MENU %} - {% endfor %} - - -