+ {% include "ui/components/sections/BaseSectionWithImage.html" with title=page.partner_with_us_title image=page.partner_with_us_image imageright=True title_underline=True red_button=True button_text=page.partner_with_us_button_text button_link=page.partner_with_us_button_link description=page.partner_with_us_description imagenotwide=True imagebottom=True%}
+
+
+
+
+
+ {% include "ui/components/TitleWithUnderline.html" with title=page.get_involved_community_title %}
+
+ {% for panel in page.get_involved_large_panels %}
+ {% include "ui/components/misc_panels/LinkBlockWithImage.html" with title=panel.value.title image=panel.value.image description=panel.value.description linktext=panel.value.link_text linkurl=panel.value.link_url %}
+ {% endfor %}
+
+
+
+ {% include "ui/components/dogear_boxes/DogearAnyColourLong.html" with title=page.dogear_box_title linktext=page.dogear_box_link_text linkurl=page.dogear_box_link_url textcolour="black" colour="var(--hot-light-grey)" arrowcolour="black" %}
+
+
+ {% include "ui/components/FlexTitleWithLink.html" with title=page.events_title linktext=page.view_all_events_text linkurl=page.view_all_events_link class="my-4" %}
+
+ {% for event in page.events %}
+ {% include "ui/components/events/EventPreviewBlockEvent.html" with event=event.value showimage=True %}
+ {% endfor %}
+
+
+
+
+
+
+
+ {% include "ui/components/TitleWithUnderline.html" with title=page.join_us_title %}
+
+
+ {% for panel in page.join_us_panels %}
+ {% include "ui/components/misc_panels/PagePreviewWithTabletDescription.html" with image=panel.value.image page=panel.value.page tablet_description=panel.value.tablet_description read_more_text=page.join_us_panel_read_more %}
+ {% endfor %}
+
+
+
+
+ {% 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/DogearBlack.html" with title=page.black_box_title linktext=page.black_box_link_text linkurl=page.black_box_link_url %}
+
+
+
+
+{% endblock %}
diff --git a/app/get_involved/tests.py b/app/get_involved/tests.py
new file mode 100644
index 0000000..7ce503c
--- /dev/null
+++ b/app/get_involved/tests.py
@@ -0,0 +1,3 @@
+from django.test import TestCase
+
+# Create your tests here.
diff --git a/app/get_involved/views.py b/app/get_involved/views.py
new file mode 100644
index 0000000..91ea44a
--- /dev/null
+++ b/app/get_involved/views.py
@@ -0,0 +1,3 @@
+from django.shortcuts import render
+
+# Create your views here.
diff --git a/app/impact_areas/migrations/0015_alter_individualimpactareapage_external_icon.py b/app/impact_areas/migrations/0015_alter_individualimpactareapage_external_icon.py
new file mode 100644
index 0000000..1a9ed94
--- /dev/null
+++ b/app/impact_areas/migrations/0015_alter_individualimpactareapage_external_icon.py
@@ -0,0 +1,20 @@
+# Generated by Django 4.2.7 on 2024-06-28 23:12
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('wagtailimages', '0025_alter_image_file_alter_rendition_file'),
+ ('impact_areas', '0014_remove_individualimpactareapage_black_dogear_box_link_text_and_more'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='individualimpactareapage',
+ name='external_icon',
+ field=models.ForeignKey(blank=True, help_text='The icon representing this page which is shown for previews of this page on other pages. This should be a purely black image which is ideally as wide as it is tall.', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='wagtailimages.image'),
+ ),
+ ]
diff --git a/app/impact_areas/models.py b/app/impact_areas/models.py
index d63017a..4410a28 100644
--- a/app/impact_areas/models.py
+++ b/app/impact_areas/models.py
@@ -42,7 +42,7 @@ def get_context(self, request, *args, **kwargs):
context['other_impact_areas'] = other_impact_areas
return context
- parent_page_type = [
+ parent_page_types = [
'impact_areas.ImpactAreasPage'
]
@@ -62,7 +62,7 @@ def get_context(self, request, *args, **kwargs):
blank=True,
on_delete=models.SET_NULL,
related_name="+",
- help_text="The icon representing this page which is shown for previews of this page on other pages."
+ help_text="The icon representing this page which is shown for previews of this page on other pages. This should be a purely black image which is ideally as wide as it is tall."
)
intro_image = models.ForeignKey(
"wagtailimages.Image",
@@ -108,6 +108,10 @@ class ImpactAreaBlock(StreamBlock):
class ImpactAreasPage(Page):
max_count = 1
+ subpage_types = [
+ 'impact_areas.IndividualImpactAreaPage'
+ ]
+
intro = RichTextField(blank=True)
image = models.ForeignKey(
diff --git a/app/impact_areas/templates/impact_areas/impact_areas_page.html b/app/impact_areas/templates/impact_areas/impact_areas_page.html
index c5867f9..b406d8e 100644
--- a/app/impact_areas/templates/impact_areas/impact_areas_page.html
+++ b/app/impact_areas/templates/impact_areas/impact_areas_page.html
@@ -13,8 +13,8 @@
{% include "ui/components/BasePageHeader.html" with title=page.title intro=page.intro image=page.image %}
- {% for block in page.impact_area_blocks %}
- {% include "ui/components/LearnMoreAboutBlurbWithImage.html" with title=block.value.title description=block.value.description image=block.value.image link=block.value.link %}
+ {% for child in page.get_children %}
+ {% include "ui/components/impact_areas/ImpactAreaPreviewBlock.html" with ia=child.specific %}
{% endfor %}
{% endblock %}
\ No newline at end of file
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 3a971b0..6ed0220 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
@@ -43,7 +43,7 @@
{% include "ui/components/BaseLink.html" with linktext=page.get_parent.specific.view_all_projects_text linkurl=page.view_all_projects_link %}
-
+
{% for project in projects %}
{% include "ui/components/projects/ProjectPreviewBlockNews.html" with project=project showimage=True %}
{% endfor %}
diff --git a/app/mapping_hubs/migrations/0009_openmappinghubspage.py b/app/mapping_hubs/migrations/0009_openmappinghubspage.py
new file mode 100644
index 0000000..0da2ebf
--- /dev/null
+++ b/app/mapping_hubs/migrations/0009_openmappinghubspage.py
@@ -0,0 +1,27 @@
+# Generated by Django 4.2.7 on 2024-07-02 18:58
+
+from django.db import migrations, models
+import django.db.models.deletion
+import wagtail.fields
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('wagtailcore', '0089_log_entry_data_json_null_to_object'),
+ ('mapping_hubs', '0008_alter_individualmappinghubpage_dogear_boxes'),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='OpenMappingHubsPage',
+ 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')),
+ ('banner_description', wagtail.fields.RichTextField(blank=True)),
+ ],
+ options={
+ 'abstract': False,
+ },
+ bases=('wagtailcore.page',),
+ ),
+ ]
diff --git a/app/mapping_hubs/migrations/0010_rename_banner_description_openmappinghubspage_header_description_and_more.py b/app/mapping_hubs/migrations/0010_rename_banner_description_openmappinghubspage_header_description_and_more.py
new file mode 100644
index 0000000..765e9f6
--- /dev/null
+++ b/app/mapping_hubs/migrations/0010_rename_banner_description_openmappinghubspage_header_description_and_more.py
@@ -0,0 +1,25 @@
+# Generated by Django 4.2.7 on 2024-07-02 19:10
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('wagtailimages', '0025_alter_image_file_alter_rendition_file'),
+ ('mapping_hubs', '0009_openmappinghubspage'),
+ ]
+
+ operations = [
+ migrations.RenameField(
+ model_name='openmappinghubspage',
+ old_name='banner_description',
+ new_name='header_description',
+ ),
+ migrations.AddField(
+ model_name='openmappinghubspage',
+ name='header_image',
+ field=models.ForeignKey(blank=True, help_text='Header image', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='wagtailimages.image'),
+ ),
+ ]
diff --git a/app/mapping_hubs/migrations/0011_openmappinghubspage_hub_text_and_more.py b/app/mapping_hubs/migrations/0011_openmappinghubspage_hub_text_and_more.py
new file mode 100644
index 0000000..d70c35b
--- /dev/null
+++ b/app/mapping_hubs/migrations/0011_openmappinghubspage_hub_text_and_more.py
@@ -0,0 +1,23 @@
+# Generated by Django 4.2.7 on 2024-07-02 21:10
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('mapping_hubs', '0010_rename_banner_description_openmappinghubspage_header_description_and_more'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='openmappinghubspage',
+ name='hub_text',
+ field=models.CharField(default='Hub', help_text="The text following a hub's name; i.e., if this field is 'Hub', the title for 'Asia-Pacific' would become 'Asia-Pacific Hub'."),
+ ),
+ migrations.AddField(
+ model_name='openmappinghubspage',
+ name='learn_more_text',
+ field=models.CharField(default='Learn More about', help_text="The text preceeding the hub's name in the link text; i.e., if this field is 'Learn More about', the link text for 'Asia-Pacific Hub' would become 'Learn More about Asia-Pacific Hub'."),
+ ),
+ ]
diff --git a/app/mapping_hubs/migrations/0012_mappinghubprojectspage.py b/app/mapping_hubs/migrations/0012_mappinghubprojectspage.py
new file mode 100644
index 0000000..fca3cc1
--- /dev/null
+++ b/app/mapping_hubs/migrations/0012_mappinghubprojectspage.py
@@ -0,0 +1,33 @@
+# Generated by Django 4.2.7 on 2024-07-04 22:41
+
+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'),
+ ('mapping_hubs', '0011_openmappinghubspage_hub_text_and_more'),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='MappingHubProjectsPage',
+ 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')),
+ ('load_more_projects_text', models.CharField(default='Load More Projects')),
+ ('projects_by_hub_title', models.CharField(default='See Projects by Open Mapping Hub')),
+ ('red_box_title', models.CharField(default='Start Mapping')),
+ ('red_box_link_text', models.CharField(default='Start Mapping')),
+ ('red_box_link_url', models.URLField(blank=True, null=True)),
+ ('black_box_title', models.CharField(default='Check many opportunities to get involved with HOT!')),
+ ('black_box_link_text', models.CharField(default='Get Involved with HOT')),
+ ('black_box_link_url', models.URLField(blank=True, null=True)),
+ ],
+ options={
+ 'abstract': False,
+ },
+ bases=('wagtailcore.page',),
+ ),
+ ]
diff --git a/app/mapping_hubs/migrations/0013_alter_mappinghubprojectspage_black_box_link_text_and_more.py b/app/mapping_hubs/migrations/0013_alter_mappinghubprojectspage_black_box_link_text_and_more.py
new file mode 100644
index 0000000..929575f
--- /dev/null
+++ b/app/mapping_hubs/migrations/0013_alter_mappinghubprojectspage_black_box_link_text_and_more.py
@@ -0,0 +1,33 @@
+# Generated by Django 4.2.7 on 2024-07-04 23:02
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('mapping_hubs', '0012_mappinghubprojectspage'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='mappinghubprojectspage',
+ name='black_box_link_text',
+ field=models.CharField(default='Get involved'),
+ ),
+ migrations.AlterField(
+ model_name='mappinghubprojectspage',
+ name='black_box_title',
+ field=models.CharField(default='See the many ways to get involved with HOT and open mapping'),
+ ),
+ migrations.AlterField(
+ model_name='mappinghubprojectspage',
+ name='red_box_link_text',
+ field=models.CharField(default='Explore projects'),
+ ),
+ migrations.AlterField(
+ model_name='mappinghubprojectspage',
+ name='red_box_title',
+ field=models.CharField(default="See all of HOT's projects"),
+ ),
+ ]
diff --git a/app/mapping_hubs/models.py b/app/mapping_hubs/models.py
index b2e6256..1f79b86 100644
--- a/app/mapping_hubs/models.py
+++ b/app/mapping_hubs/models.py
@@ -1,5 +1,6 @@
from django import forms
from django.db import models
+from django.db.models import Q
from wagtail.models import Page
from wagtail.fields import RichTextField, StreamField
@@ -30,10 +31,82 @@ class DogearBoxBlock(StreamBlock):
blocks = DogearBoxStructBlock()
+class MappingHubProjectsPage(Page):
+ def get_context(self, request):
+ context = super().get_context(request)
+
+ parent_hub = context['page'].get_parent()
+
+ projects = IndividualProjectPage.objects.live().filter(
+ Q(region_hub_list__contains=[{'type': 'region_hub', 'value': parent_hub.id}])
+ ).filter(locale=context['page'].locale)
+
+ other_hubs_projects = MappingHubProjectsPage.objects.live().filter(locale=context['page'].locale)
+
+ context['projects'] = projects
+ context['other_hubs'] = other_hubs_projects
+ return context
+
+ parent_page_types = [
+ 'mapping_hubs.IndividualMappingHubPage'
+ ]
+
+ load_more_projects_text = models.CharField(default="Load More Projects")
+
+ projects_by_hub_title = models.CharField(default="See Projects by Open Mapping Hub")
+
+ red_box_title = models.CharField(default="See all of HOT's projects")
+ red_box_link_text = models.CharField(default="Explore projects")
+ red_box_link_url = models.URLField(null=True, blank=True)
+ black_box_title = models.CharField(default="See the many ways to get involved with HOT and open mapping")
+ black_box_link_text = models.CharField(default="Get involved")
+ black_box_link_url = models.URLField(null=True, blank=True)
+
+ content_panels = Page.content_panels + [
+ FieldPanel('load_more_projects_text'),
+ FieldPanel('projects_by_hub_title'),
+ 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'),
+ ]
+
+
+class OpenMappingHubsPage(Page):
+ max_count = 1
+
+ subpage_types = [
+ 'mapping_hubs.IndividualMappingHubPage'
+ ]
+
+ header_image = models.ForeignKey(
+ "wagtailimages.Image",
+ null=True,
+ blank=True,
+ on_delete=models.SET_NULL,
+ related_name="+",
+ help_text="Header image",
+ )
+ header_description = RichTextField(blank=True)
+ hub_text = models.CharField(default="Hub", help_text="The text following a hub's name; i.e., if this field is 'Hub', the title for 'Asia-Pacific' would become 'Asia-Pacific Hub'.")
+ learn_more_text = models.CharField(default="Learn More about", help_text="The text preceeding the hub's name in the link text; i.e., if this field is 'Learn More about', the link text for 'Asia-Pacific Hub' would become 'Learn More about Asia-Pacific Hub'.")
+
+ content_panels = Page.content_panels + [
+ FieldPanel('header_image'),
+ FieldPanel('header_description'),
+ FieldPanel('hub_text'),
+ FieldPanel('learn_more_text'),
+ ]
+
+
class IndividualMappingHubPage(Page):
def get_context(self, request):
context = super().get_context(request)
- projects = IndividualProjectPage.objects.filter(owner_region_hub=context['page'], locale=context['page'].locale)
+ projects = IndividualProjectPage.objects.live().filter(
+ Q(region_hub_list__contains=[{'type': 'region_hub', 'value': context['page'].id}])
+ ).filter(locale=context['page'].locale)
context['projects'] = projects
other_hubs = IndividualMappingHubPage.objects.live().filter(locale=context['page'].locale)
context['other_hubs'] = other_hubs
diff --git a/app/mapping_hubs/templates/mapping_hubs/components/projects_header.html b/app/mapping_hubs/templates/mapping_hubs/components/projects_header.html
new file mode 100644
index 0000000..72d8327
--- /dev/null
+++ b/app/mapping_hubs/templates/mapping_hubs/components/projects_header.html
@@ -0,0 +1,25 @@
+{% comment %}
+==> PARAMETERS
+- body: The content of the header
+- image: A Wagtail image
+{% endcomment %}
+
+{% load wagtailimages_tags %}
+
+{% image page.get_parent.specific.header_image original as image_p %}
+
{% for project in projects %}
- {% include "ui/components/projects/ProjectPreviewBlockMapHub.html" with project=project showimage="True" %}
+ {% include "ui/components/projects/ProjectPreviewBlockMapHub.html" with project=project.specific showimage="True" %}
{% endfor %}
+ {% for project in projects %}
+ {% include "ui/components/projects/ProjectPreviewBlockNews.html" with project=project.specific showimage=True %}
+ {% endfor %}
+
+ {% 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/DogearBlack.html" with title=page.black_box_title linktext=page.black_box_link_text linkurl=page.black_box_link_url %}
+
+ {% for child in page.get_children %}
+ {% include "ui/components/mapping_hub/MappingHubPreviewExtendedBlock.html" with hub=child.specific hub_text=page.hub_text learn_more_text=page.learn_more_text %}
+ {% endfor %}
+
+
+
+
+ {% include "home/components/CheckOutOpportunitiesSection.html" %}
+{% endblock %}
diff --git a/app/members/migrations/0003_rename_introduction_individualmemberpage_intro.py b/app/members/migrations/0003_rename_introduction_individualmemberpage_intro.py
new file mode 100644
index 0000000..3dc041a
--- /dev/null
+++ b/app/members/migrations/0003_rename_introduction_individualmemberpage_intro.py
@@ -0,0 +1,18 @@
+# Generated by Django 4.2.7 on 2024-07-08 23:24
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('members', '0002_remove_individualmemberpage_location_and_more'),
+ ]
+
+ operations = [
+ migrations.RenameField(
+ model_name='individualmemberpage',
+ old_name='introduction',
+ new_name='intro',
+ ),
+ ]
diff --git a/app/members/migrations/0004_membergroupownerpage_membergrouppage.py b/app/members/migrations/0004_membergroupownerpage_membergrouppage.py
new file mode 100644
index 0000000..9cb5a03
--- /dev/null
+++ b/app/members/migrations/0004_membergroupownerpage_membergrouppage.py
@@ -0,0 +1,52 @@
+# Generated by Django 4.2.7 on 2024-07-09 21:59
+
+import django.core.validators
+from django.db import migrations, models
+import django.db.models.deletion
+import wagtail.fields
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('wagtailcore', '0089_log_entry_data_json_null_to_object'),
+ ('wagtailimages', '0025_alter_image_file_alter_rendition_file'),
+ ('members', '0003_rename_introduction_individualmemberpage_intro'),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='MemberGroupOwnerPage',
+ 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')),
+ ('search_placeholder', models.CharField(default='Search by name')),
+ ('filter_by_country', models.CharField(default='Filter by Country')),
+ ('sort_by_titlea', models.CharField(default='Sort by Title Alphabetical')),
+ ('sort_by_titlez', models.CharField(default='Sort by Title Reverse Alphabetical')),
+ ('load_more_text', models.CharField(default='Load more', help_text="This will be a prefix to the title of the page; i.e., if the page title is 'Voting members', and this field is 'Load more', this will end up appearing as 'Load more Voting members'.")),
+ ('footer_box_title', models.CharField(default='Work for HOT')),
+ ('footer_box_description', wagtail.fields.RichTextField(blank=True)),
+ ('footer_box_button_text', models.CharField(default='Check our Job Opportunities')),
+ ('footer_box_button_link', models.URLField(blank=True)),
+ ],
+ options={
+ 'abstract': False,
+ },
+ bases=('wagtailcore.page',),
+ ),
+ migrations.CreateModel(
+ name='MemberGroupPage',
+ 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')),
+ ('intro', wagtail.fields.RichTextField(blank=True, help_text='Appears in the header.')),
+ ('body_intro', wagtail.fields.RichTextField(blank=True)),
+ ('body_description', wagtail.fields.RichTextField(blank=True)),
+ ('desktop_size_items_per_row', models.SmallIntegerField(default=6, help_text='The number of members shown per row on desktop sizes.', validators=[django.core.validators.MinValueValidator(4), django.core.validators.MaxValueValidator(8)])),
+ ('header_image', models.ForeignKey(blank=True, help_text='Header image', 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/0005_individualmemberpage_member_groups.py b/app/members/migrations/0005_individualmemberpage_member_groups.py
new file mode 100644
index 0000000..e151dc3
--- /dev/null
+++ b/app/members/migrations/0005_individualmemberpage_member_groups.py
@@ -0,0 +1,20 @@
+# Generated by Django 4.2.7 on 2024-07-09 22:14
+
+from django.db import migrations
+import wagtail.blocks
+import wagtail.fields
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('members', '0004_membergroupownerpage_membergrouppage'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='individualmemberpage',
+ name='member_groups',
+ field=wagtail.fields.StreamField([('member_group', wagtail.blocks.PageChooserBlock(page_type=['members.MemberGroupPage']))], blank=True, null=True, use_json_field=True),
+ ),
+ ]
diff --git a/app/members/migrations/0006_alter_individualmemberpage_member_groups.py b/app/members/migrations/0006_alter_individualmemberpage_member_groups.py
new file mode 100644
index 0000000..a981794
--- /dev/null
+++ b/app/members/migrations/0006_alter_individualmemberpage_member_groups.py
@@ -0,0 +1,20 @@
+# Generated by Django 4.2.7 on 2024-07-09 22:45
+
+from django.db import migrations
+import wagtail.blocks
+import wagtail.fields
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('members', '0005_individualmemberpage_member_groups'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='individualmemberpage',
+ name='member_groups',
+ field=wagtail.fields.StreamField([('member_group', wagtail.blocks.StructBlock([('group', wagtail.blocks.PageChooserBlock(page_type=['members.MemberGroupPage'])), ('role', wagtail.blocks.CharBlock())]))], blank=True, null=True, use_json_field=True),
+ ),
+ ]
diff --git a/app/members/migrations/0007_alter_individualmemberpage_member_groups.py b/app/members/migrations/0007_alter_individualmemberpage_member_groups.py
new file mode 100644
index 0000000..14c8004
--- /dev/null
+++ b/app/members/migrations/0007_alter_individualmemberpage_member_groups.py
@@ -0,0 +1,20 @@
+# Generated by Django 4.2.7 on 2024-07-09 22:48
+
+from django.db import migrations
+import wagtail.blocks
+import wagtail.fields
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('members', '0006_alter_individualmemberpage_member_groups'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='individualmemberpage',
+ name='member_groups',
+ field=wagtail.fields.StreamField([('member_group', wagtail.blocks.StructBlock([('group', wagtail.blocks.PageChooserBlock(page_type=['members.MemberGroupPage'])), ('role', wagtail.blocks.CharBlock(required=False))]))], blank=True, null=True, use_json_field=True),
+ ),
+ ]
diff --git a/app/members/migrations/0008_membergrouppage_hub_shown_and_more.py b/app/members/migrations/0008_membergrouppage_hub_shown_and_more.py
new file mode 100644
index 0000000..b032e78
--- /dev/null
+++ b/app/members/migrations/0008_membergrouppage_hub_shown_and_more.py
@@ -0,0 +1,23 @@
+# Generated by Django 4.2.7 on 2024-07-09 23:03
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('members', '0007_alter_individualmemberpage_member_groups'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='membergrouppage',
+ name='hub_shown',
+ field=models.BooleanField(blank=True, default=False, null=True),
+ ),
+ migrations.AddField(
+ model_name='membergrouppage',
+ name='position_shown',
+ field=models.BooleanField(blank=True, default=False, null=True),
+ ),
+ ]
diff --git a/app/members/migrations/0009_alter_membergrouppage_hub_shown_and_more.py b/app/members/migrations/0009_alter_membergrouppage_hub_shown_and_more.py
new file mode 100644
index 0000000..06f523c
--- /dev/null
+++ b/app/members/migrations/0009_alter_membergrouppage_hub_shown_and_more.py
@@ -0,0 +1,23 @@
+# Generated by Django 4.2.7 on 2024-07-09 23:05
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('members', '0008_membergrouppage_hub_shown_and_more'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='membergrouppage',
+ name='hub_shown',
+ field=models.BooleanField(default=False),
+ ),
+ migrations.AlterField(
+ model_name='membergrouppage',
+ name='position_shown',
+ field=models.BooleanField(default=False),
+ ),
+ ]
diff --git a/app/members/migrations/0010_membergrouppage_show_search_options.py b/app/members/migrations/0010_membergrouppage_show_search_options.py
new file mode 100644
index 0000000..d3c5861
--- /dev/null
+++ b/app/members/migrations/0010_membergrouppage_show_search_options.py
@@ -0,0 +1,18 @@
+# Generated by Django 4.2.7 on 2024-07-10 17:43
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('members', '0009_alter_membergrouppage_hub_shown_and_more'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='membergrouppage',
+ name='show_search_options',
+ field=models.BooleanField(default=True),
+ ),
+ ]
diff --git a/app/members/migrations/0011_membergroupownerpage_search_button_text.py b/app/members/migrations/0011_membergroupownerpage_search_button_text.py
new file mode 100644
index 0000000..60de3dc
--- /dev/null
+++ b/app/members/migrations/0011_membergroupownerpage_search_button_text.py
@@ -0,0 +1,18 @@
+# Generated by Django 4.2.7 on 2024-07-10 17:53
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('members', '0010_membergrouppage_show_search_options'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='membergroupownerpage',
+ name='search_button_text',
+ field=models.CharField(default='Search'),
+ ),
+ ]
diff --git a/app/members/migrations/0012_membergroupownerpage_view_all_text.py b/app/members/migrations/0012_membergroupownerpage_view_all_text.py
new file mode 100644
index 0000000..f1c7235
--- /dev/null
+++ b/app/members/migrations/0012_membergroupownerpage_view_all_text.py
@@ -0,0 +1,18 @@
+# Generated by Django 4.2.7 on 2024-07-10 19:21
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('members', '0011_membergroupownerpage_search_button_text'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='membergroupownerpage',
+ name='view_all_text',
+ field=models.CharField(default='View all'),
+ ),
+ ]
diff --git a/app/members/models.py b/app/members/models.py
index 00e53fe..7121960 100644
--- a/app/members/models.py
+++ b/app/members/models.py
@@ -1,11 +1,15 @@
from django.db import models
+from django.core.validators import MinValueValidator, MaxValueValidator
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 django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from app.projects.models import IndividualProjectPage
from app.news.models import IndividualNewsPage
+from app.mapping_hubs.models import IndividualMappingHubPage
+from wagtail.search import index
class WebLinkStructBlock(StructBlock):
link_text = CharBlock(required=True)
@@ -16,6 +20,127 @@ class WebLinkBlock(StreamBlock):
blocks = WebLinkStructBlock()
+class MemberGroupOwnerPage(Page):
+ max_count = 1
+
+ subpage_types = [
+ 'members.MemberGroupPage'
+ ]
+
+ search_placeholder = models.CharField(default="Search by name")
+ filter_by_country = models.CharField(default="Filter by Country")
+ sort_by_titlea = models.CharField(default="Sort by Name Alphabetical")
+ sort_by_titlez = models.CharField(default="Sort by Name Reverse Alphabetical")
+ search_button_text = models.CharField(default="Search")
+
+ load_more_text = models.CharField(default="Load more", help_text="This will be a prefix to the title of the page; i.e., if the page title is 'Voting members', and this field is 'Load more', this will end up appearing as 'Load more Voting members'.")
+
+ view_all_text = models.CharField(default="View all")
+
+ footer_box_title = models.CharField(default="Work for HOT")
+ footer_box_description = RichTextField(blank=True)
+ footer_box_button_text = models.CharField(default="Check our Job Opportunities")
+ footer_box_button_link = models.URLField(blank=True)
+
+ content_panels = Page.content_panels + [
+ MultiFieldPanel([
+ FieldPanel('search_placeholder'),
+ FieldPanel('filter_by_country'),
+ FieldPanel('sort_by_titlea'),
+ FieldPanel('sort_by_titlez'),
+ FieldPanel('search_button_text'),
+ ], heading="Search options"),
+ FieldPanel('load_more_text'),
+ FieldPanel('view_all_text'),
+ MultiFieldPanel([
+ FieldPanel('footer_box_title'),
+ FieldPanel('footer_box_description'),
+ FieldPanel('footer_box_button_text'),
+ FieldPanel('footer_box_button_link'),
+ ], heading="Footer box"),
+ ]
+
+
+class MemberGroupPage(Page):
+ def get_context(self, request, *args, **kwargs):
+ context = super().get_context(request, *args, **kwargs)
+
+ members = IndividualMemberPage.objects.live().filter(
+ Q(member_groups__contains=[{'type': 'member_group', 'value': { 'group': context['page'].id }}])
+ ).filter(locale=context['page'].locale)
+
+ keyword = request.GET.get('keyword', '')
+
+ if keyword:
+ members = members.search(keyword).get_queryset()
+
+ hubs = IndividualMappingHubPage.objects.live().filter(locale=context['page'].locale)
+ query = Q()
+ for hub in hubs:
+ if request.GET.get(str(hub), ''):
+ query = query | Q(location_hub=hub)
+ members = members.filter(query).distinct()
+
+ match request.GET.get('sort', ''):
+ case 'sort.titlea':
+ members = members.order_by('title')
+ case 'sort.titlez':
+ members = members.order_by('-title')
+ case _:
+ members = members.order_by('title')
+
+ page = request.GET.get('page', 1)
+ paginator = Paginator(members, 12) # if you want more/less items per page (i.e., per load), change the number here to something else
+ try:
+ members = paginator.page(page)
+ except PageNotAnInteger:
+ members = paginator.page(1)
+ except EmptyPage:
+ members = paginator.page(paginator.num_pages)
+
+ context['members'] = members
+ context['hubs'] = hubs
+ context['groups'] = MemberGroupPage.objects.live().filter(locale=context['page'].locale).exclude(id=context['page'].id)
+
+ return context
+
+ parent_page_type = [
+ 'members.MemberGroupOwnerPage'
+ ]
+
+ header_image = models.ForeignKey(
+ "wagtailimages.Image",
+ null=True,
+ blank=True,
+ on_delete=models.SET_NULL,
+ related_name="+",
+ help_text="Header image"
+ )
+ intro = RichTextField(blank=True, help_text="Appears in the header.")
+
+ body_intro = RichTextField(blank=True)
+ body_description = RichTextField(blank=True)
+
+ show_search_options = models.BooleanField(default=True)
+ desktop_size_items_per_row = models.SmallIntegerField(default=6, help_text="The number of members shown per row on desktop sizes.", validators=[
+ MinValueValidator(4),
+ MaxValueValidator(8),
+ ])
+ position_shown = models.BooleanField(default=False)
+ hub_shown = models.BooleanField(default=False)
+
+ content_panels = Page.content_panels + [
+ FieldPanel('header_image'),
+ FieldPanel('intro'),
+ FieldPanel('body_intro'),
+ FieldPanel('body_description'),
+ FieldPanel('show_search_options'),
+ FieldPanel('desktop_size_items_per_row'),
+ FieldPanel('position_shown'),
+ FieldPanel('hub_shown'),
+ ]
+
+
class MemberOwnerPage(Page):
max_count = 1
@@ -29,6 +154,12 @@ class MemberOwnerPage(Page):
FieldPanel('project_contribution_title'),
]
+
+class MemberGroupBlock(StructBlock):
+ group = PageChooserBlock(page_type="members.MemberGroupPage")
+ role = CharBlock(required=False)
+
+
"""
This page should only be created as a child of a MemberOwnerPage!
Its template depends on fields from the MemberOwnerPage in order
@@ -62,6 +193,7 @@ def get_context(self, request, *args, **kwargs):
related_name="+",
help_text="An image of the member",
)
+ member_groups = StreamField([('member_group', MemberGroupBlock())], use_json_field=True, null=True, blank=True)
position = models.CharField()
location_hub = models.ForeignKey(
'mapping_hubs.IndividualMappingHubPage',
@@ -70,13 +202,20 @@ def get_context(self, request, *args, **kwargs):
on_delete=models.SET_NULL,
related_name='+'
)
- introduction = RichTextField()
+ intro = RichTextField()
on_the_web_links = StreamField(WebLinkBlock(), blank=True, use_json_field=True)
+
+ search_fields = Page.search_fields + [
+ index.SearchField('title'),
+ index.SearchField('search_description'),
+ index.SearchField('intro'),
+ ]
content_panels = Page.content_panels + [
FieldPanel('image'),
+ FieldPanel('member_groups'),
FieldPanel('position'),
FieldPanel('location_hub'),
- FieldPanel('introduction'),
+ FieldPanel('intro'),
FieldPanel('on_the_web_links'),
]
diff --git a/app/members/templates/members/components/MembersSortOption.html b/app/members/templates/members/components/MembersSortOption.html
new file mode 100644
index 0000000..8e3320f
--- /dev/null
+++ b/app/members/templates/members/components/MembersSortOption.html
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/members/templates/members/components/TailwindGridSizeAssurance.html b/app/members/templates/members/components/TailwindGridSizeAssurance.html
new file mode 100644
index 0000000..09e7b65
--- /dev/null
+++ b/app/members/templates/members/components/TailwindGridSizeAssurance.html
@@ -0,0 +1,9 @@
+{% comment %}
+
+This file is just for making sure that the member_group_page's grid columns work right!
+This ensures that all possible values for the grid column field will have its Tailwind
+class built.
+
+{% endcomment %}
+
+
+ {% if page.show_search_options %}
+
+ {% endif %}
+
+ {% comment %} MEMBERS LIST {% endcomment %}
+
+ {% for member in members %}
+ {% include "ui/components/members/MemberPreviewBlock.html" with member=member position_shown=page.position_shown hub_shown=page.hub_shown %}
+ {% endfor %}
+
+ {% for group in groups %}
+ {% if forloop.counter0|divisibleby:2 %}
+
+ {% include "ui/components/dogear_boxes/DogearRed.html" with title=group.title linktext=page.get_parent.specific.view_all_text|add:' '|add:group.title linkurl=group.url %}
+
+ {% else %}
+
+ {% include "ui/components/dogear_boxes/DogearBlack.html" with title=group.title linktext=page.get_parent.specific.view_all_text|add:' '|add:group.title linkurl=group.url %}
+
+ {% endif %}
+ {% endfor %}
+
+
+ {% include "ui/components/FooterBannerWithTextAndLink.html" with text=page.get_parent.specific.footer_box_title url=page.get_parent.specific.footer_box_button_link buttontext=page.get_parent.specific.footer_box_button_text description=page.get_parent.specific.footer_box_description %}
+
+
+{% endblock %}
diff --git a/app/news/models.py b/app/news/models.py
index 279dda1..c0887ae 100644
--- a/app/news/models.py
+++ b/app/news/models.py
@@ -21,6 +21,9 @@ def get_context(self, request, *args, **kwargs):
keyword = request.GET.get('keyword', '')
news_list = IndividualNewsPage.objects.live().filter(locale=context['page'].locale)
+
+ if keyword:
+ news_list = news_list.search(keyword).get_queryset()
categories = NewsCategory.objects.all()
tags = [x[4:] for x in request.GET.keys() if x.startswith("tag.")]
@@ -28,24 +31,24 @@ def get_context(self, request, *args, **kwargs):
for category in categories:
if request.GET.get(str(category), ''):
query = query | Q(categories=category)
+ news_list = news_list.filter(query).distinct()
+
+ query = Q()
for tag in tags:
query = query | Q(tags__name=tag)
news_list = news_list.filter(query).distinct()
match request.GET.get('sort', ''):
case 'sort.new':
- news_list = news_list.order_by('date')
- case 'sort.old':
news_list = news_list.order_by('-date')
+ case 'sort.old':
+ news_list = news_list.order_by('date')
case 'sort.titlea':
news_list = news_list.order_by('title')
case 'sort.titlez':
news_list = news_list.order_by('-title')
case _:
- news_list = news_list.order_by('date')
-
- if keyword:
- news_list = news_list.search(keyword)
+ news_list = news_list.order_by('-date')
page = request.GET.get('page', 1)
paginator = Paginator(news_list, 6) # if you want more/less items per page (i.e., per load), change the number here to something else
@@ -64,6 +67,10 @@ def get_context(self, request, *args, **kwargs):
max_count = 1
+ subpage_types = [
+ 'news.IndividualNewsPage'
+ ]
+
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")
@@ -180,8 +187,9 @@ class IndividualNewsPage(Page):
search_fields = Page.search_fields + [
index.SearchField('title'),
index.SearchField('intro'),
- index.FilterField('newscategory_id'), # the console warns you about this but if you don't have this then category search doesn't work
- index.FilterField('name'),
+ # index.FilterField('newscategory_id'), # the console warns you about this but if you don't have this then category search doesn't work
+ # index.FilterField('name'),
+ index.SearchField('search_description'),
]
content_panels = Page.content_panels + [
diff --git a/app/news/templates/news/components/NewsSortOption.html b/app/news/templates/news/components/NewsSortOption.html
index 8b30d23..d364b07 100644
--- a/app/news/templates/news/components/NewsSortOption.html
+++ b/app/news/templates/news/components/NewsSortOption.html
@@ -1,4 +1,4 @@
-
+
\ No newline at end of file
diff --git a/app/news/templates/news/individual_news_page.html b/app/news/templates/news/individual_news_page.html
index 26b25ac..c91346e 100644
--- a/app/news/templates/news/individual_news_page.html
+++ b/app/news/templates/news/individual_news_page.html
@@ -17,7 +17,7 @@
{{ page.title }}
{{page.get_parent.specific.authors_posted_by_text}}
{% for author in page.authors %}
- {{author.value.title}}
+ {{author.value.title}}
{% if not forloop.last %}
,
{% endif %}
@@ -41,70 +41,70 @@
{% for article in news %}
{% include "ui/components/news/NewsPreviewBlockProjects.html" with news=article showimage=True class="[&_.image-hide-small]:hidden md:[&_.image-hide-small]:block" %}
{% endfor %}
- {% with ''|center:news_paginator.num_pages as range %}
- {% for _ in range %}
- {% if forloop.counter == 1 or forloop.counter == news_paginator.num_pages or forloop.counter == current_page or forloop.counter|add:1 == current_page or forloop.counter|add:'-1' == current_page %}
-
-
-
- {% endif %}
- {% if forloop.counter|add:2 == current_page or forloop.counter|add:'-2' == current_page and not forloop.last %}
- {% comment %}
- for reasons that i can't begin to comprehend, the if statement
- below CANNOT be part of the if statement above. it just does
- not work
- {% endcomment %}
- {% if not forloop.first %}
-
{% include "ui/components/BaseLink.html" with linkurl=page.get_parent.specific.view_all_news_url linktext=page.get_parent.specific.view_all_news_text %}
+ {% for project in projects %}
+ {% include "ui/components/projects/ProjectPreviewBlockNews.html" with project=project.specific showimage=True %}
+ {% endfor %}
+
+ {% for panel in page.large_panels %}
+ {% include "ui/components/misc_panels/LinkBlockWithImage.html" with title=panel.value.title image=panel.value.image description=panel.value.description linktext=panel.value.link_text linkurl=panel.value.link_url %}
+ {% endfor %}
+
+
+
+
+
+ {% include "ui/components/sections/BaseSectionWithImage.html" with title=page.resource_learning_title image=page.resource_learning_image imageright=True red_button=True button_text=page.get_connected_button_text button_link=page.get_connected_button_link description=page.resource_learning_description imagenotwide=True %}
+
+
+
+
+
+ {% include "ui/components/dogear_boxes/DogearAnyColourLong.html" with title=page.dogear_tech_news_title linktext=page.dogear_tech_news_link_text linkurl=page.dogear_tech_news_link_url textcolour="black" colour="var(--hot-off-white)" arrowcolour="black" %}
+
+
+
+
+ {% 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/DogearBlack.html" with title=page.black_box_title linktext=page.black_box_link_text linkurl=page.black_box_link_url %}
+
+
+
+
+{% endblock %}
diff --git a/app/tools_and_resources/tests.py b/app/tools_and_resources/tests.py
new file mode 100644
index 0000000..7ce503c
--- /dev/null
+++ b/app/tools_and_resources/tests.py
@@ -0,0 +1,3 @@
+from django.test import TestCase
+
+# Create your tests here.
diff --git a/app/tools_and_resources/views.py b/app/tools_and_resources/views.py
new file mode 100644
index 0000000..91ea44a
--- /dev/null
+++ b/app/tools_and_resources/views.py
@@ -0,0 +1,3 @@
+from django.shortcuts import render
+
+# Create your views here.
diff --git a/app/ui/templates/ui/components/BasePageHeader.html b/app/ui/templates/ui/components/BasePageHeader.html
index 174943a..cce8bb9 100644
--- a/app/ui/templates/ui/components/BasePageHeader.html
+++ b/app/ui/templates/ui/components/BasePageHeader.html
@@ -2,9 +2,11 @@
==> PARAMETERS
- title: A string, the title shown in the header
- intro: An HTML element (regular usage would be a
with some text in it)
+- subtitle: An HTML element
- image: A Wagtail image
-{% endcomment %}
+Only one of either intro or subtitle should be present; you probably would not want both.
+{% endcomment %}
{% load wagtailimages_tags %}
{% image image original as image_p %}
@@ -13,21 +15,21 @@
-
+
{{ title }}
{% if intro %}
-
+
{{ intro|safe }}
{% endif %}
-
- {% if subtitle %}
+ {% if subtitle %}
+
{{ subtitle|safe }}
- {% endif %}
-
+
+ {% endif %}
\ No newline at end of file
diff --git a/app/ui/templates/ui/components/CTABodyPanelBase.html b/app/ui/templates/ui/components/CTABodyPanelBase.html
index 7136626..7d6e8df 100644
--- a/app/ui/templates/ui/components/CTABodyPanelBase.html
+++ b/app/ui/templates/ui/components/CTABodyPanelBase.html
@@ -1,3 +1,10 @@
+{% comment %}
+==> PARAMETERS
+- title: string; the title for the panel
+- text: html element; the description for the panel
+- linktext: string; the text shown for the link
+- linkurl: string; the url for the link
+{% endcomment %}
{{ title }}
diff --git a/app/ui/templates/ui/components/FlexTitleWithLink.html b/app/ui/templates/ui/components/FlexTitleWithLink.html
new file mode 100644
index 0000000..ecf2dc6
--- /dev/null
+++ b/app/ui/templates/ui/components/FlexTitleWithLink.html
@@ -0,0 +1,16 @@
+{% comment %}
+==> PARAMETERS
+- title: string; the title
+- class: string; the classes for the containing div
+- titleclass: string; the classes for the title specifically. If no class is provided, the title will be h3 title size
+- linktext: string; the text to be shown for the link
+- linkurl: string; the url for the link
+{% endcomment %}
+
+
+ {{title}}
+
+
+ {% include "ui/components/BaseLink.html" %}
+
+
\ No newline at end of file
diff --git a/app/ui/templates/ui/components/FooterBannerWithTextAndLink.html b/app/ui/templates/ui/components/FooterBannerWithTextAndLink.html
index b93d3e9..7b9cdf1 100644
--- a/app/ui/templates/ui/components/FooterBannerWithTextAndLink.html
+++ b/app/ui/templates/ui/components/FooterBannerWithTextAndLink.html
@@ -10,6 +10,11 @@
{{ text }}
+ {% if description %}
+
+ {{description|safe}}
+
+ {% endif %}
{% include "components/branded_elements/button.html" with text=buttontext %}
diff --git a/app/ui/templates/ui/components/PageHeaderWithBlur.html b/app/ui/templates/ui/components/PageHeaderWithBlur.html
index 3aa41e6..e67f2ed 100644
--- a/app/ui/templates/ui/components/PageHeaderWithBlur.html
+++ b/app/ui/templates/ui/components/PageHeaderWithBlur.html
@@ -3,6 +3,7 @@
- title: A string, the title shown in the header
- subtitle: An HTML element (regular usage would be a
with some text in it)
- image: A Wagtail image
+- full_length: If falsey/null, the content will not be entirely full length in the header; otherwise, it will be full length
{% endcomment %}
{% load wagtailimages_tags %}
diff --git a/app/ui/templates/ui/components/SectionHeadingWithUnderline.html b/app/ui/templates/ui/components/SectionHeadingWithUnderline.html
index a1b5a00..cd31bca 100644
--- a/app/ui/templates/ui/components/SectionHeadingWithUnderline.html
+++ b/app/ui/templates/ui/components/SectionHeadingWithUnderline.html
@@ -1,3 +1,8 @@
+{% comment %}
+==> PARAMETERS
+- title: string; the title
+{% endcomment %}
+
{{ title }}
diff --git a/app/ui/templates/ui/components/ThreeElementCarousel.html b/app/ui/templates/ui/components/ThreeElementCarousel.html
index 0e3fed9..00ff572 100644
--- a/app/ui/templates/ui/components/ThreeElementCarousel.html
+++ b/app/ui/templates/ui/components/ThreeElementCarousel.html
@@ -1,3 +1,13 @@
+{% comment %}
+==> PARAMETERS
+- carousel: list of blocks; each block should have a .value, which should have:
+ - .header: string
+ - .body: string
+ - .action_button.text: string
+ - .action_button.link: string
+
+If you'd like, refer to app.ui.models to see the specifics of what makes up a carousel block.
+{% endcomment %}
diff --git a/app/ui/templates/ui/components/TitleWithUnderline.html b/app/ui/templates/ui/components/TitleWithUnderline.html
new file mode 100644
index 0000000..af7adc9
--- /dev/null
+++ b/app/ui/templates/ui/components/TitleWithUnderline.html
@@ -0,0 +1,8 @@
+{% comment %}
+==> PARAMETERS
+- title: string; the title
+{% endcomment %}
+
+ {{title}}
+
+
diff --git a/app/ui/templates/ui/components/dogear_boxes/DogearAnyColourLong.html b/app/ui/templates/ui/components/dogear_boxes/DogearAnyColourLong.html
index 3b0288b..b1f5fdd 100644
--- a/app/ui/templates/ui/components/dogear_boxes/DogearAnyColourLong.html
+++ b/app/ui/templates/ui/components/dogear_boxes/DogearAnyColourLong.html
@@ -4,15 +4,16 @@
- linkurl: a string; the link's url
- linktext: a string; the text that shows for the link
- colour: a string; the colour that the box should be (can be hex code or any other CSS compatible colour thing)
+- arrowcolour: a string; the colour the arrow should be
{% endcomment %}
-
+
{{ title }}
{{ linktext }}
-
+
{% include "ui/components/icon_svgs/LinkCaret.html" %}
diff --git a/app/ui/templates/ui/components/dogear_boxes/DogearBlack.html b/app/ui/templates/ui/components/dogear_boxes/DogearBlack.html
index dd7a5a2..6a3d2fe 100644
--- a/app/ui/templates/ui/components/dogear_boxes/DogearBlack.html
+++ b/app/ui/templates/ui/components/dogear_boxes/DogearBlack.html
@@ -5,6 +5,6 @@
- linktext: a string; the text that shows for the link
{% endcomment %}
-
+
{% include "./DogearContent.html" with color="var(--hot-red)" %}
\ No newline at end of file
diff --git a/app/ui/templates/ui/components/dogear_boxes/DogearContent.html b/app/ui/templates/ui/components/dogear_boxes/DogearContent.html
index 15e7663..ca842a1 100644
--- a/app/ui/templates/ui/components/dogear_boxes/DogearContent.html
+++ b/app/ui/templates/ui/components/dogear_boxes/DogearContent.html
@@ -1,6 +1,7 @@
{% comment %}
==> PARAMETERS
- title: a string; the title of the box
+- description: an html element; a description under the title (optional)
- linkurl: a string; the link's url
- linktext: a string; the text that shows for the link
- color: a string; the color that the caret next to the link text should show as
@@ -11,6 +12,9 @@
\ No newline at end of file
diff --git a/app/ui/templates/ui/components/mapping_hub/MappingHubPreviewBlock.html b/app/ui/templates/ui/components/mapping_hub/MappingHubPreviewBlock.html
index f20bfad..affd498 100644
--- a/app/ui/templates/ui/components/mapping_hub/MappingHubPreviewBlock.html
+++ b/app/ui/templates/ui/components/mapping_hub/MappingHubPreviewBlock.html
@@ -2,15 +2,8 @@
==> PARAMETERS
- hub: An IndividualMappingHubPage object; the mapping hub page to be previewed
{% endcomment %}
-
{% load wagtailimages_tags %}
-
\ No newline at end of file
diff --git a/app/ui/templates/ui/components/misc_panels/LinkBlockWithImage.html b/app/ui/templates/ui/components/misc_panels/LinkBlockWithImage.html
new file mode 100644
index 0000000..3eadf13
--- /dev/null
+++ b/app/ui/templates/ui/components/misc_panels/LinkBlockWithImage.html
@@ -0,0 +1,19 @@
+{% comment %}
+==> PARAMETERS
+- title: string; the title
+- description: html element; the description of the block
+- linktext: string; the text to show for the link
+- linkurl: string; the desired url
+{% endcomment %}
+{% load wagtailimages_tags %}
+
+
+ {% image image original class="aspect-[2/1] object-cover" %}
+
{{title}}
+
+ {{description}}
+
+
+ {% include "ui/components/BaseLink.html" %}
+
+
\ No newline at end of file
diff --git a/app/ui/templates/ui/components/misc_panels/PagePreviewBasic.html b/app/ui/templates/ui/components/misc_panels/PagePreviewBasic.html
new file mode 100644
index 0000000..3c6429a
--- /dev/null
+++ b/app/ui/templates/ui/components/misc_panels/PagePreviewBasic.html
@@ -0,0 +1,19 @@
+{% comment %}
+==> PARAMETERS
+- page: Page object; its link and title is used here
+- previmg: image object; the image for the preview
+{% endcomment %}
+{% load wagtailimages_tags %}
+
+{% image image original as previmg %}
+
+
+
\ No newline at end of file
diff --git a/app/ui/templates/ui/components/misc_panels/PagePreviewWithTabletDescription.html b/app/ui/templates/ui/components/misc_panels/PagePreviewWithTabletDescription.html
new file mode 100644
index 0000000..eb1db9d
--- /dev/null
+++ b/app/ui/templates/ui/components/misc_panels/PagePreviewWithTabletDescription.html
@@ -0,0 +1,31 @@
+{% comment %}
+==> PARAMETERS
+- page: Page object; its link and title is used here
+- previmg: image object; the image for the preview
+- tablet_description: html element; the description of the block, which only shows on tablet sizes and smaller
+- read_more_text: string; the text to show for "read more"
+{% endcomment %}
+{% load wagtailimages_tags %}
+
+{% image image original as previmg %}
+
+
+
\ No newline at end of file
diff --git a/app/ui/templates/ui/components/navigation/FooterNavigation.html b/app/ui/templates/ui/components/navigation/FooterNavigation.html
index 38f5427..2aa3619 100644
--- a/app/ui/templates/ui/components/navigation/FooterNavigation.html
+++ b/app/ui/templates/ui/components/navigation/FooterNavigation.html
@@ -1,3 +1,6 @@
+{% comment %}
+No parameters; it grabs directly from the home page (for the correct locale).
+{% endcomment %}
{% load homepage_tags %}
{% get_home_page as home_page %}
{% get_navigation as navigation %}
diff --git a/app/ui/templates/ui/components/navigation/HeaderNavbar.html b/app/ui/templates/ui/components/navigation/HeaderNavbar.html
index 3bfe9fc..2a49392 100644
--- a/app/ui/templates/ui/components/navigation/HeaderNavbar.html
+++ b/app/ui/templates/ui/components/navigation/HeaderNavbar.html
@@ -1,3 +1,6 @@
+{% comment %}
+No parameters; it grabs directly from the home page (for the correct locale).
+{% endcomment %}
{% load homepage_tags %}
{% get_navigation as navigation %}
{% get_home_page as home_page %}
@@ -50,6 +53,7 @@
{% comment %} MOBILE EXPANDED LIST {% endcomment %}
+
{% include "ui/components/navigation/SearchForm.html" %}
{% for item in navigation %}
{% include "ui/components/navigation/HeaderNavbarItem.html" with item=item.value %}
diff --git a/app/ui/templates/ui/components/navigation/HeaderNavbarButton.html b/app/ui/templates/ui/components/navigation/HeaderNavbarButton.html
index 22f0dd0..39a73a2 100644
--- a/app/ui/templates/ui/components/navigation/HeaderNavbarButton.html
+++ b/app/ui/templates/ui/components/navigation/HeaderNavbarButton.html
@@ -1,3 +1,7 @@
+{% comment %}
+==> PARAMETERS
+- item: a navigation item; has a title and a link_page OR link_url
+{% endcomment %}
\ No newline at end of file
diff --git a/app/ui/templates/ui/components/projects/ProjectPreviewBlockNews.html b/app/ui/templates/ui/components/projects/ProjectPreviewBlockNews.html
index 222ffed..b8b33f2 100644
--- a/app/ui/templates/ui/components/projects/ProjectPreviewBlockNews.html
+++ b/app/ui/templates/ui/components/projects/ProjectPreviewBlockNews.html
@@ -1,13 +1,13 @@
{% comment %}
==> PARAMETERS
- project: An IndividualProjectPage object; the project page to be previewed
-- showimage: a boolean; whether or not the image should be shown in the preview
+- showimage: optional; if truthy, the project's image will be shown in the preview
{% endcomment %}
{% load wagtailimages_tags %}
{% image project.header_image original as image_p %}
-
\ No newline at end of file
diff --git a/app/ui/templates/ui/components/sections/GreyBackgroundWithImage.html b/app/ui/templates/ui/components/sections/GreyBackgroundWithImage.html
new file mode 100644
index 0000000..bd6f16d
--- /dev/null
+++ b/app/ui/templates/ui/components/sections/GreyBackgroundWithImage.html
@@ -0,0 +1,21 @@
+{% comment %}
+==> PARAMETERS
+- image: image object; the image for the section
+- title: html element; the title for the section
+- description: html element; the description for the section
+- button2_text: string; the left button's text
+- button2_link: string; the left button's link
+- button_text: string; the right button's text
+- button_link: string; the right button's link
+
+- red_button: if truthy, the right button will be red; otherwise it will be outlined
+- bigdescription: if truthy, the description will have larger text
+- imagebottom: if truthy, the image will always be on the bottom in tablet/mobile sizes
+- imageright: if truthy, the image will always be on the right on desktop size
+- imagenotwide: if truthy, the image will not stretch to the edge of the screen in tablet/mobile sizes
+{% endcomment %}
+{% load wagtailimages_tags %}
+
+
+ {% include "./BaseSectionWithImage.html" %}
+
\ No newline at end of file
diff --git a/app/ui/templates/ui/components/sections/LinkListSection.html b/app/ui/templates/ui/components/sections/LinkListSection.html
new file mode 100644
index 0000000..c2326d9
--- /dev/null
+++ b/app/ui/templates/ui/components/sections/LinkListSection.html
@@ -0,0 +1,20 @@
+{% comment %}
+==> PARAMETERS
+- title: string; the title
+- description: html element; the description for the section
+- links: list of link objects; these objects should have a .value.text and a .value.link
+{% endcomment %}
+
{{title}}
+
+
+
+ {{description|safe}}
+
+
+ {% for link in links %}
+
+ {% include "ui/components/BaseLink.html" with linktext=link.value.text linkurl=link.value.link %}
+
+ {% endfor %}
+
+
diff --git a/app/ui/templates/ui/components/sections/NavyBackgroundWithImage.html b/app/ui/templates/ui/components/sections/NavyBackgroundWithImage.html
new file mode 100644
index 0000000..86801e5
--- /dev/null
+++ b/app/ui/templates/ui/components/sections/NavyBackgroundWithImage.html
@@ -0,0 +1,21 @@
+{% comment %}
+==> PARAMETERS
+- image: image object; the image for the section
+- title: html element; the title for the section
+- description: html element; the description for the section
+- button2_text: string; the left button's text
+- button2_link: string; the left button's link
+- button_text: string; the right button's text
+- button_link: string; the right button's link
+
+- red_button: if truthy, the right button will be red; otherwise it will be outlined
+- bigdescription: if truthy, the description will have larger text
+- imagebottom: if truthy, the image will always be on the bottom in tablet/mobile sizes
+- imageright: if truthy, the image will always be on the right on desktop size
+- imagenotwide: if truthy, the image will not stretch to the edge of the screen in tablet/mobile sizes
+{% endcomment %}
+{% load wagtailimages_tags %}
+
+
+ {% include "./BaseSectionWithImage.html" %}
+
\ No newline at end of file
diff --git a/app/ui/templates/ui/components/sharers/ShareSection.html b/app/ui/templates/ui/components/sharers/ShareSection.html
index a7782da..be28251 100644
--- a/app/ui/templates/ui/components/sharers/ShareSection.html
+++ b/app/ui/templates/ui/components/sharers/ShareSection.html
@@ -1,3 +1,8 @@
+{% comment %}
+==> PARAMETERS
+- class: string; the classes for the containing div
+- sharetext: string; the text to be shown next to the share icons
+{% endcomment %}
diff --git a/app/ui/templates/ui/components/utilities/PaginatorNavigation.html b/app/ui/templates/ui/components/utilities/PaginatorNavigation.html
new file mode 100644
index 0000000..e2ed781
--- /dev/null
+++ b/app/ui/templates/ui/components/utilities/PaginatorNavigation.html
@@ -0,0 +1,47 @@
+{% comment %}
+PARAMETERS:
+=> paginator: a paginator object
+=> current_page: an integer, the current page
+{% endcomment %}
+
+ {% with ''|center:paginator.num_pages as range %}
+ {% for _ in range %}
+ {% if forloop.counter == 1 or forloop.counter == paginator.num_pages or forloop.counter == current_page or forloop.counter|add:1 == current_page or forloop.counter|add:'-1' == current_page %}
+
+
+
+ {% endif %}
+ {% if forloop.counter|add:2 == current_page or forloop.counter|add:'-2' == current_page and not forloop.last %}
+ {% comment %}
+ for reasons that i can't begin to comprehend, the if statement
+ below CANNOT be part of the if statement above. it just does
+ not work
+ {% endcomment %}
+ {% if not forloop.first %}
+
+ {% include "ui/components/sections/LinkListSection.html" with title=page.our_people_title description=page.our_people_description links=page.our_people_links %}
+
+
+
+
+
+ {% comment %} PAGE PREVIEWS {% endcomment %}
+
+ {% for prev in page.other_page_preview_blocks %}
+ {% include "ui/components/misc_panels/PagePreviewBasic.html" with page=prev.value.page image=prev.value.image %}
+ {% endfor %}
+
+
+ {% comment %} PARTNERS {% endcomment %}
+
+
+
+ {{ page.partners_title }}
+
+
+
+
+
+ {% include "ui/components/BaseLink.html" with linkurl=page.partners_view_all_url linktext=page.partners_view_all_text %}
+
+
+ {% include "ui/components/partners/PartnerViewBlock.html" with partners=page.partners.all %}
+
+
+
+ {% comment %} OPPORTUNITIES {% endcomment %}
+ {% include "home/components/CheckOutOpportunitiesSection.html" %}
+ {% comment %} WORK FOR HOT {% endcomment %}
+ {% include "ui/components/sections/GreyBackgroundWithImage.html" with image=page.work_hot_image title=page.work_hot_title description=page.work_hot_description button_text=page.work_hot_button_text button_link=page.work_hot_button_url red_button=True %}
+
+
+
+ {% include "ui/components/sections/LinkListSection.html" with title=page.our_policies_title description=page.our_policies_description links=page.our_policies_links %}
+
+
+
+
+
+
+ {% include "ui/components/dogear_boxes/DogearRed.html" with title=page.red_box_title description=page.red_box_description linktext=page.red_box_link_text linkurl=page.red_box_link_url %}
+ {% include "ui/components/dogear_boxes/DogearBlack.html" with title=page.black_box_title description=page.black_box_description linktext=page.black_box_link_text linkurl=page.black_box_link_url %}
+