diff --git a/app/impact_areas/migrations/0014_remove_individualimpactareapage_black_dogear_box_link_text_and_more.py b/app/impact_areas/migrations/0014_remove_individualimpactareapage_black_dogear_box_link_text_and_more.py new file mode 100644 index 0000000..ad98470 --- /dev/null +++ b/app/impact_areas/migrations/0014_remove_individualimpactareapage_black_dogear_box_link_text_and_more.py @@ -0,0 +1,121 @@ +# Generated by Django 4.2.7 on 2024-06-04 23:15 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('impact_areas', '0013_individualimpactareapage_external_icon_and_more'), + ] + + operations = [ + migrations.RemoveField( + model_name='individualimpactareapage', + name='black_dogear_box_link_text', + ), + migrations.RemoveField( + model_name='individualimpactareapage', + name='black_dogear_box_link_url', + ), + migrations.RemoveField( + model_name='individualimpactareapage', + name='black_dogear_box_title', + ), + migrations.RemoveField( + model_name='individualimpactareapage', + name='explore_impact_areas_text', + ), + migrations.RemoveField( + model_name='individualimpactareapage', + name='load_more_projects_text', + ), + migrations.RemoveField( + model_name='individualimpactareapage', + name='projects_title', + ), + migrations.RemoveField( + model_name='individualimpactareapage', + name='red_dogear_box_link_text', + ), + migrations.RemoveField( + model_name='individualimpactareapage', + name='red_dogear_box_link_url', + ), + migrations.RemoveField( + model_name='individualimpactareapage', + name='red_dogear_box_title', + ), + migrations.RemoveField( + model_name='individualimpactareapage', + name='use_cases_title', + ), + migrations.RemoveField( + model_name='individualimpactareapage', + name='view_all_projects_link', + ), + migrations.RemoveField( + model_name='individualimpactareapage', + name='view_all_projects_text', + ), + migrations.AddField( + model_name='impactareaspage', + name='black_dogear_box_link_text', + field=models.CharField(default='Get Involved with HOT'), + ), + migrations.AddField( + model_name='impactareaspage', + name='black_dogear_box_link_url', + field=models.URLField(blank=True), + ), + migrations.AddField( + model_name='impactareaspage', + name='black_dogear_box_title', + field=models.CharField(default='Check many opportunities to get involved with HOT!'), + ), + migrations.AddField( + model_name='impactareaspage', + name='explore_impact_areas_text', + field=models.CharField(default='Explore Other Impact Areas'), + ), + migrations.AddField( + model_name='impactareaspage', + name='load_more_projects_text', + field=models.CharField(default='Load More Projects'), + ), + migrations.AddField( + model_name='impactareaspage', + name='projects_title', + field=models.CharField(default='Projects'), + ), + migrations.AddField( + model_name='impactareaspage', + name='red_dogear_box_link_text', + field=models.CharField(default='View Tools & Resources'), + ), + migrations.AddField( + model_name='impactareaspage', + name='red_dogear_box_link_url', + field=models.URLField(blank=True), + ), + migrations.AddField( + model_name='impactareaspage', + name='red_dogear_box_title', + field=models.CharField(default='Learn more about Tools & Resources and Data Access'), + ), + migrations.AddField( + model_name='impactareaspage', + name='use_cases_title', + field=models.CharField(default='Use Cases'), + ), + migrations.AddField( + model_name='impactareaspage', + name='view_all_projects_link', + field=models.URLField(blank=True), + ), + migrations.AddField( + model_name='impactareaspage', + name='view_all_projects_text', + field=models.CharField(default='View all projects'), + ), + ] diff --git a/app/impact_areas/models.py b/app/impact_areas/models.py index 91fa638..d63017a 100644 --- a/app/impact_areas/models.py +++ b/app/impact_areas/models.py @@ -42,6 +42,10 @@ def get_context(self, request, *args, **kwargs): context['other_impact_areas'] = other_impact_areas return context + parent_page_type = [ + 'impact_areas.ImpactAreasPage' + ] + header_image = models.ForeignKey( "wagtailimages.Image", null=True, @@ -71,24 +75,8 @@ def get_context(self, request, *args, **kwargs): intro = RichTextField(blank=True) description = RichTextField(blank=True) - use_cases_title = models.CharField(default="Use Cases") use_cases = StreamField(UseCaseBlock(), use_json_field=True, blank=True, null=True) - projects_title = models.CharField(default="Projects") - view_all_projects_text = models.CharField(default="View all projects") - view_all_projects_link = models.URLField(blank=True) - load_more_projects_text = models.CharField(default="Load More Projects") - - explore_impact_areas_text = models.CharField(default="Explore Other Impact Areas") - - red_dogear_box_title = models.CharField(blank=True) - red_dogear_box_link_text = models.CharField(blank=True) - red_dogear_box_link_url = models.URLField(blank=True) - - black_dogear_box_title = models.CharField(blank=True) - black_dogear_box_link_text = models.CharField(blank=True) - black_dogear_box_link_url = models.URLField(blank=True) - content_panels = Page.content_panels + [ MultiFieldPanel([ FieldPanel('header_image'), @@ -101,24 +89,8 @@ def get_context(self, request, *args, **kwargs): FieldPanel('description'), ], heading="Body"), MultiFieldPanel([ - FieldPanel('use_cases_title'), FieldPanel('use_cases'), ], heading="Use Cases"), - MultiFieldPanel([ - FieldPanel('projects_title'), - FieldPanel('view_all_projects_text'), - FieldPanel('view_all_projects_link'), - FieldPanel('load_more_projects_text'), - ], heading="Projects"), - FieldPanel('explore_impact_areas_text'), - MultiFieldPanel([ - FieldPanel('red_dogear_box_title'), - FieldPanel('red_dogear_box_link_text'), - FieldPanel('red_dogear_box_link_url'), - FieldPanel('black_dogear_box_title'), - FieldPanel('black_dogear_box_link_text'), - FieldPanel('black_dogear_box_link_url'), - ], heading="Dogear Boxes"), ] @@ -134,6 +106,8 @@ class ImpactAreaBlock(StreamBlock): class ImpactAreasPage(Page): + max_count = 1 + intro = RichTextField(blank=True) image = models.ForeignKey( @@ -147,10 +121,48 @@ class ImpactAreasPage(Page): impact_area_blocks = StreamField(ImpactAreaBlock(), use_json_field=True, null=True) + # > IMPACT AREA SHARED FIELDS + use_cases_title = models.CharField(default="Use Cases") + + projects_title = models.CharField(default="Projects") + view_all_projects_text = models.CharField(default="View all projects") + view_all_projects_link = models.URLField(blank=True) + load_more_projects_text = models.CharField(default="Load More Projects") + + explore_impact_areas_text = models.CharField(default="Explore Other Impact Areas") + + red_dogear_box_title = models.CharField(default="Learn more about Tools & Resources and Data Access") + red_dogear_box_link_text = models.CharField(default="View Tools & Resources") + red_dogear_box_link_url = models.URLField(blank=True) + + black_dogear_box_title = models.CharField(default="Check many opportunities to get involved with HOT!") + black_dogear_box_link_text = models.CharField(default="Get Involved with HOT") + black_dogear_box_link_url = models.URLField(blank=True) + content_panels = Page.content_panels + [ MultiFieldPanel([ FieldPanel('image'), FieldPanel('intro') ], heading="Header section"), - FieldPanel('impact_area_blocks') + FieldPanel('impact_area_blocks'), + MultiFieldPanel([ + MultiFieldPanel([ + FieldPanel('use_cases_title'), + ], heading="Use Cases"), + MultiFieldPanel([ + FieldPanel('projects_title'), + FieldPanel('view_all_projects_text'), + FieldPanel('view_all_projects_link'), + FieldPanel('load_more_projects_text'), + ], heading="Projects"), + FieldPanel('explore_impact_areas_text'), + MultiFieldPanel([ + FieldPanel('red_dogear_box_title'), + FieldPanel('red_dogear_box_link_text'), + FieldPanel('red_dogear_box_link_url'), + FieldPanel('black_dogear_box_title'), + FieldPanel('black_dogear_box_link_text'), + FieldPanel('black_dogear_box_link_url'), + ], heading="Dogear Boxes"), + ], heading="Impact Area Shared Fields"), ] diff --git a/app/impact_areas/templates/impact_areas/individual_impact_area_page.html b/app/impact_areas/templates/impact_areas/individual_impact_area_page.html index 7ee8749..3a971b0 100644 --- a/app/impact_areas/templates/impact_areas/individual_impact_area_page.html +++ b/app/impact_areas/templates/impact_areas/individual_impact_area_page.html @@ -26,7 +26,7 @@ {% comment %} USE CASES {% endcomment %} - {% include "ui/components/SectionHeadingWithUnderline.html" with title=page.use_cases_title %} + {% include "ui/components/SectionHeadingWithUnderline.html" with title=page.get_parent.specific.use_cases_title %}
{% for case in page.use_cases %} {% include "./components/UseCaseBox.html" with number=forloop.counter body=case.value.description linktext=case.value.link_text linkurl=case.value.link_url %} @@ -37,10 +37,10 @@
- {% include "ui/components/SectionHeadingWithUnderline.html" with title=page.projects_title %} + {% include "ui/components/SectionHeadingWithUnderline.html" with title=page.get_parent.specific.projects_title %}

- {% include "ui/components/BaseLink.html" with linktext=page.view_all_projects_text linkurl=page.view_all_projects_link %} + {% include "ui/components/BaseLink.html" with linktext=page.get_parent.specific.view_all_projects_text linkurl=page.view_all_projects_link %}

@@ -58,7 +58,7 @@ hx-select-oob="#projects-list:beforeend, #next-project:outerHTML" > - Load More Projects + {{page.get_parent.specific.load_more_projects_text}} {% include "ui/components/icon_svgs/LinkCaret.html" with class="rotate-90 text-hot-red" %} @@ -69,7 +69,7 @@ {% comment %} OTHER IMPACT AREAS {% endcomment %}

- {{ page.explore_impact_areas_text }} + {{ page.get_parent.specific.explore_impact_areas_text }}

{% for area in other_impact_areas %} @@ -91,10 +91,10 @@

{% comment %} DOGEAR BOXES {% endcomment %}
- {% include "ui/components/dogear_boxes/DogearRed.html" with title=page.red_dogear_box_title linktext=page.red_dogear_box_link_text linkurl=page.red_dogear_box_link_url %} + {% include "ui/components/dogear_boxes/DogearRed.html" with title=page.get_parent.specific.red_dogear_box_title linktext=page.get_parent.specific.red_dogear_box_link_text linkurl=page.get_parent.specific.red_dogear_box_link_url %}
- {% include "ui/components/dogear_boxes/DogearBlack.html" with title=page.black_dogear_box_title linktext=page.black_dogear_box_link_text linkurl=page.black_dogear_box_link_url %} + {% include "ui/components/dogear_boxes/DogearBlack.html" with title=page.get_parent.specific.black_dogear_box_title linktext=page.get_parent.specific.black_dogear_box_link_text linkurl=page.get_parent.specific.black_dogear_box_link_url %}

diff --git a/app/members/__init__.py b/app/members/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/members/admin.py b/app/members/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/app/members/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/app/members/apps.py b/app/members/apps.py new file mode 100644 index 0000000..db4ad21 --- /dev/null +++ b/app/members/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class MembersConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'app.members' diff --git a/app/members/migrations/0001_initial.py b/app/members/migrations/0001_initial.py new file mode 100644 index 0000000..4a06355 --- /dev/null +++ b/app/members/migrations/0001_initial.py @@ -0,0 +1,47 @@ +# Generated by Django 4.2.7 on 2024-06-03 23:02 + +from django.db import migrations, models +import django.db.models.deletion +import wagtail.blocks +import wagtail.fields + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ('wagtailcore', '0089_log_entry_data_json_null_to_object'), + ('wagtailimages', '0025_alter_image_file_alter_rendition_file'), + ] + + operations = [ + migrations.CreateModel( + name='MemberOwnerPage', + fields=[ + ('page_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='wagtailcore.page')), + ('on_the_web_title', models.CharField(default='On the Web')), + ('posts_title', models.CharField(default='Posts')), + ('project_contribution_title', models.CharField(default='Project Contribution')), + ], + options={ + 'abstract': False, + }, + bases=('wagtailcore.page',), + ), + migrations.CreateModel( + name='IndividualMemberPage', + fields=[ + ('page_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='wagtailcore.page')), + ('position', models.CharField()), + ('location', models.CharField()), + ('introduction', wagtail.fields.RichTextField()), + ('on_the_web_links', wagtail.fields.StreamField([('blocks', wagtail.blocks.StructBlock([('link_text', wagtail.blocks.CharBlock(required=True)), ('link_url', wagtail.blocks.URLBlock(blank=True, required=False))]))], blank=True, use_json_field=True)), + ('image', models.ForeignKey(blank=True, help_text='An image of the member', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='wagtailimages.image')), + ], + options={ + 'abstract': False, + }, + bases=('wagtailcore.page',), + ), + ] diff --git a/app/members/migrations/0002_remove_individualmemberpage_location_and_more.py b/app/members/migrations/0002_remove_individualmemberpage_location_and_more.py new file mode 100644 index 0000000..e8f6967 --- /dev/null +++ b/app/members/migrations/0002_remove_individualmemberpage_location_and_more.py @@ -0,0 +1,24 @@ +# Generated by Django 4.2.7 on 2024-06-03 23:26 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('mapping_hubs', '0008_alter_individualmappinghubpage_dogear_boxes'), + ('members', '0001_initial'), + ] + + operations = [ + migrations.RemoveField( + model_name='individualmemberpage', + name='location', + ), + migrations.AddField( + model_name='individualmemberpage', + name='location_hub', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='mapping_hubs.individualmappinghubpage'), + ), + ] diff --git a/app/members/migrations/__init__.py b/app/members/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/members/models.py b/app/members/models.py new file mode 100644 index 0000000..00e53fe --- /dev/null +++ b/app/members/models.py @@ -0,0 +1,82 @@ +from django.db import models +from wagtail.admin.panels import FieldPanel, MultiFieldPanel +from wagtail.blocks import CharBlock, StreamBlock, StructBlock, URLBlock, PageChooserBlock +from wagtail.fields import RichTextField, StreamField +from wagtail.models import Page +from django.db.models import Q +from app.projects.models import IndividualProjectPage +from app.news.models import IndividualNewsPage + +class WebLinkStructBlock(StructBlock): + link_text = CharBlock(required=True) + link_url = URLBlock(required=False, blank=True) + + +class WebLinkBlock(StreamBlock): + blocks = WebLinkStructBlock() + + +class MemberOwnerPage(Page): + max_count = 1 + + on_the_web_title = models.CharField(default="On the Web") + posts_title = models.CharField(default="Posts") + project_contribution_title = models.CharField(default="Project Contribution") + + content_panels = Page.content_panels + [ + FieldPanel('on_the_web_title'), + FieldPanel('posts_title'), + FieldPanel('project_contribution_title'), + ] + +""" +This page should only be created as a child of a MemberOwnerPage! +Its template depends on fields from the MemberOwnerPage in order +to create one unifying place where unchanging fields may be modified. +""" +class IndividualMemberPage(Page): + def get_context(self, request, *args, **kwargs): + context = super().get_context(request, *args, **kwargs) + + news_posts = IndividualNewsPage.objects.live().filter( + Q(authors__contains=[{'type': 'author', 'value': context['page'].id}]) + ).filter(locale=context['page'].locale) + project_contributions = IndividualProjectPage.objects.live().filter( + Q(project_contributors__contains=[{'type': 'contributor', 'value': context['page'].id}]) + ).filter(locale=context['page'].locale) + + context['posts'] = news_posts + context['contributions'] = project_contributions + + return context + + parent_page_type = [ + 'members.MemberOwnerPage' + ] + + image = models.ForeignKey( + "wagtailimages.Image", + null=True, + blank=True, + on_delete=models.SET_NULL, + related_name="+", + help_text="An image of the member", + ) + position = models.CharField() + location_hub = models.ForeignKey( + 'mapping_hubs.IndividualMappingHubPage', + null=True, + blank=True, + on_delete=models.SET_NULL, + related_name='+' + ) + introduction = RichTextField() + on_the_web_links = StreamField(WebLinkBlock(), blank=True, use_json_field=True) + + content_panels = Page.content_panels + [ + FieldPanel('image'), + FieldPanel('position'), + FieldPanel('location_hub'), + FieldPanel('introduction'), + FieldPanel('on_the_web_links'), + ] diff --git a/app/members/templates/members/individual_member_page.html b/app/members/templates/members/individual_member_page.html new file mode 100644 index 0000000..ccd2c59 --- /dev/null +++ b/app/members/templates/members/individual_member_page.html @@ -0,0 +1,73 @@ +{% extends "base.html" %} +{% load static %} +{% load wagtailcore_tags %} +{% load wagtailimages_tags %} +{% load compress %} +{% block body_class %}template-individualmappinghubpage{% endblock %} +{% block extra_css %} + {% compress css %} + {% endcompress css %} +{% endblock extra_css %} + +{% block content %} +
+ {% comment %} BODY SECTION {% endcomment %} +
+
+ {% if page.image %} + {% image page.image original class="md:w-full h-auto w-auto max-h-[24rem] object-contain" %} + {% endif %} +
+
+ {% comment %} TODO: REMOVE PLACEHOLDER AND IMPLEMENT PROPER (BASICALLY REQUIRES OTHER PAGES COMPLETION) {% endcomment %} +

+ Board + / + Voting Member + / + Staff +

+

{{page.title}}

+

+ {{page.position}} + / + {{page.location_hub.title}} +

+
+ {{page.introduction|safe}} +
+
+
+ + {% comment %} ON THE WEB LINKS {% endcomment %} + {% if page.on_the_web_links %} +
+
+
+

{{page.get_parent.specific.on_the_web_title}}

+
+ {% for link in page.on_the_web_links %} +

+ {% include "ui/components/BaseLink.html" with linktext=link.value.link_text linkurl=link.value.link_url %} +

+ {% endfor %} +
+
+
+ {% endif %} + + {% comment %} NEWS POSTS {% endcomment %} + {% if posts %} +
+ {% include "ui/components/news/NewsPreviewCarousel.html" with news=posts title=page.get_parent.specific.posts_title %} +
+ {% endif %} + + {% comment %} CONTRIBUTIONS {% endcomment %} + {% if contributions%} +
+ {% include "ui/components/projects/ProjectPreviewCarousel.html" with projects=contributions title=page.get_parent.specific.project_contribution_title %} +
+ {% endif %} +
+{% endblock %} \ No newline at end of file diff --git a/app/members/tests.py b/app/members/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/app/members/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/app/members/views.py b/app/members/views.py new file mode 100644 index 0000000..91ea44a --- /dev/null +++ b/app/members/views.py @@ -0,0 +1,3 @@ +from django.shortcuts import render + +# Create your views here. diff --git a/app/news/migrations/0016_individualnewspage_authors.py b/app/news/migrations/0016_individualnewspage_authors.py new file mode 100644 index 0000000..ecdcd16 --- /dev/null +++ b/app/news/migrations/0016_individualnewspage_authors.py @@ -0,0 +1,20 @@ +# Generated by Django 4.2.7 on 2024-06-04 16:57 + +from django.db import migrations +import wagtail.blocks +import wagtail.fields + + +class Migration(migrations.Migration): + + dependencies = [ + ('news', '0015_alter_individualnewspage_article_body'), + ] + + operations = [ + migrations.AddField( + model_name='individualnewspage', + name='authors', + field=wagtail.fields.StreamField([('author', wagtail.blocks.PageChooserBlock(page_type=['members.IndividualMemberPage']))], blank=True, null=True, use_json_field=True), + ), + ] diff --git a/app/news/migrations/0017_individualnewspage_authors_posted_by_text_and_more.py b/app/news/migrations/0017_individualnewspage_authors_posted_by_text_and_more.py new file mode 100644 index 0000000..2d5154e --- /dev/null +++ b/app/news/migrations/0017_individualnewspage_authors_posted_by_text_and_more.py @@ -0,0 +1,23 @@ +# Generated by Django 4.2.7 on 2024-06-04 21:57 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('news', '0016_individualnewspage_authors'), + ] + + operations = [ + migrations.AddField( + model_name='individualnewspage', + name='authors_posted_by_text', + field=models.CharField(default='Posted by', help_text="The text which appears prior to the authors names; with 'posted by', the text displays as 'posted by [author]'."), + ), + migrations.AddField( + model_name='individualnewspage', + name='authors_posted_on_text', + field=models.CharField(default='on', help_text="The text which appears prior to the date; with 'on', it would display as 'on [date]'."), + ), + ] diff --git a/app/news/migrations/0018_alter_individualnewspage_date.py b/app/news/migrations/0018_alter_individualnewspage_date.py new file mode 100644 index 0000000..121acd0 --- /dev/null +++ b/app/news/migrations/0018_alter_individualnewspage_date.py @@ -0,0 +1,18 @@ +# Generated by Django 4.2.7 on 2024-06-04 22:36 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('news', '0017_individualnewspage_authors_posted_by_text_and_more'), + ] + + operations = [ + migrations.AlterField( + model_name='individualnewspage', + name='date', + field=models.DateField(help_text='Post date'), + ), + ] diff --git a/app/news/migrations/0019_newsownerpage_and_more.py b/app/news/migrations/0019_newsownerpage_and_more.py new file mode 100644 index 0000000..a0c57dd --- /dev/null +++ b/app/news/migrations/0019_newsownerpage_and_more.py @@ -0,0 +1,66 @@ +# Generated by Django 4.2.7 on 2024-06-04 23:03 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('wagtailcore', '0089_log_entry_data_json_null_to_object'), + ('news', '0018_alter_individualnewspage_date'), + ] + + operations = [ + migrations.CreateModel( + name='NewsOwnerPage', + fields=[ + ('page_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='wagtailcore.page')), + ('authors_posted_by_text', models.CharField(default='Posted by', help_text="The text which appears prior to the authors names; with 'posted by', the text displays as 'posted by [author]'.")), + ('authors_posted_on_text', models.CharField(default='on', help_text="The text which appears prior to the date; with 'on', it would display as 'on [date]'.")), + ('related_projects_title', models.CharField(default='Related Projects')), + ('related_news_title', models.CharField(default='Related News')), + ('view_all_news_text', models.CharField(default='View all News')), + ('view_all_news_url', models.URLField(blank=True)), + ('news_read_more_text', models.CharField(default='Read More')), + ('categories_title', models.CharField(default='Categories')), + ('tags_title', models.CharField(default='Tags')), + ], + options={ + 'abstract': False, + }, + bases=('wagtailcore.page',), + ), + migrations.RemoveField( + model_name='individualnewspage', + name='authors_posted_by_text', + ), + migrations.RemoveField( + model_name='individualnewspage', + name='authors_posted_on_text', + ), + migrations.RemoveField( + model_name='individualnewspage', + name='categories_title', + ), + migrations.RemoveField( + model_name='individualnewspage', + name='news_read_more_text', + ), + migrations.RemoveField( + model_name='individualnewspage', + name='related_news_title', + ), + migrations.RemoveField( + model_name='individualnewspage', + name='related_projects_title', + ), + migrations.RemoveField( + model_name='individualnewspage', + name='tags_title', + ), + migrations.RemoveField( + model_name='individualnewspage', + name='view_all_news_text', + ), + ] diff --git a/app/news/models.py b/app/news/models.py index 8bc6cb6..d2c3b1e 100644 --- a/app/news/models.py +++ b/app/news/models.py @@ -12,6 +12,36 @@ from wagtail.snippets.models import register_snippet +class NewsOwnerPage(Page): + max_count = 1 + + authors_posted_by_text = models.CharField(default="Posted by", help_text="The text which appears prior to the authors names; with 'posted by', the text displays as 'posted by [author]'.") + authors_posted_on_text = models.CharField(default="on", help_text="The text which appears prior to the date; with 'on', it would display as 'on [date]'.") + related_projects_title = models.CharField(default="Related Projects") + related_news_title = models.CharField(default="Related News") + view_all_news_text = models.CharField(default="View all News") + view_all_news_url = models.URLField(blank=True) + news_read_more_text = models.CharField(default="Read More") + categories_title = models.CharField(default="Categories") + tags_title = models.CharField(default="Tags") + + content_panels = Page.content_panels + [ + MultiFieldPanel([ + FieldPanel("authors_posted_by_text"), + FieldPanel("authors_posted_on_text"), + ], heading="Info"), + MultiFieldPanel([ + FieldPanel('related_projects_title'), + FieldPanel('related_news_title'), + FieldPanel('view_all_news_text'), + FieldPanel('view_all_news_url'), + FieldPanel('news_read_more_text'), + FieldPanel('categories_title'), + FieldPanel('tags_title'), + ], heading="Sidebar"), + ] + + @register_snippet class NewsCategory(models.Model): category_name = models.CharField() @@ -36,6 +66,12 @@ class NewsTag(TaggedItemBase): class IndividualNewsPage(Page): + parent_page_type = [ + 'news.NewsOwnerPage' + ] + + authors = StreamField([('author', PageChooserBlock(page_type="members.IndividualMemberPage"))], use_json_field=True, null=True, blank=True) + image = models.ForeignKey( "wagtailimages.Image", null=True, @@ -47,7 +83,7 @@ class IndividualNewsPage(Page): intro = RichTextField(blank=True) - date = models.DateField("Post date") + date = models.DateField(help_text="Post date") article_body = StreamField([ ('text_block', RichTextBlock(features=[ @@ -55,28 +91,22 @@ class IndividualNewsPage(Page): ])) ], use_json_field=True, null=True, blank=True) - # Question: are related projects/news chosen for the article, or are they based off something? - related_projects_title = models.CharField(default="Related Projects") related_projects = StreamField([ ('project_page', PageChooserBlock(page_type="projects.IndividualProjectPage")) ], use_json_field=True, null=True, blank=True) - related_news_title = models.CharField(default="Related News") - view_all_news_text = models.CharField(default="View all News") related_news = StreamField([ ('news_page', PageChooserBlock(page_type="news.IndividualNewsPage")) ], use_json_field=True, null=True, blank=True) - news_read_more_text = models.CharField(default="Read More") - categories_title = models.CharField(default="Categories") categories = ParentalManyToManyField('news.NewsCategory', blank=True) - tags_title = models.CharField(default="Tags") tags = ClusterTaggableManager(through=NewsTag, blank=True) content_panels = Page.content_panels + [ MultiFieldPanel([ - FieldPanel("date") + FieldPanel("authors"), + FieldPanel("date"), ], heading="Info"), MultiFieldPanel([ FieldPanel("image"), @@ -84,15 +114,9 @@ class IndividualNewsPage(Page): FieldPanel("article_body"), ], heading="Body"), MultiFieldPanel([ - FieldPanel('related_projects_title'), FieldPanel('related_projects'), - FieldPanel('related_news_title'), - FieldPanel('view_all_news_text'), FieldPanel('related_news'), - FieldPanel('news_read_more_text'), - FieldPanel('categories_title'), FieldPanel('categories', widget=forms.CheckboxSelectMultiple), - FieldPanel('tags_title'), FieldPanel('tags'), ], heading="Sidebar"), ] diff --git a/app/news/templates/news/individual_news_page.html b/app/news/templates/news/individual_news_page.html index d1869c1..26b25ac 100644 --- a/app/news/templates/news/individual_news_page.html +++ b/app/news/templates/news/individual_news_page.html @@ -14,7 +14,16 @@ {% comment %} HEADER {% endcomment %}

{{ page.title }}

-

Posted by Author on {{ page.date }}

+

+ {{page.get_parent.specific.authors_posted_by_text}} + {% for author in page.authors %} + {{author.value.title}} + {% if not forloop.last %} + , + {% endif %} + {% endfor %} + {{page.get_parent.specific.authors_posted_on_text}} {{ page.date }} +

@@ -35,7 +44,7 @@

{{ page.title }}


- {{ page.related_projects_title }} + {{ page.get_parent.specific.related_projects_title }}

{% with projects=page.related_projects %} @@ -51,13 +60,15 @@


- {{ page.related_news_title }} + {{ page.get_parent.specific.related_news_title }}

- {% include "ui/components/BaseLink.html" with linkurl="#" linktext=page.view_all_news_text %} +
+ {% include "ui/components/BaseLink.html" with linkurl="#" linktext=page.get_parent.specific.view_all_news_text %} +
{% with allnews=page.related_news %} {% for news in allnews %} - {% include "ui/components/news/NewsPreviewBlockNews.html" with news=news.value readmoretext=page.read_more_text %} + {% include "ui/components/news/NewsPreviewBlockNews.html" with news=news.value readmoretext=page.get_parent.specific.read_more_text %} {% endfor %} {% endwith %}
@@ -68,7 +79,7 @@


- {{ page.categories_title }} + {{ page.get_parent.specific.categories_title }}

{% with categories=page.categories.all %} @@ -84,7 +95,7 @@


- {{ page.tags_title }} + {{ page.get_parent.specific.tags_title }}

{% with tags=page.tags.all %} diff --git a/app/programs/migrations/0008_programownerpage_and_more.py b/app/programs/migrations/0008_programownerpage_and_more.py new file mode 100644 index 0000000..c0a645c --- /dev/null +++ b/app/programs/migrations/0008_programownerpage_and_more.py @@ -0,0 +1,85 @@ +# Generated by Django 4.2.7 on 2024-06-05 16:21 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('wagtailcore', '0089_log_entry_data_json_null_to_object'), + ('programs', '0007_alter_individualprogrampage_bottom_banner_text'), + ] + + operations = [ + migrations.CreateModel( + name='ProgramOwnerPage', + fields=[ + ('page_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='wagtailcore.page')), + ('stats_title', models.CharField(default='Stats')), + ('goals_title', models.CharField(default='Goals')), + ('projects_title', models.CharField(default='Projects')), + ('partners_title', models.CharField(default='Meet Our Partners')), + ('view_all_partners_title', models.CharField(default='View All Partners')), + ('view_all_partners_link', models.CharField(blank=True)), + ('more_programs_title', models.CharField(default='More Programs')), + ('view_all_programs_title', models.CharField(default='View All Programs')), + ('view_all_programs_link', models.URLField(blank=True)), + ('bottom_banner_text', models.CharField(default='Check out the many opportunities to get involved with HOT!')), + ('bottom_banner_url', models.URLField(blank=True)), + ('bottom_banner_url_text', models.CharField(default='Get Involved with HOT')), + ], + options={ + 'abstract': False, + }, + bases=('wagtailcore.page',), + ), + migrations.RemoveField( + model_name='individualprogrampage', + name='bottom_banner_text', + ), + migrations.RemoveField( + model_name='individualprogrampage', + name='bottom_banner_url', + ), + migrations.RemoveField( + model_name='individualprogrampage', + name='bottom_banner_url_text', + ), + migrations.RemoveField( + model_name='individualprogrampage', + name='goals_title', + ), + migrations.RemoveField( + model_name='individualprogrampage', + name='more_programs_title', + ), + migrations.RemoveField( + model_name='individualprogrampage', + name='partners_title', + ), + migrations.RemoveField( + model_name='individualprogrampage', + name='projects_title', + ), + migrations.RemoveField( + model_name='individualprogrampage', + name='stats_title', + ), + migrations.RemoveField( + model_name='individualprogrampage', + name='view_all_partners_link', + ), + migrations.RemoveField( + model_name='individualprogrampage', + name='view_all_partners_title', + ), + migrations.RemoveField( + model_name='individualprogrampage', + name='view_all_programs_link', + ), + migrations.RemoveField( + model_name='individualprogrampage', + name='view_all_programs_title', + ), + ] diff --git a/app/programs/models.py b/app/programs/models.py index a639777..9e55079 100644 --- a/app/programs/models.py +++ b/app/programs/models.py @@ -33,6 +33,49 @@ class ProgramGoalBlock(StreamBlock): goal_block = IndividualGoalBlock() +class ProgramOwnerPage(Page): + max_count = 1 + + stats_title = models.CharField(default="Stats") + goals_title = models.CharField(default="Goals") + projects_title = models.CharField(default="Projects") + + partners_title = models.CharField(default="Meet Our Partners") + view_all_partners_title = models.CharField(default="View All Partners") + view_all_partners_link = models.CharField(blank=True) + + more_programs_title = models.CharField(default="More Programs") + view_all_programs_title = models.CharField(default="View All Programs") + view_all_programs_link = models.URLField(blank=True) + + bottom_banner_text = models.CharField(default="Check out the many opportunities to get involved with HOT!") + bottom_banner_url = models.URLField(blank=True) + bottom_banner_url_text = models.CharField(default="Get Involved with HOT") + + content_panels = Page.content_panels + [ + MultiFieldPanel([ + FieldPanel("stats_title"), + FieldPanel("goals_title"), + FieldPanel("projects_title"), + ], heading="Various Section Titles"), + MultiFieldPanel([ + FieldPanel("partners_title"), + FieldPanel("view_all_partners_title"), + FieldPanel("view_all_partners_link"), + ], heading="Partners"), + MultiFieldPanel([ + FieldPanel("more_programs_title"), + FieldPanel("view_all_programs_title"), + FieldPanel("view_all_programs_link"), + ], heading="Programs"), + MultiFieldPanel([ + FieldPanel('bottom_banner_text'), + FieldPanel('bottom_banner_url'), + FieldPanel('bottom_banner_url_text'), + ]), + ] + + class IndividualProgramPage(Page): def get_context(self, request): context = super().get_context(request) @@ -40,6 +83,10 @@ def get_context(self, request): context['projects'] = projects return context + parent_page_type = [ + 'programs.ProgramOwnerPage' + ] + subtitle = RichTextField(blank=True) header_image = models.ForeignKey( "wagtailimages.Image", @@ -61,30 +108,16 @@ def get_context(self, request): help_text="Intro image" ) - stats_title = models.CharField(default="Stats") stats = StreamField(ProgramStatBlock(), use_json_field=True, null=True, blank=True) - goals_title = models.CharField(default="Goals") goals = StreamField(ProgramGoalBlock(), use_json_field=True, null=True, blank=True) - projects_title = models.CharField(default="Projects") - - partners_title = models.CharField(default="Meet Our Partners") - view_all_partners_title = models.CharField(default="View All Partners") - view_all_partners_link = models.CharField(blank=True) partners = ParentalManyToManyField('core.Partner', blank=True) - more_programs_title = models.CharField(default="More Programs") - view_all_programs_title = models.CharField(default="View All Programs") - view_all_programs_link = models.URLField(blank=True) more_programs = StreamField([ ('program_page', PageChooserBlock(page_type="programs.IndividualProgramPage")) ], use_json_field=True, null=True, blank=True) - bottom_banner_text = models.CharField(default="Check out the many opportunities to get involved with HOT!") - bottom_banner_url = models.URLField(blank=True) - bottom_banner_url_text = models.CharField(default="Get Involved with HOT") - content_panels = Page.content_panels + [ MultiFieldPanel([ FieldPanel("subtitle"), @@ -96,31 +129,15 @@ def get_context(self, request): FieldPanel("intro_image"), ], heading="Intro"), MultiFieldPanel([ - FieldPanel("stats_title"), FieldPanel("stats"), ], heading="Stats"), MultiFieldPanel([ - FieldPanel("goals_title"), FieldPanel("goals"), ], heading="Goals"), MultiFieldPanel([ - FieldPanel("projects_title"), - ], heading="Projects"), - MultiFieldPanel([ - FieldPanel("partners_title"), - FieldPanel("view_all_partners_title"), - FieldPanel("view_all_partners_link"), FieldPanel("partners", widget=forms.CheckboxSelectMultiple), ], heading="Partners"), MultiFieldPanel([ - FieldPanel("more_programs_title"), - FieldPanel("view_all_programs_title"), - FieldPanel("view_all_programs_link"), FieldPanel("more_programs"), ], heading="Programs"), - MultiFieldPanel([ - FieldPanel('bottom_banner_text'), - FieldPanel('bottom_banner_url'), - FieldPanel('bottom_banner_url_text'), - ]) ] diff --git a/app/programs/templates/programs/individual_program_page.html b/app/programs/templates/programs/individual_program_page.html index 8902f0a..469a6a4 100644 --- a/app/programs/templates/programs/individual_program_page.html +++ b/app/programs/templates/programs/individual_program_page.html @@ -24,7 +24,7 @@

- {{ page.stats_title }} + {{ page.get_parent.specific.stats_title }}

{% for stat in page.stats %} @@ -42,7 +42,7 @@

- {{ page.goals_title }} + {{ page.get_parent.specific.goals_title }}


@@ -60,7 +60,7 @@

- {{ page.projects_title }} + {{ page.get_parent.specific.projects_title }}


@@ -75,13 +75,13 @@

- {{ page.partners_title }} + {{ page.get_parent.specific.partners_title }}


- {% include "ui/components/BaseLink.html" with linkurl=page.view_all_partners_link linktext=page.view_all_partners_title %} + {% include "ui/components/BaseLink.html" with linkurl=page.get_parent.specific.view_all_partners_link linktext=page.get_parent.specific.view_all_partners_title %}
@@ -92,11 +92,11 @@

- {{ page.more_programs_title }} + {{ page.get_parent.specific.more_programs_title }}

- {% include "ui/components/BaseLink.html" with linkurl=page.view_all_programs_link linktext=page.view_all_programs_title %} + {% include "ui/components/BaseLink.html" with linkurl=page.get_parent.specific.view_all_programs_link linktext=page.get_parent.specific.view_all_programs_title %}
@@ -106,5 +106,5 @@

- {% include "ui/components/FooterBannerWithTextAndLink.html" with text=page.bottom_banner_text buttontext=page.bottom_banner_url_text url=page.bottom_banner_url %} + {% include "ui/components/FooterBannerWithTextAndLink.html" with text=page.get_parent.specific.bottom_banner_text buttontext=page.get_parent.specific.bottom_banner_url_text url=page.get_parent.specific.bottom_banner_url %} {% endblock %} diff --git a/app/projects/migrations/0015_remove_individualprojectpage_partners_and_more.py b/app/projects/migrations/0015_remove_individualprojectpage_partners_and_more.py new file mode 100644 index 0000000..2c0e8f5 --- /dev/null +++ b/app/projects/migrations/0015_remove_individualprojectpage_partners_and_more.py @@ -0,0 +1,24 @@ +# Generated by Django 4.2.7 on 2024-06-03 21:40 + +from django.db import migrations +import modelcluster.fields + + +class Migration(migrations.Migration): + + dependencies = [ + ('core', '0002_alter_partner_partner_logo_alter_partner_partner_url'), + ('projects', '0014_alter_individualprojectpage_description'), + ] + + operations = [ + migrations.RemoveField( + model_name='individualprojectpage', + name='partners', + ), + migrations.AddField( + model_name='individualprojectpage', + name='partners_list', + field=modelcluster.fields.ParentalManyToManyField(blank=True, to='core.partner'), + ), + ] diff --git a/app/projects/migrations/0016_individualprojectpage_project_contributors.py b/app/projects/migrations/0016_individualprojectpage_project_contributors.py new file mode 100644 index 0000000..ea8aa0e --- /dev/null +++ b/app/projects/migrations/0016_individualprojectpage_project_contributors.py @@ -0,0 +1,20 @@ +# Generated by Django 4.2.7 on 2024-06-04 16:57 + +from django.db import migrations +import wagtail.blocks +import wagtail.fields + + +class Migration(migrations.Migration): + + dependencies = [ + ('projects', '0015_remove_individualprojectpage_partners_and_more'), + ] + + operations = [ + migrations.AddField( + model_name='individualprojectpage', + name='project_contributors', + field=wagtail.fields.StreamField([('project', wagtail.blocks.PageChooserBlock(page_type=['members.IndividualMemberPage']))], blank=True, null=True, use_json_field=True), + ), + ] diff --git a/app/projects/migrations/0017_alter_individualprojectpage_project_contributors.py b/app/projects/migrations/0017_alter_individualprojectpage_project_contributors.py new file mode 100644 index 0000000..7abd609 --- /dev/null +++ b/app/projects/migrations/0017_alter_individualprojectpage_project_contributors.py @@ -0,0 +1,20 @@ +# Generated by Django 4.2.7 on 2024-06-04 17:21 + +from django.db import migrations +import wagtail.blocks +import wagtail.fields + + +class Migration(migrations.Migration): + + dependencies = [ + ('projects', '0016_individualprojectpage_project_contributors'), + ] + + operations = [ + migrations.AlterField( + model_name='individualprojectpage', + name='project_contributors', + field=wagtail.fields.StreamField([('contributor', wagtail.blocks.PageChooserBlock(page_type=['members.IndividualMemberPage']))], blank=True, null=True, use_json_field=True), + ), + ] diff --git a/app/projects/migrations/0018_projectownerpage.py b/app/projects/migrations/0018_projectownerpage.py new file mode 100644 index 0000000..00330cc --- /dev/null +++ b/app/projects/migrations/0018_projectownerpage.py @@ -0,0 +1,41 @@ +# Generated by Django 4.2.7 on 2024-06-04 22:36 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('wagtailcore', '0089_log_entry_data_json_null_to_object'), + ('projects', '0017_alter_individualprojectpage_project_contributors'), + ] + + operations = [ + migrations.CreateModel( + name='ProjectOwnerPage', + fields=[ + ('page_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='wagtailcore.page')), + ('impact_areas_title', models.CharField(default='Impact Areas')), + ('region_hub_title', models.CharField(default='Region Hub')), + ('duration_title', models.CharField(default='Duration')), + ('partners_title', models.CharField(default='Partners')), + ('tools_title', models.CharField(default='Tools')), + ('contact_title', models.CharField(default='Contact')), + ('related_news_title', models.CharField(default='Related News')), + ('view_all_news_text', models.CharField(default='View all News')), + ('related_events_title', models.CharField(default='Related Events')), + ('view_all_events_text', models.CharField(default='View all Events')), + ('red_box_title', models.CharField(default='Chat with Our Community')), + ('red_box_link_text', models.CharField(default='Get connected now')), + ('red_box_link_url', models.URLField(blank=True, null=True)), + ('black_box_title', models.CharField(default='Our Work')), + ('black_box_link_text', models.CharField(default='View Our Work')), + ('black_box_link_url', models.URLField(blank=True, null=True)), + ], + options={ + 'abstract': False, + }, + bases=('wagtailcore.page',), + ), + ] diff --git a/app/projects/migrations/0019_projectownerpage_view_all_events_url_and_more.py b/app/projects/migrations/0019_projectownerpage_view_all_events_url_and_more.py new file mode 100644 index 0000000..5072356 --- /dev/null +++ b/app/projects/migrations/0019_projectownerpage_view_all_events_url_and_more.py @@ -0,0 +1,23 @@ +# Generated by Django 4.2.7 on 2024-06-04 22:43 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('projects', '0018_projectownerpage'), + ] + + operations = [ + migrations.AddField( + model_name='projectownerpage', + name='view_all_events_url', + field=models.URLField(blank=True), + ), + migrations.AddField( + model_name='projectownerpage', + name='view_all_news_url', + field=models.URLField(blank=True), + ), + ] diff --git a/app/projects/migrations/0020_remove_individualprojectpage_black_box_link_text_and_more.py b/app/projects/migrations/0020_remove_individualprojectpage_black_box_link_text_and_more.py new file mode 100644 index 0000000..f8cfd4f --- /dev/null +++ b/app/projects/migrations/0020_remove_individualprojectpage_black_box_link_text_and_more.py @@ -0,0 +1,77 @@ +# Generated by Django 4.2.7 on 2024-06-04 22:45 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('projects', '0019_projectownerpage_view_all_events_url_and_more'), + ] + + operations = [ + migrations.RemoveField( + model_name='individualprojectpage', + name='black_box_link_text', + ), + migrations.RemoveField( + model_name='individualprojectpage', + name='black_box_link_url', + ), + migrations.RemoveField( + model_name='individualprojectpage', + name='black_box_title', + ), + migrations.RemoveField( + model_name='individualprojectpage', + name='contact_title', + ), + migrations.RemoveField( + model_name='individualprojectpage', + name='duration_title', + ), + migrations.RemoveField( + model_name='individualprojectpage', + name='impact_areas_title', + ), + migrations.RemoveField( + model_name='individualprojectpage', + name='partners_title', + ), + migrations.RemoveField( + model_name='individualprojectpage', + name='red_box_link_text', + ), + migrations.RemoveField( + model_name='individualprojectpage', + name='red_box_link_url', + ), + migrations.RemoveField( + model_name='individualprojectpage', + name='red_box_title', + ), + migrations.RemoveField( + model_name='individualprojectpage', + name='region_hub_title', + ), + migrations.RemoveField( + model_name='individualprojectpage', + name='related_events_title', + ), + migrations.RemoveField( + model_name='individualprojectpage', + name='related_news_title', + ), + migrations.RemoveField( + model_name='individualprojectpage', + name='tools_title', + ), + migrations.RemoveField( + model_name='individualprojectpage', + name='view_all_events_text', + ), + migrations.RemoveField( + model_name='individualprojectpage', + name='view_all_news_text', + ), + ] diff --git a/app/projects/models.py b/app/projects/models.py index 183da20..8631672 100644 --- a/app/projects/models.py +++ b/app/projects/models.py @@ -1,12 +1,74 @@ +from django import forms from django.db import models from wagtail.models import Page from wagtail.fields import RichTextField, StreamField from wagtail.admin.panels import FieldPanel, MultiFieldPanel, PageChooserPanel from wagtail.blocks import CharBlock, StreamBlock, StructBlock, URLBlock, RichTextBlock, PageChooserBlock +from modelcluster.fields import ParentalKey, ParentalManyToManyField +class ProjectOwnerPage(Page): + max_count = 1 + + impact_areas_title = models.CharField(default="Impact Areas") + region_hub_title = models.CharField(default="Region Hub") + duration_title = models.CharField(default="Duration") + partners_title = models.CharField(default="Partners") + tools_title = models.CharField(default="Tools") + contact_title = models.CharField(default="Contact") + + related_news_title = models.CharField(default="Related News") + view_all_news_text = models.CharField(default="View all News") + view_all_news_url = models.URLField(blank=True) + related_events_title = models.CharField(default="Related Events") + view_all_events_text = models.CharField(default="View all Events") + view_all_events_url = models.URLField(blank=True) + + red_box_title = models.CharField(default="Chat with Our Community") + red_box_link_text = models.CharField(default="Get connected now") + red_box_link_url = models.URLField(null=True, blank=True) + black_box_title = models.CharField(default="Our Work") + black_box_link_text = models.CharField(default="View Our Work") + black_box_link_url = models.URLField(null=True, blank=True) + + content_panels = Page.content_panels + [ + MultiFieldPanel([ + FieldPanel('impact_areas_title'), + FieldPanel('region_hub_title'), + FieldPanel('duration_title'), + FieldPanel('partners_title'), + FieldPanel('tools_title'), + FieldPanel('contact_title'), + MultiFieldPanel([ + FieldPanel('related_news_title'), + FieldPanel('view_all_news_text'), + FieldPanel('view_all_news_url'), + FieldPanel('related_events_title'), + FieldPanel('view_all_events_text'), + FieldPanel('view_all_events_url'), + ], heading="Related Pages"), + ], heading="Sidebar"), + MultiFieldPanel([ + FieldPanel('red_box_title'), + FieldPanel('red_box_link_text'), + FieldPanel('red_box_link_url'), + FieldPanel('black_box_title'), + FieldPanel('black_box_link_text'), + FieldPanel('black_box_link_url'), + ], heading="Footer"), + ] + + +""" +This page should only be created as a child of a ProjectOwnerPage! +Its template depends on fields from the ProjectOwnerPage in order +to create one unifying place where unchanging fields may be modified. +""" class IndividualProjectPage(Page): + parent_page_type = [ + 'projects.ProjectOwnerPage' + ] # > HEADER owner_program = models.ForeignKey( 'wagtailcore.Page', @@ -39,10 +101,8 @@ class IndividualProjectPage(Page): call_to_action_link_url = models.URLField(null=True, blank=True) # > SIDE BAR - impact_areas_title = models.CharField(default="Impact Areas") impact_area_list = StreamField([('impact_area', PageChooserBlock(page_type="impact_areas.IndividualImpactAreaPage"))], use_json_field=True, null=True, blank=True) - region_hub_title = models.CharField(default="Region Hub") owner_region_hub = models.ForeignKey( 'wagtailcore.Page', null=True, @@ -51,35 +111,19 @@ class IndividualProjectPage(Page): related_name='+' ) - duration_title = models.CharField(default="Duration") duration = models.CharField(default="Ongoing", blank=True) - partners_title = models.CharField(default="Partners") - partners = RichTextField(null=True, blank=True) # Will need to reference partners when they are added + partners_list = ParentalManyToManyField('core.Partner', blank=True) - tools_title = models.CharField(default="Tools") tools = RichTextField(null=True, blank=True) # Will need to reference tools when they are added - contact_title = models.CharField(default="Contact") contact = RichTextField(null=True, blank=True) - # Question: are related news/events chosen for the article, or are they based off something? - related_news_title = models.CharField(default="Related News") - view_all_news_text = models.CharField(default="View all News") related_news = StreamField([ ('news_page', PageChooserBlock(page_type="news.IndividualNewsPage")) ], use_json_field=True, null=True, blank=True) - related_events_title = models.CharField(default="Related Events") - view_all_events_text = models.CharField(default="View all Events") - - # > BOTTOM AREA - red_box_title = models.CharField(default="Chat with Our Community") - red_box_link_text = models.CharField(default="Get connected now") - red_box_link_url = models.URLField(null=True, blank=True) - black_box_title = models.CharField(default="Our Work") - black_box_link_text = models.CharField(default="View Our Work") - black_box_link_url = models.URLField(null=True, blank=True) + project_contributors = StreamField([('contributor', PageChooserBlock(page_type="members.IndividualMemberPage"))], use_json_field=True, null=True, blank=True) content_panels = Page.content_panels + [ MultiFieldPanel([ @@ -98,32 +142,17 @@ class IndividualProjectPage(Page): ], heading="Call to Action"), ], heading="Body"), MultiFieldPanel([ - FieldPanel('impact_areas_title'), FieldPanel('impact_area_list'), - FieldPanel('region_hub_title'), PageChooserPanel('owner_region_hub', 'mapping_hubs.IndividualMappingHubPage'), - FieldPanel('duration_title'), FieldPanel('duration'), - FieldPanel('partners_title'), - FieldPanel('partners'), - FieldPanel('tools_title'), + FieldPanel('partners_list', widget=forms.CheckboxSelectMultiple), FieldPanel('tools'), - FieldPanel('contact_title'), FieldPanel('contact'), MultiFieldPanel([ - FieldPanel('related_news_title'), - FieldPanel('view_all_news_text'), FieldPanel('related_news'), - FieldPanel('related_events_title'), - FieldPanel('view_all_events_text'), ], heading="Related Pages"), ], heading="Sidebar"), MultiFieldPanel([ - FieldPanel('red_box_title'), - FieldPanel('red_box_link_text'), - FieldPanel('red_box_link_url'), - FieldPanel('black_box_title'), - FieldPanel('black_box_link_text'), - FieldPanel('black_box_link_url'), - ], heading="Bottom"), + FieldPanel('project_contributors'), + ], heading="Extras") ] \ No newline at end of file diff --git a/app/projects/templates/projects/individual_project_page.html b/app/projects/templates/projects/individual_project_page.html index 0bcc47c..85ff86f 100644 --- a/app/projects/templates/projects/individual_project_page.html +++ b/app/projects/templates/projects/individual_project_page.html @@ -14,7 +14,6 @@
- {% comment %} BODY {% endcomment %}
@@ -31,52 +30,62 @@ {% comment %} NOTE TO SELF: the "safe" thing is only needed temporarily until everything is put in {% endcomment %}
-

{{page.impact_areas_title}}

-

{{page.impact_areas|safe}}

+

{{page.get_parent.specific.impact_areas_title}}

+ {% for area in page.impact_area_list %} +

{{area.value.title}}

+ {% endfor %}
-

{{page.region_hub_title}}

+

{{page.get_parent.specific.region_hub_title}}

{{page.owner_region_hub.title}}

-

{{page.duration_title}}

+

{{page.get_parent.specific.duration_title}}

{{page.duration}}

-

{{page.partners_title}}

-

{{page.partners|safe}}

+

{{page.get_parent.specific.partners_title}}

+ {% for partner in page.partners_list.all %} +

{{partner.partner_name}}

+ {% endfor %}
-

{{page.tools_title}}

+

{{page.get_parent.specific.tools_title}}

{{page.tools|safe}}

-

{{page.contact_title}}

+

{{page.get_parent.specific.contact_title}}

{{page.contact|safe}}

+ {% comment %} RELATED NEWS {% endcomment %} {% if page.related_news %} -
-

- {{ page.related_news_title }} -

- {% include "ui/components/BaseLink.html" with linkurl="#" linktext=page.view_all_news_text %} -
- {% with allnews=page.related_news %} - {% for news in allnews %} - {% include "ui/components/news/NewsPreviewBlockProjects.html" with news=news.value %} - {% endfor %} - {% endwith %} +
+

+ {{ page.get_parent.specific.related_news_title }} +

+
+ {% include "ui/components/BaseLink.html" with linkurl=page.get_parent.specific.view_all_news_url linktext=page.get_parent.specific.view_all_news_text %} +
+
+ {% with allnews=page.related_news %} + {% for news in allnews %} + {% include "ui/components/news/NewsPreviewBlockProjects.html" with news=news.value %} + {% endfor %} + {% endwith %} +
-
{% endif %} + {% comment %} RELATED EVENTS {% endcomment %}

- {{ page.related_events_title }} + {{ page.get_parent.specific.related_events_title }}

- {% include "ui/components/BaseLink.html" with linkurl="#" linktext=page.view_all_events_text %} +
+ {% include "ui/components/BaseLink.html" with linkurl=page.get_parent.specific.view_all_events_url linktext=page.get_parent.specific.view_all_events_text %} +
@@ -84,10 +93,10 @@

{% comment %} BOTTOM AREA {% endcomment %}
- {% include "ui/components/dogear_boxes/DogearRed.html" with title=page.red_box_title linktext=page.red_box_link_text linkurl=page.red_box_link_url %} + {% include "ui/components/dogear_boxes/DogearRed.html" with title=page.get_parent.specific.red_box_title linktext=page.get_parent.specific.red_box_link_text linkurl=page.get_parent.specific.red_box_link_url %}
- {% include "ui/components/dogear_boxes/DogearBlack.html" with title=page.black_box_title linktext=page.black_box_link_text linkurl=page.black_box_link_url %} + {% include "ui/components/dogear_boxes/DogearBlack.html" with title=page.get_parent.specific.black_box_title linktext=page.get_parent.specific.black_box_link_text linkurl=page.get_parent.specific.black_box_link_url %}

diff --git a/app/ui/templates/ui/components/news/NewsPreviewCarousel.html b/app/ui/templates/ui/components/news/NewsPreviewCarousel.html new file mode 100644 index 0000000..70da95e --- /dev/null +++ b/app/ui/templates/ui/components/news/NewsPreviewCarousel.html @@ -0,0 +1,61 @@ +{% load wagtailimages_tags %} +
+
+ {% if title %} +
+

+ {{title}} +

+
+ {% endif %} + +
+ +
+ {% for article in news %} +
+ {% if article.value %} + {% include "ui/components/news/NewsPreviewBlockNews.html" with news=article.value %} + {% else %} + {% include "ui/components/news/NewsPreviewBlockNews.html" with news=article %} + {% endif %} +
+ {% endfor %} +
+ +
+
+
+ {% include "ui/components/icon_svgs/LinkCaret.html" with class="rotate-180" %} +
+
+
+
+ {% include "ui/components/icon_svgs/LinkCaret.html" %} +
+
+
+
\ No newline at end of file diff --git a/app/ui/templates/ui/components/partners/PartnerViewBlock.html b/app/ui/templates/ui/components/partners/PartnerViewBlock.html index 3a59874..ea655b6 100644 --- a/app/ui/templates/ui/components/partners/PartnerViewBlock.html +++ b/app/ui/templates/ui/components/partners/PartnerViewBlock.html @@ -17,9 +17,12 @@
{% for partner in partners %} -
{% image partner.partner_logo original class="max-h-16 max-w-24 h-auto w-auto" %}
diff --git a/app/ui/templates/ui/components/programs/ProgramCarouselBlock.html b/app/ui/templates/ui/components/programs/ProgramCarouselBlock.html index d4f6d9c..a9fca4d 100644 --- a/app/ui/templates/ui/components/programs/ProgramCarouselBlock.html +++ b/app/ui/templates/ui/components/programs/ProgramCarouselBlock.html @@ -15,9 +15,11 @@
{% for program in programs %} -
{% include "ui/components/programs/ProgramPreviewBlockBase.html" with program=program.value %}
diff --git a/app/ui/templates/ui/components/projects/ProjectPreviewBlockNews.html b/app/ui/templates/ui/components/projects/ProjectPreviewBlockNews.html index b9a801a..222ffed 100644 --- a/app/ui/templates/ui/components/projects/ProjectPreviewBlockNews.html +++ b/app/ui/templates/ui/components/projects/ProjectPreviewBlockNews.html @@ -31,9 +31,9 @@
{% for area in project.impact_area_list %} - -

{{ area.value.title }}{% if not forloop.last %},{% endif %}

-
+

+ {{ area.value.title }}{% if not forloop.last %},{% endif %} +

{% endfor %}
\ No newline at end of file diff --git a/app/ui/templates/ui/components/projects/ProjectPreviewCarousel.html b/app/ui/templates/ui/components/projects/ProjectPreviewCarousel.html new file mode 100644 index 0000000..05ac3cd --- /dev/null +++ b/app/ui/templates/ui/components/projects/ProjectPreviewCarousel.html @@ -0,0 +1,61 @@ +{% load wagtailimages_tags %} +
+
+ {% if title %} +
+

+ {{title}} +

+
+ {% endif %} + +
+ +
+ {% for project in projects %} +
+ {% if project.value %} + {% include "ui/components/projects/ProjectPreviewBlockNews.html" with project=project.value %} + {% else %} + {% include "ui/components/projects/ProjectPreviewBlockNews.html" with project=project %} + {% endif %} +
+ {% endfor %} +
+ +
+
+
+ {% include "ui/components/icon_svgs/LinkCaret.html" with class="rotate-180" %} +
+
+
+
+ {% include "ui/components/icon_svgs/LinkCaret.html" %} +
+
+
+
\ No newline at end of file diff --git a/hot_osm/locale/en/LC_MESSAGES/django.po b/hot_osm/locale/en/LC_MESSAGES/django.po index 2d6b726..2e28bdc 100644 --- a/hot_osm/locale/en/LC_MESSAGES/django.po +++ b/hot_osm/locale/en/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-05-23 19:32+0000\n" +"POT-Creation-Date: 2024-06-03 23:08+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/hot_osm/locale/es/LC_MESSAGES/django.po b/hot_osm/locale/es/LC_MESSAGES/django.po index 46bf7f9..b37f0f5 100644 --- a/hot_osm/locale/es/LC_MESSAGES/django.po +++ b/hot_osm/locale/es/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-05-23 19:32+0000\n" +"POT-Creation-Date: 2024-06-03 23:08+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/hot_osm/locale/fr/LC_MESSAGES/django.po b/hot_osm/locale/fr/LC_MESSAGES/django.po index 6715543..bd8581f 100644 --- a/hot_osm/locale/fr/LC_MESSAGES/django.po +++ b/hot_osm/locale/fr/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-05-23 19:32+0000\n" +"POT-Creation-Date: 2024-06-03 23:08+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/hot_osm/settings/base.py b/hot_osm/settings/base.py index 911dcec..076eac0 100644 --- a/hot_osm/settings/base.py +++ b/hot_osm/settings/base.py @@ -36,6 +36,7 @@ "app.programs", "app.core", "app.mapping_hubs", + "app.members", "search", "users", "utils", diff --git a/media/images/temp_person.max-165x165.png b/media/images/temp_person.max-165x165.png new file mode 100644 index 0000000..645d555 Binary files /dev/null and b/media/images/temp_person.max-165x165.png differ diff --git a/media/images/temp_person.original.png b/media/images/temp_person.original.png new file mode 100644 index 0000000..207db68 Binary files /dev/null and b/media/images/temp_person.original.png differ diff --git a/media/original_images/temp_person.png b/media/original_images/temp_person.png new file mode 100644 index 0000000..dc259af Binary files /dev/null and b/media/original_images/temp_person.png differ