Skip to content
Open
Show file tree
Hide file tree
Changes from 16 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
2fff9df
feat(2403): wire up learn page
ycanales May 16, 2026
4b41b69
Bug: Learn Page correct post card and community card display issues
jlchilders11 May 8, 2026
4572f92
Update community card inputs
jlchilders11 May 8, 2026
68148fa
PR feedback
jlchilders11 May 8, 2026
83f33ae
PR feedback
jlchilders11 May 11, 2026
8c08a20
PR feedback: spacing adjustments
jlchilders11 May 12, 2026
0266f1b
Correct inconsistent max width on mobile
jlchilders11 May 18, 2026
9d73e8e
QA feedback: update post cards arguments
jlchilders11 May 20, 2026
dc6f00f
QA Feedback: Add icon to community card
jlchilders11 May 20, 2026
4a3ddc5
Merge branch 'develop' into cy/2403-learn-page
ycanales May 20, 2026
03844dc
Merge branch 'jc/bug-correct-learn-page' into cy/2403-learn-page
ycanales May 20, 2026
e8219c3
Merge branch 'develop' into cy/2403-learn-page
ycanales May 20, 2026
aa9ad5e
fix(2403): shorten buttons in mobile viewport as it is in figma
ycanales May 21, 2026
621581f
fix: relative URLs
ycanales May 22, 2026
358970e
fix: adjust params (community_card and Entry's show_badge)
ycanales May 22, 2026
a3aaa28
fix: Exclude categories without name
ycanales May 22, 2026
e5da24b
fix: filter out soft deleted posts
ycanales May 25, 2026
4dab468
2403: simplify panels list, add stub for wagtail posts
ycanales May 25, 2026
6a663e0
2403: move arrow-down-right icon into icon component
ycanales May 26, 2026
a5e9239
2403: use reverse for boost-history link
ycanales May 26, 2026
80dd8ec
2403: move info_card and calendar_card from view to template
ycanales May 26, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions config/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
CommunityView,
DocLibsTemplateView,
ImageView,
LearnPageView,
MarkdownTemplateView,
TermsOfUseView,
PrivacyPolicyView,
Expand Down Expand Up @@ -181,6 +182,7 @@
),
path("health/", include("health_check.urls")),
path("asciidoctor_sandbox/", include("asciidoctor_sandbox.urls")),
path("learn/", LearnPageView.as_view(), name="learn"),
path("community/", CommunityView.as_view(), name="community"),
path(
"community/<boostversionslug:version_slug>/",
Expand Down
3 changes: 2 additions & 1 deletion core/context_processors.py
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ class NavItem(StrEnum):
"/doc/libs/": NavItem.LIBRARIES, # special case - handle first
"/doc/": NavItem.LEARN,
"/docs/": NavItem.LEARN,
"/learn/": NavItem.LEARN,
"/boost-development/": NavItem.LEARN,
"/news/": NavItem.NEWS,
"/community/": NavItem.COMMUNITY,
Expand Down Expand Up @@ -217,7 +218,7 @@ def header_context(request):
"""Context processor for header nav links."""
nav_links = [
NavLink(label="Libraries", url=reverse("libraries"), nav_id="libraries"),
NavLink(label="Learn", url=reverse("docs"), nav_id="learn"),
NavLink(label="Learn", url=reverse("learn"), nav_id="learn"),
NavLink(label="Community", url=reverse("community"), nav_id="community"),
NavLink(
label="Posts", url=reverse("news"), nav_id="news", is_unread=True
Expand Down
222 changes: 123 additions & 99 deletions core/views.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import os
import random
import re

import requests
from django.db.models import Count
from django.utils import timezone

from textwrap import dedent
Expand Down Expand Up @@ -86,8 +88,10 @@
save_rendered_content,
)

from libraries.models import Library, LibraryVersion, Tier

from libraries.models import Category, Library, LibraryVersion, Tier
from news.models import Entry
from news.services import get_latest_post_cards
from libraries.utils import (
get_commit_data_by_release_for_library,
commit_data_to_stats_bars,
Expand Down Expand Up @@ -506,155 +510,175 @@ def get_v3_context_data(self, **kwargs):
ctx["learn_card_data"] = [
{
"title": "I want to learn:",
"text": "How to install Boost, use its libraries, build projects, and get help when you need it.",
"text": (
"How to install Boost, use its libraries, build projects, "
"and get help when you need it."
),
"links": [
{
"label": "Explore common use cases",
"url": "https://www.example.com",
"url": "/doc/user-guide/common-introduction.html",
},
{
"label": "Build with CMake",
"url": "/doc/user-guide/building-with-cmake.html",
},
{
"label": "Visit the FAQ",
"url": "/doc/user-guide/faq.html",
},
{"label": "Build with CMake", "url": "https://www.example.com"},
{"label": "Visit the FAQ", "url": "https://www.example.com"},
],
"url": "https://www.example.com",
"label": "Learn more about Boost",
"url": "/doc/user-guide/getting-started.html",
"label": "Get started with Boost",
"image_src": large_static("/img/v3/learn-page/learn-cheetah.png"),
"mobile_image_src": large_static(
"/img/v3/learn-page/cheetah-mobile.png"
),
},
{
"title": "I want to learn:",
"text": "How to install Boost, use its libraries, build projects, and get help when you need it.",
"title": "I want to contribute:",
"text": (
"How to contribute to Boost, propose new libraries, "
"and engage in formal reviews."
),
"links": [
{
"label": "Explore common use cases",
"url": "https://www.example.com",
"label": "Contribute to an existing library",
"url": "/doc/contributor-guide/contributors-faq.html",
},
{
"label": "Learn about formal reviews",
"url": "/doc/formal-reviews/submissions.html",
},
{
"label": "Visit the Contributors FAQ",
"url": "/doc/contributor-guide/contributors-faq.html",
},
{"label": "Build with CMake", "url": "https://www.example.com"},
{"label": "Visit the FAQ", "url": "https://www.example.com"},
],
"url": "https://www.example.com",
"label": "Learn more about Boost",
"image_src": large_static("img/v3/learn-page/learn-octopus.png"),
"url": "/doc/contributor-guide/requirements/library-requirements.html",
"label": "Propose a new library",
"image_src": large_static("/img/v3/learn-page/learn-octopus.png"),
"mobile_image_src": large_static(
"/img/v3/learn-page/octopus-mobile.png"
),
},
]
Comment thread
ycanales marked this conversation as resolved.

demo_cards = [
{
"title": "Get help",
"description": "Tap into quick answers, networking, and chat with 24,000+ members.",
"cta_label": "Start here",
"cta_href": reverse("community"),
},
{
"title": "Documentation",
"description": "Browse library docs, examples, and release notes in one place.",
"cta_label": "View docs",
"cta_href": reverse("docs"),
},
{
"title": "Community",
"description": "Mailing lists, GitHub, and community guidelines for contributors.",
"cta_label": "Join",
"cta_href": reverse("community"),
},
{
"title": "Releases",
"description": "Latest releases, download links, and release notes.",
"cta_label": "Download",
"cta_href": reverse("releases-most-recent"),
},
ctx["library_cards"] = self._build_category_cards()

# Copy mirrors the Figma frame at node 1849:49695. The design currently
# has two cards titled "Modern approach to C++" — flagged to design.
Comment on lines +569 to +570
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we follow up with design and remove this comment from code? 🙏

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll update once we get news from @rbbeeston 👍

ctx["why_boost_cards"] = [
{
"title": "Libraries",
"description": "Explore the full catalog of Boost C++ libraries with docs and metadata.",
"cta_label": "Browse libraries",
"cta_href": reverse("libraries"),
"title": "Modern approach to C++",
"description": "Skip months of development with production-ready solutions.",
},
{
"title": "News",
"description": "Blog posts, announcements, and community news from the Boost project.",
"cta_label": "Read news",
"cta_href": reverse("news"),
"title": "Write safer code",
"description": "Peer-reviewed by C++ standards committee members.",
},
{
"title": "Getting started",
"description": "Step-by-step guides to build and use Boost in your projects.",
"cta_label": "Get started",
"cta_href": reverse("getting-started"),
"title": "Make real impact",
"description": "Your code could power millions of apps & shape the future of C++.",
},
{
"title": "Resources",
"description": "Learning resources, books, and other materials for Boost users.",
"cta_label": "View resources",
"cta_href": reverse("resources"),
"title": "Modern approach to C++",
"description": "We embrace contemporary C++ practices, leveraging the latest language features.",
},
{
"title": "Calendar",
"description": "Community events, meetings, and review schedule.",
"cta_label": "View calendar",
"cta_href": reverse("calendar"),
"title": "Template-heavy by design",
"description": "Maximum flexibility with compile-time guarantees.",
},
{
"title": "Donate",
"description": "Support the Boost Software Foundation and open-source C++.",
"cta_label": "Donate",
"cta_href": reverse("donate"),
"title": "Independent but consistent",
"description": "Each library is built by a small, dedicated team with shared standards.",
},
]

ctx["library_cards"] = demo_cards
ctx["why_boost_cards"] = demo_cards[:6]
ctx["calendar_card"] = {
"title": "Boost is released three times a year",
"text": "Each release has updates to existing libraries, and any new libraries that have passed the rigorous acceptance process.",
"primary_button_url": "www.example.com",
"primary_button_label": "View the Release Calendar",
"secondary_button_url": "www.example.com",
"secondary_button_label": "Secondary Button",
"text": (
"Each release has updates to existing libraries, and any new "
"libraries that have passed the rigorous acceptance process."
),
"primary_button_url": reverse("calendar"),
"primary_button_label": "View release calendar",
"image": large_static("/img/v3/demo-page/calendar.png"),
}
ctx["info_card"] = {
"title": "How we got here",
"text": "Since 1998, Boost has been where C++ innovation happens. What started with three developers has grown into the foundation of modern C++ development.",
"primary_button_url": "www.example.com",
"primary_button_label": "Explore Our History",
"text": (
"Since 1998, Boost has been where C++ innovation happens. What "
"started with three developers has grown into the foundation of "
"modern C++ development."
),
"primary_button_url": "/doc/user-guide/boost-history.html",
"primary_button_label": "Explore our history",
}
ctx["post_cards_data"] = {
"heading": "Posts from the Boost Community",
"view_all_url": "#",
"view_all_label": "View All Posts",
"variant": "Content Card",
"posts": SharedResources.demo_posts[0:4],
"heading": "Posts from the Boost community",
"view_all_url": reverse("news"),
"view_all_label": "View all posts",
"posts": get_latest_post_cards(limit=4),
}
ctx["boost_community_data"] = {
"heading": "The Boost community",
"view_all_url": "#",
"view_all_label": "Explore the community",
"posts": 3
* [
"primary_cta_label": "Explore the community",
"primary_cta_url": reverse("community"),
"items": [
{
"title": "A talk by Richard Thomson at the Utah C++ Programmers Group",
"description": "Lorem Ispum Sum Delores",
"url": "#",
"date": "03/03/2025",
"category": "Issues",
"tag": "beast",
"author": {
"name": "Richard Thomson",
"role": "Contributor",
"show_badge": True,
"avatar_url": large_static("img/v3/demo-page/avatar.png"),
},
"cta_url": "#",
"cta_label": "Learn More",
}
"title": "Stay up to date",
"description": "Watch the Boost GitHub org for the latest releases and activity.",
"cta_url": "https://github.com/boostorg/boost",
"cta_label": "Watch now",
},
{
"title": "Get help",
"description": "Chat with thousands of C++ developers on the CPPLang Slack.",
"cta_url": "https://cppalliance.org/slack/",
"cta_label": "Join now",
},
{
"title": "Fix an issue",
"description": "Browse open issues and contribute fixes on GitHub.",
"cta_url": "https://github.com/boostorg/boost/issues",
"cta_label": "Get involved",
},
],
}
return ctx

@staticmethod
def _build_category_cards():
"""Return library categories shuffled per request, with live counts."""
categories = list(
Category.objects.annotate(library_count=Count("libraries", distinct=True))
.filter(library_count__gt=0)
.exclude(name__isnull=True)
.exclude(name="")
.only("name", "slug", "short_description")
Comment thread
ycanales marked this conversation as resolved.
)
random.shuffle(categories)
cards = []
for category in categories:
cards.append(
{
"title": category.name,
"description": category.short_description,
"badge_count": category.library_count,
"cta_label": "Start here",
"cta_href": reverse(
"libraries-list",
kwargs={
"version_slug": LATEST_RELEASE_URL_PATH_STR,
"library_view_str": "categorized",
"category_slug": category.slug,
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this is doing anything currently. We should probably create a follow-up ticket to wire this up correctly to what @julhoang did in her pr #2420

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If @julhoang's PR merges first I could adjust it here, or in a follow-up ticket, whatever's best 👍

},
),
}
)
return cards


class ContentNotFoundException(Exception):
pass
Expand Down
3 changes: 2 additions & 1 deletion libraries/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,9 +162,10 @@ def merge_authors(self, request, queryset):

@admin.register(Category)
class CategoryAdmin(admin.ModelAdmin):
list_display = ["name"]
list_display = ["name", "short_description"]
ordering = ["name"]
search_fields = ["name"]
fields = ["name", "slug", "short_description"]


class LibraryVersionInline(admin.TabularInline):
Expand Down
22 changes: 22 additions & 0 deletions libraries/migrations/0040_category_short_description.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Generated by Django 6.0.2 on 2026-05-14 16:27

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
("libraries", "0039_flag_known_bot_commit_authors"),
]

operations = [
migrations.AddField(
model_name="category",
name="short_description",
field=models.TextField(
blank=True,
default="",
help_text="Short marketing copy shown on the Learn page category carousel.",
),
),
]
5 changes: 5 additions & 0 deletions libraries/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,11 @@ class Category(models.Model):

name = models.CharField(max_length=100)
slug = models.SlugField(blank=True, null=True)
short_description = models.TextField(
blank=True,
default="",
help_text="Short marketing copy shown on the Learn page category carousel.",
)

class Meta:
verbose_name_plural = "Categories"
Expand Down
Loading
Loading