From afca218a304037f5ca62cf866d425b982c878a39 Mon Sep 17 00:00:00 2001 From: Thijs Kramer Date: Fri, 4 May 2018 14:24:52 +0200 Subject: [PATCH 1/8] add optional field to Site model to mention which company the site was co-developed with --- .../0011_add_cooperation_field_to_site.py | 27 +++++++++++++++++++ core/models.py | 8 ++++++ 2 files changed, 35 insertions(+) create mode 100644 core/migrations/0011_add_cooperation_field_to_site.py diff --git a/core/migrations/0011_add_cooperation_field_to_site.py b/core/migrations/0011_add_cooperation_field_to_site.py new file mode 100644 index 0000000..89b10cd --- /dev/null +++ b/core/migrations/0011_add_cooperation_field_to_site.py @@ -0,0 +1,27 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.7 on 2018-05-04 09:19 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('core', '0010_wagtailsitepage_screenshot'), + ] + + operations = [ + migrations.AddField( + model_name='wagtailsitepage', + name='in_cooperation_with', + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name='+', + to='core.WagtailCompanyPage' + ), + ), + ] diff --git a/core/models.py b/core/models.py index c8e1e96..0de2fe0 100644 --- a/core/models.py +++ b/core/models.py @@ -405,6 +405,14 @@ class WagtailSitePage(WagtailPage): help_text='The URL of your site, something like "https://www.springload.co.nz"', ) + in_cooperation_with = models.ForeignKey( + 'core.WagtailCompanyPage', + null=True, + blank=True, + on_delete=models.SET_NULL, + related_name='+', + ) + search_fields = Page.search_fields + [ index.SearchField('site_url'), index.SearchField('body_text') From cb266a56c1905f0cfb27c2a2188d95dc63df1ad9 Mon Sep 17 00:00:00 2001 From: Thijs Kramer Date: Fri, 4 May 2018 14:25:53 +0200 Subject: [PATCH 2/8] add fieldpanel for in_cooperation_with field --- core/panels.py | 1 + 1 file changed, 1 insertion(+) diff --git a/core/panels.py b/core/panels.py index a9364d8..d3a4208 100644 --- a/core/panels.py +++ b/core/panels.py @@ -28,6 +28,7 @@ ImageChooserPanel('site_screenshot'), FieldPanel('body', classname="full"), FieldPanel('tags'), + FieldPanel('in_cooperation_with'), ] WAGTAIL_COMPANY_PAGE_CONTENT_PANELS = HOME_PAGE_CONTENT_PANELS + [ From a93675232d72d3ed4cb69cd77df35ebe715b3db8 Mon Sep 17 00:00:00 2001 From: Thijs Kramer Date: Fri, 4 May 2018 14:27:50 +0200 Subject: [PATCH 3/8] add 'in cooperation with' suffix if applicable --- core/templates/core/includes/sites.html | 12 +++++++++++- core/templates/core/wagtail_site_page.html | 6 ++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/core/templates/core/includes/sites.html b/core/templates/core/includes/sites.html index 98a9ba3..6798126 100644 --- a/core/templates/core/includes/sites.html +++ b/core/templates/core/includes/sites.html @@ -29,7 +29,17 @@

{{ page.title }}

- {{ page.parent.title|default:"A Wagtail developer" }} + + {{ page.parent.title|default:"A Wagtail developer" }} + + {% if page.in_cooperation_with %} + + — in cooperation with + + {{ page.in_cooperation_with.title }} + + + {% endif %}

{% endfor %} diff --git a/core/templates/core/wagtail_site_page.html b/core/templates/core/wagtail_site_page.html index fa36c2d..ca8d696 100644 --- a/core/templates/core/wagtail_site_page.html +++ b/core/templates/core/wagtail_site_page.html @@ -25,6 +25,12 @@

{{ self.title }}

Made by {{ self.parent.title }} + {% if self.in_cooperation_with %} + — in cooperation with + {{ self.in_cooperation_with.title }} + + + {% endif %}

{{ self.body|richtext }} From 9874cef6a89c3db2e9f4100b8710528627c9f8dc Mon Sep 17 00:00:00 2001 From: Thijs Kramer Date: Fri, 4 May 2018 14:28:22 +0200 Subject: [PATCH 4/8] decrease font size for 'in cooperation with' suffix --- core/frontend/sass/modules/_cards.scss | 3 +++ 1 file changed, 3 insertions(+) diff --git a/core/frontend/sass/modules/_cards.scss b/core/frontend/sass/modules/_cards.scss index e102471..fb265f5 100644 --- a/core/frontend/sass/modules/_cards.scss +++ b/core/frontend/sass/modules/_cards.scss @@ -76,6 +76,9 @@ .project-author { color: $color-light-text; + .project-featuring { + font-size: 0.875em; + } } .project-author--block { From 082c06314f7ca69e3e824ba5313d8f734436a7d5 Mon Sep 17 00:00:00 2001 From: Thijs Kramer Date: Fri, 4 May 2018 14:30:28 +0200 Subject: [PATCH 5/8] include the 'in cooperation with' pages in the queryset --- core/models.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/core/models.py b/core/models.py index 0de2fe0..6f543de 100644 --- a/core/models.py +++ b/core/models.py @@ -346,7 +346,9 @@ def children(self): def get_context(self, request, *args, **kwargs): # Get pages - pages = self.children() + pages = WagtailSitePage.objects.filter( + Q(path__startswith=self.path) | Q(in_cooperation_with=self) + ).distinct() # Pagination page = request.GET.get('page') paginator = Paginator(pages, 12) # Show 12 pages per page From 691544d8a774a872c3f401e958c567dc4135058c Mon Sep 17 00:00:00 2001 From: Thijs Kramer Date: Fri, 4 May 2018 14:30:43 +0200 Subject: [PATCH 6/8] fix isort linting errors --- core/models.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) mode change 100644 => 100755 core/models.py diff --git a/core/models.py b/core/models.py old mode 100644 new mode 100755 index 6f543de..7609c04 --- a/core/models.py +++ b/core/models.py @@ -3,10 +3,13 @@ from operator import itemgetter from bs4 import BeautifulSoup +from core import panels +from core.forms import SubmitFormBuilder +from core.utilities import has_recaptcha, validate_only_one_instance from django.core.exceptions import ObjectDoesNotExist from django.core.paginator import EmptyPage, PageNotAnInteger, Paginator from django.db import models -from django.db.models import Count +from django.db.models import Count, Q from django.utils.encoding import python_2_unicode_compatible from django.utils.html import mark_safe from modelcluster.fields import ParentalKey @@ -18,10 +21,6 @@ from wagtail.wagtailsearch import index from wagtailcaptcha.models import WagtailCaptchaEmailForm -from core import panels -from core.forms import SubmitFormBuilder -from core.utilities import has_recaptcha, validate_only_one_instance - class IndexPage(models.Model): """ From fb59689e8356a5ddc469294a982b6f61035dccbc Mon Sep 17 00:00:00 2001 From: Loic Teixeira Date: Mon, 25 Jun 2018 14:37:46 +1000 Subject: [PATCH 7/8] Use the sites ordering when querying children --- core/models.py | 50 +++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 41 insertions(+), 9 deletions(-) diff --git a/core/models.py b/core/models.py index 7609c04..c84f785 100755 --- a/core/models.py +++ b/core/models.py @@ -1,11 +1,9 @@ import os import re +from itertools import chain from operator import itemgetter from bs4 import BeautifulSoup -from core import panels -from core.forms import SubmitFormBuilder -from core.utilities import has_recaptcha, validate_only_one_instance from django.core.exceptions import ObjectDoesNotExist from django.core.paginator import EmptyPage, PageNotAnInteger, Paginator from django.db import models @@ -21,6 +19,10 @@ from wagtail.wagtailsearch import index from wagtailcaptcha.models import WagtailCaptchaEmailForm +from core import panels +from core.forms import SubmitFormBuilder +from core.utilities import has_recaptcha, validate_only_one_instance + class IndexPage(models.Model): """ @@ -243,13 +245,15 @@ class WagtailCompanyPage(WagtailPage): parent_types = ['core.HomePage'] subpage_types = ['core.WagtailSitePage'] + SITES_ORDERING_ALPHABETICAL = 'alphabetical' SITES_ORDERING_CREATED = 'created' + SITES_ORDERING_PATH = 'path' SITES_ORDERING = { - 'path': { + SITES_ORDERING_PATH: { 'name': 'Path (i.e. manual)', 'ordering': ['-path'], }, - 'alphabetical': { + SITES_ORDERING_ALPHABETICAL: { 'name': 'Alphabetical', 'ordering': ['title'], }, @@ -341,13 +345,41 @@ def og_image(self): def children(self): ordering = self.SITES_ORDERING[self.sites_ordering]['ordering'] - return WagtailSitePage.objects.live().descendant_of(self).order_by(*ordering) + + # When ordering by `path`, the collaborations would either all be listed first or last + # depending on whether the collaborator(s) page(s) was created before or after this page. + # Adding an overwrite here so collaborations always appear last. + if self.sites_ordering == self.SITES_ORDERING_PATH: + own_site_pages = WagtailSitePage.objects\ + .live()\ + .descendant_of(self)\ + .order_by(*ordering) + + collab_site_pages = WagtailSitePage.objects\ + .live()\ + .filter(in_cooperation_with=self)\ + .order_by(*ordering) + + # Using `itertools.chain` to chain both querysets + # as joining them with `|` or `union` does not produce the expected result. + site_pages = chain(own_site_pages, collab_site_pages) + + # When ordering alphabetically or by creation date, + # own sites and collaboration sites will be sorted together. + else: + site_pages = WagtailSitePage.objects\ + .live()\ + .filter(Q(path__startswith=self.path) | Q(in_cooperation_with=self))\ + .order_by(*ordering) + + # At this point, `site_pages` might be an iterator or a QuerySet. + # It's not ideal to cast it to a list but at least it's consistent. + return list(site_pages) def get_context(self, request, *args, **kwargs): # Get pages - pages = WagtailSitePage.objects.filter( - Q(path__startswith=self.path) | Q(in_cooperation_with=self) - ).distinct() + pages = self.children() + # Pagination page = request.GET.get('page') paginator = Paginator(pages, 12) # Show 12 pages per page From 7cd3b726fb8349f6bdbff539be6395dbb0084156 Mon Sep 17 00:00:00 2001 From: Loic Teixeira Date: Mon, 25 Jun 2018 14:55:08 +1000 Subject: [PATCH 8/8] Keep children as a queryset --- core/models.py | 37 +++++++++++++------------------------ 1 file changed, 13 insertions(+), 24 deletions(-) diff --git a/core/models.py b/core/models.py index c84f785..60ef492 100755 --- a/core/models.py +++ b/core/models.py @@ -1,13 +1,12 @@ import os import re -from itertools import chain from operator import itemgetter from bs4 import BeautifulSoup from django.core.exceptions import ObjectDoesNotExist from django.core.paginator import EmptyPage, PageNotAnInteger, Paginator from django.db import models -from django.db.models import Count, Q +from django.db.models import Case, Count, Q, Value, When from django.utils.encoding import python_2_unicode_compatible from django.utils.html import mark_safe from modelcluster.fields import ParentalKey @@ -344,37 +343,27 @@ def og_image(self): return image def children(self): - ordering = self.SITES_ORDERING[self.sites_ordering]['ordering'] + user_ordering = self.SITES_ORDERING[self.sites_ordering]['ordering'] + pages = WagtailSitePage.objects.live().filter(Q(path__startswith=self.path) | Q(in_cooperation_with=self)) # When ordering by `path`, the collaborations would either all be listed first or last # depending on whether the collaborator(s) page(s) was created before or after this page. # Adding an overwrite here so collaborations always appear last. if self.sites_ordering == self.SITES_ORDERING_PATH: - own_site_pages = WagtailSitePage.objects\ - .live()\ - .descendant_of(self)\ - .order_by(*ordering) - - collab_site_pages = WagtailSitePage.objects\ - .live()\ - .filter(in_cooperation_with=self)\ - .order_by(*ordering) - - # Using `itertools.chain` to chain both querysets - # as joining them with `|` or `union` does not produce the expected result. - site_pages = chain(own_site_pages, collab_site_pages) + pages = pages.annotate( + is_own=Case( + When(path__startswith=self.path, then=Value(True)), + default_value=Value(False), + output_field=models.BooleanField(), + ) + ).order_by('is_own', *user_ordering) # When ordering alphabetically or by creation date, # own sites and collaboration sites will be sorted together. else: - site_pages = WagtailSitePage.objects\ - .live()\ - .filter(Q(path__startswith=self.path) | Q(in_cooperation_with=self))\ - .order_by(*ordering) - - # At this point, `site_pages` might be an iterator or a QuerySet. - # It's not ideal to cast it to a list but at least it's consistent. - return list(site_pages) + pages = pages.order_by(*user_ordering) + + return pages def get_context(self, request, *args, **kwargs): # Get pages