Skip to content

Commit

Permalink
Merge pull request #1297 from devinit/feature/update_focus_area_page_…
Browse files Browse the repository at this point in the history
…type

Feature | Update Focus Area Page Type
  • Loading branch information
edwinmp authored Mar 6, 2023
2 parents c5c5839 + 80116df commit a574a4b
Show file tree
Hide file tree
Showing 7 changed files with 241 additions and 18 deletions.
59 changes: 59 additions & 0 deletions di_website/project/migrations/0048_auto_20230302_0159.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# Generated by Django 3.2.16 on 2023-03-02 01:59

from django.db import migrations, models
import django.db.models.deletion
import django.utils.timezone
import modelcluster.contrib.taggit
import modelcluster.fields
import wagtail.blocks
import wagtail.fields


class Migration(migrations.Migration):

dependencies = [
('taggit', '0005_auto_20220424_2025'),
('project', '0047_auto_20221012_1214'),
]

operations = [
migrations.AlterModelOptions(
name='focusareaspagelink',
options={},
),
migrations.RemoveField(
model_name='focusareaspagelink',
name='sort_order',
),
migrations.AddField(
model_name='focusareaspagelink',
name='related_page_handler',
field=models.CharField(choices=[('manual', 'Manual'), ('topic', 'Topic')], default='manual', max_length=253, verbose_name='Show By'),
),
migrations.AddField(
model_name='projectpage',
name='published_date',
field=models.DateTimeField(blank=True, default=django.utils.timezone.now, help_text='This date will be used for display and ordering'),
),
migrations.AlterField(
model_name='focusareaspagelink',
name='projects',
field=wagtail.fields.StreamField([('page', wagtail.blocks.PageChooserBlock(required=True))], blank=True, null=True, use_json_field=True, verbose_name='Projects'),
),
migrations.CreateModel(
name='FocusAreasPageLinkTopic',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('content_object', modelcluster.fields.ParentalKey(blank=True, on_delete=django.db.models.deletion.CASCADE, related_name='focus_areas_page_link_topics', to='project.focusareaspagelink')),
('tag', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='project_focusareaspagelinktopic_items', to='taggit.tag')),
],
options={
'abstract': False,
},
),
migrations.AddField(
model_name='focusareaspagelink',
name='topics',
field=modelcluster.contrib.taggit.ClusterTaggableManager(blank=True, help_text='A comma-separated list of tags.', through='project.FocusAreasPageLinkTopic', to='taggit.Tag', verbose_name='Topics'),
),
]
22 changes: 22 additions & 0 deletions di_website/project/migrations/0049_auto_20230302_0200.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Generated by Django 3.2.16 on 2023-03-02 02:00

from django.db import migrations


def add_published_date(apps, schema_editor):
project = apps.get_model('project', 'ProjectPage')
for project_page in project.objects.all():
if project_page.first_published_at is not None:
project_page.published_date = project_page.first_published_at
project_page.save()


class Migration(migrations.Migration):

dependencies = [
('project', '0048_auto_20230302_0159'),
]

operations = [
migrations.RunPython(add_published_date),
]
33 changes: 33 additions & 0 deletions di_website/project/migrations/0050_auto_20230302_0224.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Generated by Django 3.2.16 on 2023-03-02 02:24

from django.db import migrations, models
import django.db.models.deletion
import modelcluster.contrib.taggit
import modelcluster.fields


class Migration(migrations.Migration):

dependencies = [
('taggit', '0005_auto_20220424_2025'),
('project', '0049_auto_20230302_0200'),
]

operations = [
migrations.CreateModel(
name='ProjectPageTopic',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('content_object', modelcluster.fields.ParentalKey(blank=True, on_delete=django.db.models.deletion.CASCADE, related_name='project_page_topics', to='project.projectpage')),
('tag', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='project_projectpagetopic_items', to='taggit.tag')),
],
options={
'abstract': False,
},
),
migrations.AddField(
model_name='projectpage',
name='topics',
field=modelcluster.contrib.taggit.ClusterTaggableManager(blank=True, help_text='A comma-separated list of tags.', through='project.ProjectPageTopic', to='taggit.Tag', verbose_name='Topics'),
),
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 3.2.16 on 2023-03-02 08:09

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('project', '0050_auto_20230302_0224'),
]

operations = [
migrations.AddField(
model_name='focusareaspagelink',
name='related_page_section_title',
field=models.CharField(blank=True, default='Key Projects and Publications', max_length=255, verbose_name='Section Title'),
),
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 3.2.15 on 2023-03-06 06:10

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('project', '0051_focusareaspagelink_related_page_section_title'),
]

operations = [
migrations.AlterField(
model_name='focusareaspagelink',
name='related_page_section_title',
field=models.CharField(blank=True, default='Key projects and publications', max_length=255, verbose_name='Section Title'),
),
]
73 changes: 65 additions & 8 deletions di_website/project/models.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
from django.db import models

from modelcluster.fields import ParentalKey
from modelcluster.contrib.taggit import ClusterTaggableManager
from taggit.models import TaggedItemBase
from modelcluster.models import ClusterableModel

from wagtail.admin.panels import (
InlinePanel,
Expand All @@ -15,21 +18,43 @@
from di_website.common.base import hero_panels, get_related_pages
from di_website.common.mixins import HeroMixin, OtherPageMixin, TypesetBodyMixin
from di_website.common.constants import MAX_RELATED_LINKS, RICHTEXT_FEATURES_NO_FOOTNOTES
from di_website.publications.models import AudioVisualMedia, LegacyPublicationPage, PublicationPage, ShortPublicationPage
from di_website.publications.mixins import PublishedDateMixin
from di_website.publications.utils import PublishedDatePanel
from di_website.blog.models import BlogArticlePage
from di_website.news.models import NewsStoryPage


class ProjectPage(TypesetBodyMixin, HeroMixin, Page):
RELATED_CHOICES = (
('manual', 'Manual'),
('topic', 'Topic')
)
SECTION_TITLE = 'Section Title'

class FocusAreasPageLinkTopic(TaggedItemBase):
content_object = ParentalKey('project.FocusAreasPageLink', blank=True, on_delete=models.CASCADE, related_name='focus_areas_page_link_topics')


class ProjectPageTopic(TaggedItemBase):
content_object = ParentalKey('project.ProjectPage', blank=True, on_delete=models.CASCADE, related_name='project_page_topics')


class ProjectPage(PublishedDateMixin, TypesetBodyMixin, HeroMixin, Page):
"""
http://development-initiatives.surge.sh/page-templates/08-1-project
"""
other_pages_heading = models.CharField(
max_length=255,
null=True,
blank=True,
verbose_name='Section Title',
verbose_name=SECTION_TITLE,
default='Related content'
)
topics = ClusterTaggableManager(through=ProjectPageTopic, blank=True, verbose_name="Topics")
content_panels = Page.content_panels + [
hero_panels(),
PublishedDatePanel(),
FieldPanel('topics'),
FieldPanel('body'),
MultiFieldPanel([
FieldPanel('other_pages_heading'),
Expand Down Expand Up @@ -68,8 +93,8 @@ class FocusAreasPage(TypesetBodyMixin, HeroMixin, Page):
"""
http://development-initiatives.surge.sh/page-templates/08-focus-areas
"""
subpage_types = ['ProjectPage', 'general.General']
parent_page_types = ['whatwedo.WhatWeDoPage']
subpage_types = ['ProjectPage', 'general.General', 'FocusAreasPage']
parent_page_types = ['whatwedo.WhatWeDoPage', 'FocusAreasPage']

class Meta():
verbose_name = 'Focus Areas Page'
Expand All @@ -78,7 +103,7 @@ class Meta():
max_length=255,
null=True,
blank=True,
verbose_name='Section Title',
verbose_name=SECTION_TITLE,
default='More about'
)

Expand All @@ -96,14 +121,14 @@ class Meta():
]


class FocusAreasPageLink(Orderable):
class FocusAreasPageLink(ClusterableModel):
page = ParentalKey(
Page,
related_name='focus_areas_page_link',
on_delete=models.CASCADE
)
projects = StreamField(
[('page', PageChooserBlock(page_type="project.ProjectPage", required=True))],
[('page', PageChooserBlock(required=True))],
verbose_name="Projects",
null=True,
blank=True,
Expand Down Expand Up @@ -135,14 +160,46 @@ class FocusAreasPageLink(Orderable):
verbose_name='Image',
help_text='Add an image to this focus area'
)
related_page_section_title = models.CharField(blank=True, max_length=255, default='Key projects and publications', verbose_name=SECTION_TITLE)
related_page_handler = models.CharField(max_length=253, choices=RELATED_CHOICES, default='manual', verbose_name='Show By')
topics = ClusterTaggableManager(through=FocusAreasPageLinkTopic, blank=True, verbose_name="Topics")
panels = [
FieldPanel('title'),
FieldPanel('subtitle'),
FieldPanel('body'),
FieldPanel('image'),
FieldPanel('projects')

MultiFieldPanel([
FieldPanel('related_page_section_title'),
FieldPanel('related_page_handler', heading='Show by'),
FieldPanel('topics', help_text="Fill in tags if you selected topics above"),
FieldPanel('projects'),
], heading='Focus Area Pages', help_text="Manual option displays all page types while Topic only matches projects, publications, podcasts, blogs and news stories")
]

def get_topic_related_pages(self):
ALT_MAX_RELATED_LINKS = 2
objects = {
'audio': AudioVisualMedia.objects,
'legacy': LegacyPublicationPage.objects,
'publication': PublicationPage.objects,
'short': ShortPublicationPage.objects,
'project': ProjectPage.objects,
'blog': BlogArticlePage.objects,
'news': NewsStoryPage.objects,
}

if self.related_page_handler == 'topic' or self.related_page_handler == 'Topic':
combined_queryset = {}
for key in objects:
results = objects[key].live().filter(topics__in=self.topics.get_queryset()).order_by('title').distinct()
for item in results:
if item.title:
combined_queryset[item.title] = item #remove duplicate titles, usually alias pages
combined_queryset = [combined_queryset[key] for key in combined_queryset.keys()]
slice_queryset = combined_queryset[:ALT_MAX_RELATED_LINKS] if len(combined_queryset) > ALT_MAX_RELATED_LINKS else combined_queryset
return get_related_pages(self, slice_queryset, objects, ALT_MAX_RELATED_LINKS)


class FocusAreasProjects(OtherPageMixin):
page = ParentalKey(
Expand Down
36 changes: 26 additions & 10 deletions di_website/templates/includes/partials/focus_areas.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,34 @@
{% load wagtailimages_tags wagtailcore_tags static responsive %}

{% block project_aside %}
{% if self.projects %}
<h3 class="project__subheading">Key projects</h3>

{% for block in self.projects %}
{% if block.value.specific.hero_image %}
{% image block.value.specific.hero_image max-313x178 as hero_img %}
<a href="{% pageurl block.value.specific %}" class="project-card" style="background-image: url({{hero_img.url}});">
{% if self.related_page_section_title %}
<h3 class="project__subheading">{{ self.related_page_section_title }}</h3>
{% endif %}
{% if self.related_page_handler == 'manual' %}
{% if self.projects %}
{% for block in self.projects %}
{% if block.value.specific.hero_image %}
{% image block.value.specific.hero_image max-313x178 as hero_img %}
<a href="{% pageurl block.value.specific %}" class="project-card" style="background-image: url({{hero_img.url}});">
{% else %}
<a href="{% pageurl block.value.specific %}" class="project-card" style="background-image: url({% static 'img/fallback-image.jpg' %});">
{% endif %}
<span class="project-card__caption">{{ block.value.title }}</span>
</a>
{% endfor %}
{% endif %}
{% else %}
{% with related_pages=self.get_topic_related_pages %}
{% for self in related_pages %}
{% if self.hero_image %}
{% image self.hero_image max-313x178 as hero_img %}
<a href="{% pageurl self %}" class="project-card" style="background-image: url({{hero_img.url}});">
{% else %}
<a href="{% pageurl block.value.specific %}" class="project-card" style="background-image: url({% static 'img/fallback-image.jpg' %});">
<a href="{% pageurl self %}" class="project-card" style="background-image: url({% static 'img/fallback-image.jpg' %});">
{% endif %}
<span class="project-card__caption">{{ block.value.title }}</span>
</a>
<span class="project-card__caption">{{ self.title }}</span>
</a>
{% endfor %}
{% endwith %}
{% endif %}
{% endblock project_aside %}

0 comments on commit a574a4b

Please sign in to comment.