Skip to content

Story 2366: Homepage Integration#2480

Open
julhoang wants to merge 26 commits into
developfrom
julia/homepage-integration
Open

Story 2366: Homepage Integration#2480
julhoang wants to merge 26 commits into
developfrom
julia/homepage-integration

Conversation

@julhoang

@julhoang julhoang commented Jun 4, 2026

Copy link
Copy Markdown
Collaborator

Issue: #2366

Summary & Context

Wires every card on the V3 homepage from mock data to live data — calendar events, ranked community posts, the featured library, project-wide commit stats, and CMS-managed testimonials — and extracts a dedicated ak/homepage.py adapter layer so the view stays a thin context assembler.

Changes

Hero

  • Wire primary CTA to docs-user-guide getting-started and secondary CTA to the latest libraries list via {% url %}

Upcoming Events card

  • Wire items to the Boost calendar via new core.calendar.upcoming_events() (flattens HomepageView.get_events() to the next N events, soonest first)
  • Add empty_message slot to _event_card.html for an "No Upcoming Events" empty state
  • Switch event date to a real date object: template formats it as Feb 15, 2026
  • Wire primary CTA to release-detail (latest) and secondary CTA to calendar

Posts from the Boost Community card

  • Wire items to ranked, published news.Entry records via new build_community_posts()
  • Add Entry.to_v3_post_card_dict() so the post-card shape lives on the model; reused by CommunityView
  • Wire primary CTA to the news URL

Get Started code block

⚠️ This component is getting a requirement + design change, so please ignore the changes introduced in this PR ⚠️

  • Wire to a featured library via build_get_started_code() + get_v3_featured_library() (falls back to a Hello, Boost. snippet with a TODO)
  • Wire "View library" button to library-detail for the featured library

Join developers card

  • Wire items to real destinations (Slack, contributor-guide FAQ, boost-announce mailing list) via new build_join_developers_links()
  • Wire primary CTA to the community URL

Install card

  • Extract INSTALL_PKG_MANAGERS / INSTALL_SYSTEM_INSTALL to new core/install_commands.py and adopt across HomepageView, CommunityView, LibraryDetail, and V3ComponentDemoView (previously duplicated from core.mock_data.SharedResources)

Why Boost cards

  • Wire why_boost_cards to WHY_BOOST_CARDS constant in ak/homepage.py with finalized copy and icons
  • Add new 16-unit icons (message, speed-fast, arrows-horizontal, users, building-community, zap, bookmarks) to includes/icon.html with icon_viewbox plumbed through _content_detail_card_item.html and _join_card.html; rename legacy slack glyph to message

Boost in numbers Card (Stats)

  • Wire bars to project-wide commit counts per minor release via new get_commit_data_by_release(); update heading/description and wire primary CTA to the Boost GitHub org
  • Carry commit_count through commit_data_to_stats_bars() and render a per-bar tooltip ("412 commits") in _stats_in_numbers.html
  • Fix responsive-limit-5-items rule to keep the last 5 bars on tablet/mobile (previously it was hiding the wrong ones)

Library Intro card

  • Wire to the featured library via build_library_intro(); add include_contributors=False so the homepage shows only authors + maintainers
  • Add HomepageSettings (Wagtail BaseGenericSetting) with a featured_library chooser scoped to flagship + core libraries present in the latest stable release (A→Z); falls back to a random pick when unset
  • Register wagtail.contrib.settings in INSTALLED_APPS

Testimonials card ("What engineers are saying")

  • Wire testimonials to live Testimonial pages via new testimonials.utils.get_testimonial_cards() (carousel-shaped dicts with cyclic prev/next slugs)
  • Add author_role (RichTextField, link-only) and author_avatar (ForeignKey to wagtailimages.Image) to Testimonial; role HTML flows through _user_profile.html as a SafeString so the embedded hyperlink renders
  • ‼️ Please note that the content that you see in your local environment might look slightly different from my screenshot since I had updated the CMS content on my end, please see Considerations section for content migration concerns ‼️

License card ("Build anything with the Boost Software License")

  • Inline the finalized multi-paragraph copy in homepage.html and wire the button to the license URL
  • Change _horizontal_card.html's text prop to render HTML via |safe (callers now own their <p> tags — Django tag parsing can't carry literal newlines)

Backend refactor & cleanup

  • Add ak/homepage.py adapter module (including hero_image_context() for hero image URLs); flatten HomepageView.get_v3_context_data() from nested dicts (stats_in_numbers.example_library_commits_bars, posts_from_the_boost_community.items, …) to flat keys per card
  • Centralize V3 card dict shapes on model methods: Entry.to_v3_post_card_dict(), CommitAuthor.to_v3_profile_dict() (mirrors User.to_v3_profile_dict(), both now return badge/bio keys for _user_profile.html)
  • Refactor build_library_intro_context() to delegate to to_v3_profile_dict() instead of hand-building author dicts; drop the obsolete medal/badge inline logic
  • Delete unused SharedResources entries (install command lists, join links, posts, events, hero URLs, library intro mock) now that homepage data is wired up; convert remaining release_notes mock dates to real date objects

Risks & Considerations

  • _horizontal_card.html's text prop is now |safe HTML; any other caller passing plain text will still render fine, but callers needing paragraph breaks must wrap their own <p> tags
  • CommitAuthor.to_v3_profile_dict() previously returned badge_url; it now returns badge/bio (matches User.to_v3_profile_dict). Grep for badge_url consumers before merging
  • Entry.to_v3_post_card_dict() now relies on Entry.author.to_v3_profile_dict(); entries authored by users without a display name will fall back to str(self)
  • ‼️ Testimonial Content ‼️
    V3 currently reads from the same pull quote field (along with many others) as the legacy testimonial view, even though V3 only needs a much shorter snippet (roughly one sentence). I considered two alternatives and ruled both out:
  1. Content migration – this risks affecting legacy data, and keeping both versions in sync would be difficult if legacy content changes in production.
  2. Duplicate V3 fields – this felt like overkill for a temporary content length difference.

Instead, the plan is to update the CMS content directly closer to the V3 launch date. Until then, V3 renders the legacy content as-is, which is not very notable since we truncate the rest of the long data anyways.

CMS Content V3 Render
image image

Peer-Testing Guidelines

‼️ Please ask me for the CALENDAR_API_KEY env key if you don't have it ‼️

  1. Pull this branch and run docker compose exec web python manage.py migrate (adds core.HomepageSettings and the new Testimonial.author_role / author_avatar fields).
  2. Open http://localhost:8000/ and confirm each homepage card renders with live data — no mock copy and no broken images. Hero, Upcoming Events, Posts, Get Started, Join, Install, Why Boost, Boost in numbers, Library Intro, Testimonials, and License card.
  3. In the Wagtail admin (http://localhost:8000/cms/), open Settings → Homepage Settings and set a featured library. Reload the homepage and confirm the Library Intro card reflect that library (and the "View library" / "View Library" buttons link to it).
Screenshot 2026-06-03 at 6 45 34 PM
  1. Clear the featured library, reload — the Library Intro card should fall back to a random flagship/core library from the latest stable release. The chooser dropdown should only list flagship + core libraries present in the latest stable release, A→Z.
  2. Edit any Testimonial page in the Wagtail admin, set author_role with a hyperlink and upload an author_avatar. Reload the homepage — the role text should render with the link inside _user_profile.html, and the avatar should appear in the carousel.
  3. Hover any bar in Boost in numbers — a tooltip should appear with <N> commits. On tablet/mobile (<1280px), only the last 5 bars should be visible (most recent releases).
  4. Verify hero CTAs and card CTAs all navigate to real destinations
  5. To exercise the Upcoming Events empty state, temporarily clear or break the calendar fetch (or test against a future date with no events) — the card should show "No Upcoming Events" rather than rendering an empty list.

Screenshots

Before After
Boost C__ Homepage · 6 50pm · 06-03 Boost C__ Homepage

Empty Event Card
Screenshot 2026-06-03 at 7 13 30 PM

Self-review Checklist

  • Link this PR to the related GitHub Project ticket

Frontend

  • UI implementation matches Figma design
  • Tested in light and dark mode
  • Responsive / mobile verified
  • Accessibility checked (keyboard navigation, etc.)
  • Ensure design tokens are used for colors, spacing, typography, etc. – No hardcoded values
  • Test without JavaScript (if applicable)
  • No console errors or warnings

@julhoang julhoang changed the title Julia/homepage integration Story 2366: Homepage Integration Jun 4, 2026
@julhoang julhoang linked an issue Jun 4, 2026 that may be closed by this pull request
@julhoang julhoang marked this pull request as ready for review June 4, 2026 02:38
julhoang added 25 commits June 4, 2026 12:02
Adds Entry.to_v3_post_card_dict() and fixes the two existing
to_v3_profile_dict() methods (User, CommitAuthor) to actually match
their template contract:
- 'badge_url' -> 'badge' (the dead key no template ever read)
- 'bio' added to CommitAuthor for the 6-key shape consistency
- User name fallback no longer returns the email-suffixed __str__

Reuses these methods to collapse two inline card dicts:
- CommunityView.get_v3_context_data: 20-line post-dict comprehension
- build_library_intro_context: 20-line author dict block, including a
  latent AttributeError on the dormant top_contributors branch.

POST_CARD_TAG_LABELS lives on news/models.py as the single source of
truth for category labels.
Moves per-card data shaping out of HomepageView.get_v3_context_data
and into ak/homepage.py:
- build_community_posts, build_join_developers_links,
  build_get_started_code, build_library_intro, hero_image_context
- WHY_BOOST_CARDS, HELLO_WORLD_SNIPPET, HERO_* constants at module
  scope so they allocate once at import, not per request

Flattens the card context wrappers ({'items': [...]}/'bars': [...])
so each context key carries a flat list. Chrome (heading, CTA,
variant, theme) moves into the homepage template, matching how
other V3 surfaces already pass these literals.

Co-locates event_to_card_dict + upcoming_events next to the rest of
the calendar pipeline in core/calendar.py.

HomepageView.get_v3_context_data goes from ~150 lines to ~40 lines
of one-key-per-line orchestration.
@julhoang julhoang force-pushed the julia/homepage-integration branch from 2dd07c5 to 41493c7 Compare June 4, 2026 19:03
@julioest julioest self-requested a review June 5, 2026 13:40
@herzog0 herzog0 self-requested a review June 12, 2026 15:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Webpage Integration: Home

2 participants