@@ -58,7 +58,7 @@
hx-select-oob="#projects-list:beforeend, #next-project:outerHTML"
>
{% 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 %}
+ {% 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 %}
+
+
+
+ {% include "ui/components/icon_svgs/LinkCaret.html" with class="rotate-180" %}
+
+
+
+
+ {% include "ui/components/icon_svgs/LinkCaret.html" %}
+
+
+
+
+
+
+ {% 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 %}
+
+
+
+ {% include "ui/components/icon_svgs/LinkCaret.html" with class="rotate-180" %}
+
+
+
+
+ {% include "ui/components/icon_svgs/LinkCaret.html" %}
+
+
+
+
+
+
+ {% 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 0000000000000000000000000000000000000000..645d555e4d4a4620a6efb7b523e9520a0972a01f
GIT binary patch
literal 4709
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
literal 0
HcmV?d00001
diff --git a/media/original_images/temp_person.png b/media/original_images/temp_person.png
new file mode 100644
index 0000000000000000000000000000000000000000..dc259af999517cc5dbc1b503db08a7cacf94d331
GIT binary patch
literal 2527
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
literal 0
HcmV?d00001