1 Commits

Author SHA1 Message Date
Mark
1c5ba6cf90 feat: replace hardcoded navigation with CMS-managed models
All checks were successful
CI / nightly-e2e (pull_request) Has been skipped
CI / deploy (pull_request) Has been skipped
CI / pr-e2e (pull_request) Successful in 1m15s
CI / ci (pull_request) Successful in 1m20s
Replace static nav/footer links with Wagtail-managed NavigationMenuItem
and SocialMediaLink orderables on SiteSettings. Unpublished pages are
automatically excluded from rendering, fixing the dead-link problem.

- Extend SiteSettings with site_name, tagline, footer_description,
  copyright_text branding fields
- Add NavigationMenuItem orderable (link_page/link_url, show_in_header,
  show_in_footer, sort_order) with automatic live-page filtering
- Add SocialMediaLink orderable with platform icon templates
- New template tags: get_nav_items, get_social_links
- Update nav.html and footer.html to render from CMS data
- Data migration seeds existing hardcoded values for zero-change deploy
- Update seed_e2e_content command for test/dev environments
- 18 new tests covering models, template tags, and rendered output

Closes #32

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-02 19:07:35 +00:00

View File

@@ -140,40 +140,45 @@ class Command(BaseCommand):
site.is_default_site = True site.is_default_site = True
site.save() site.save()
# Navigation menu items and social links # Navigation menu items and social links — always reconcile to
# match the pages we just created (the data migration may have
# seeded partial items before these pages existed).
settings, _ = SiteSettings.objects.get_or_create(site=site) settings, _ = SiteSettings.objects.get_or_create(site=site)
if not NavigationMenuItem.objects.filter(settings=settings).exists(): NavigationMenuItem.objects.filter(settings=settings).delete()
article_index_page = ArticleIndexPage.objects.child_of(home).filter(slug="articles").first() article_index_page = ArticleIndexPage.objects.child_of(home).filter(slug="articles").first()
about_page = AboutPage.objects.child_of(home).filter(slug="about").first() about_page = AboutPage.objects.child_of(home).filter(slug="about").first()
nav_items = [ nav_items = [
NavigationMenuItem(settings=settings, link_page=home, link_title="Home", sort_order=0), NavigationMenuItem(settings=settings, link_page=home, link_title="Home", sort_order=0),
] ]
if article_index_page: if article_index_page:
nav_items.append( nav_items.append(
NavigationMenuItem( NavigationMenuItem(
settings=settings, link_page=article_index_page, settings=settings, link_page=article_index_page,
link_title="Articles", sort_order=1, link_title="Articles", sort_order=1,
)
) )
if about_page:
nav_items.append(
NavigationMenuItem(settings=settings, link_page=about_page, link_title="About", sort_order=2)
)
NavigationMenuItem.objects.bulk_create(nav_items)
if not SocialMediaLink.objects.filter(settings=settings).exists():
SocialMediaLink.objects.bulk_create(
[
SocialMediaLink(
settings=settings, platform="twitter",
url="https://twitter.com/nohypeai",
label="Twitter (X)", sort_order=0,
),
SocialMediaLink(
settings=settings, platform="rss",
url="/feed/", label="RSS Feed", sort_order=1,
),
]
) )
if about_page:
nav_items.append(
NavigationMenuItem(
settings=settings, link_page=about_page,
link_title="About", sort_order=2,
)
)
NavigationMenuItem.objects.bulk_create(nav_items)
SocialMediaLink.objects.filter(settings=settings).delete()
SocialMediaLink.objects.bulk_create(
[
SocialMediaLink(
settings=settings, platform="twitter",
url="https://twitter.com/nohypeai",
label="Twitter (X)", sort_order=0,
),
SocialMediaLink(
settings=settings, platform="rss",
url="/feed/", label="RSS Feed", sort_order=1,
),
]
)
self.stdout.write(self.style.SUCCESS("Seeded E2E content.")) self.stdout.write(self.style.SUCCESS("Seeded E2E content."))