From 8ca1c65d1575b7c370839140a0be826f28c03f04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20de=20Courville?= Date: Thu, 10 Sep 2026 14:49:24 +0200 Subject: [PATCH 1/2] Add organizer partner pages This change adds a new Discover our Partners section to the Organizer Kit, including partner cards, hidden detail pages, and navigation support for published partner entries. It also updates the docs layout to support back links and heading logos, adds Butter as a sponsor logo, and refines sponsor/footer styling for the new partner content. --- AGENTS.md | 2 + pcd-website/src/components/Footer.astro | 15 +++--- pcd-website/src/components/PartnerCards.astro | 24 +++++++++ pcd-website/src/config/organizer-kit-nav.ts | 6 ++- pcd-website/src/config/sponsors.ts | 6 +++ pcd-website/src/content.config.ts | 8 ++- .../organizer-kit/partner-pages/butter.md | 21 ++++++++ .../partner-pages/openprocessing.md | 23 ++++++++ .../src/content/organizer-kit/partners.md | 7 +++ pcd-website/src/images/butter_logo.svg | 1 + pcd-website/src/layouts/DocsLayout.astro | 30 +++++++++-- .../src/pages/organize/[...slug].astro | 17 +++++- pcd-website/src/styles/prose.css | 53 +++++++++++++++++++ 13 files changed, 195 insertions(+), 18 deletions(-) create mode 100644 pcd-website/src/components/PartnerCards.astro create mode 100644 pcd-website/src/content/organizer-kit/partner-pages/butter.md create mode 100644 pcd-website/src/content/organizer-kit/partner-pages/openprocessing.md create mode 100644 pcd-website/src/content/organizer-kit/partners.md create mode 100644 pcd-website/src/images/butter_logo.svg diff --git a/AGENTS.md b/AGENTS.md index 586624b8..65df7835 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -59,6 +59,8 @@ No install needed — `open-location-code` is already available at `pcd-website/ - **Astro** owns routing, layouts, metadata, and static content pages. `src/layouts/BaseLayout.astro` provides the document shell; `MapLayout.astro`, `SiteLayout.astro`, and `DocsLayout.astro` provide the map, standard content, and Organizer Kit shells respectively. - The Organizer Kit introduction lives in `src/content/organizer-kit/getting-started/introduction.md`; `/organize/` redirects to its canonical `/organize/getting-started/introduction/` route. +- The Organizer Kit's `partners.md` supplies the “Discover our Partners” overview introduction. `PartnerCards.astro` renders published Organizer Kit entries with `partnerCard` frontmatter, sorted by `order` then title. Each partner detail page in `src/content/organizer-kit/partner-pages/` owns its card's `logo` (relative image path validated by Astro), `summary` (one paragraph leading with the participant or organizer benefit, followed by a short partner description); its title and route supply the card name and link. The same data supplies the overview's shared Markdown and the detail-page logo. Detail pages use `hideFromNav: true` to stay published while being omitted from both shared navigation trees and prev/next links; `draft: true` still excludes a page from build output and cards. Partner card styles live in `src/styles/prose.css`. +- Partner detail routes pass their logo to `DocsLayout` through its optional `headingLogo` prop; the image stays inside the h1 with the page title as alt text. Its optional `backLink` prop renders the shared `BackButton` above the heading in place of the eyebrow; partner pages link back to `/organize/partners/`. - **Vue** handles the interactive map UI as `client:only="vue"` island components. Map-specific interactive features belong in Vue; static site and Organizer Kit pages belong in Astro and Markdown content collections. The map filter drawer in `MapView.vue` filters clustered markers by date (future, past, or all), format, and activity type; checkbox choices are ORed within a group and filter groups are ANDed together. ### Event list diff --git a/pcd-website/src/components/Footer.astro b/pcd-website/src/components/Footer.astro index 6501a781..3310ad44 100644 --- a/pcd-website/src/components/Footer.astro +++ b/pcd-website/src/components/Footer.astro @@ -179,22 +179,19 @@ const UTILITY_LINKS = [ .sponsor-logo { display: inline-flex; align-items: center; - padding: 0.5rem 0.625rem; - border: 1px solid var(--color-border); - border-radius: 4px; - background: #fff; + padding: 0.5rem 0; } .sponsor-logo img { display: block; - width: 200px; + width: auto; max-width: 100%; - height: auto; + height: 30px; + object-fit: contain; } - .sponsor-logo:hover { - border-color: var(--color-primary); - color: var(--color-primary); + .sponsor-logo:hover img { + opacity: 0.8; } .social-row { diff --git a/pcd-website/src/components/PartnerCards.astro b/pcd-website/src/components/PartnerCards.astro new file mode 100644 index 00000000..448ec4c5 --- /dev/null +++ b/pcd-website/src/components/PartnerCards.astro @@ -0,0 +1,24 @@ +--- +import { Image } from 'astro:assets'; +import { kitHref, type KitEntry } from '../config/organizer-kit-nav'; + +interface Props { + partners: KitEntry[]; +} + +const { partners } = Astro.props; +--- + +
+ {partners.map((partner) => { + const card = partner.data.partnerCard; + if (!card) return null; + return ( +
+

{partner.data.title}

+

{card.summary}

+

Learn more about {partner.data.title} →

+
+ ); + })} +
diff --git a/pcd-website/src/config/organizer-kit-nav.ts b/pcd-website/src/config/organizer-kit-nav.ts index 67a633f6..ef0a60e7 100644 --- a/pcd-website/src/config/organizer-kit-nav.ts +++ b/pcd-website/src/config/organizer-kit-nav.ts @@ -32,6 +32,7 @@ const TOP_LEVEL: ReadonlyArray = [ { page: 'peer-support-sessions' }, { page: 'code-of-conduct' }, { page: 'faq' }, + { page: 'partners' }, { page: 'about-processing-foundation' }, { page: 'contact' }, { page: 'documents' }, @@ -49,13 +50,14 @@ function toPage(entry: KitEntry): KitPage { /** * Builds the sidebar tree by walking TOP_LEVEL and pulling matching entries out - * of the collection. Throws if an entry exists that TOP_LEVEL never places, so + * of the collection. Pages with `hideFromNav` remain published but are omitted. + * Throws if any other entry exists that TOP_LEVEL never places, so * adding a Markdown file without listing it here fails the build rather than * silently producing an unreachable page. */ export async function getKitNav(): Promise { const allEntries = await getCollection('organizerKit'); - const entries = allEntries.filter((entry) => !entry.data.draft); + const entries = allEntries.filter((entry) => !entry.data.draft && !entry.data.hideFromNav); const allIds = new Set(allEntries.map((entry) => entry.id)); const byId = new Map(entries.map((entry) => [entry.id, entry])); diff --git a/pcd-website/src/config/sponsors.ts b/pcd-website/src/config/sponsors.ts index d219ccef..2fbd121a 100644 --- a/pcd-website/src/config/sponsors.ts +++ b/pcd-website/src/config/sponsors.ts @@ -1,5 +1,6 @@ import type { ImageMetadata } from 'astro'; import openProcessingLogo from '../images/openprocessing_logo.svg'; +import butterLogo from '../images/butter_logo.svg'; export interface Sponsor { name: string; @@ -13,4 +14,9 @@ export const SPONSORS: Sponsor[] = [ href: 'https://openprocessing.org', logo: openProcessingLogo, }, + { + name: 'Butter', + href: 'https://www.butter.video/', + logo: butterLogo, + }, ]; diff --git a/pcd-website/src/content.config.ts b/pcd-website/src/content.config.ts index a9985619..17f926c8 100644 --- a/pcd-website/src/content.config.ts +++ b/pcd-website/src/content.config.ts @@ -31,7 +31,7 @@ const pages = defineCollection({ const organizerKit = defineCollection({ loader: glob({ base: './src/content/organizer-kit', pattern: '**/*.md' }), - schema: z.object({ + schema: ({ image }) => z.object({ title: z.string(), // Sidebar grouping. `section` is the parent group's title; standalone // top-level pages omit it. `order` sorts a page within its section — the @@ -39,9 +39,15 @@ const organizerKit = defineCollection({ section: z.string().optional(), order: z.number().default(0), description: z.string().optional(), + partnerCard: z.object({ + logo: image(), + summary: z.string().min(1), + }).optional(), // Excludes the page from the sidebar and from build output entirely, for // TBD pages that shouldn't be publicly reachable yet. draft: z.boolean().default(false), + // Keeps a page published while omitting it from navigation and prev/next links. + hideFromNav: z.boolean().default(false), // Suppresses the "On this page" table of contents, for short pages whose // headings aren't worth navigating. hideToc: z.boolean().default(false), diff --git a/pcd-website/src/content/organizer-kit/partner-pages/butter.md b/pcd-website/src/content/organizer-kit/partner-pages/butter.md new file mode 100644 index 00000000..51149755 --- /dev/null +++ b/pcd-website/src/content/organizer-kit/partner-pages/butter.md @@ -0,0 +1,21 @@ +--- +title: Butter +hideFromNav: true +order: 1 +description: Free Butter Pro for PCD participants in October 2026 +draft: false +hideToc: true +partnerCard: + logo: ../../../images/butter_logo.svg + summary: Get free access to Butter Pro as a PCD participant during October 2026 and build a tool to get a chance to win a cash prize. +--- + +[Butter](https://www.butter.video/) is an online video editor with customizable blocks for motion graphics, animated type, and visual effects. + +## Butter Pro in October + +Butter is offering PCD participants access to Butter Pro during October 2026. Details on how to claim access will be shared here when available. + +## Creative Coding Challenge + +Details TBD diff --git a/pcd-website/src/content/organizer-kit/partner-pages/openprocessing.md b/pcd-website/src/content/organizer-kit/partner-pages/openprocessing.md new file mode 100644 index 00000000..3afd1683 --- /dev/null +++ b/pcd-website/src/content/organizer-kit/partner-pages/openprocessing.md @@ -0,0 +1,23 @@ +--- +title: OpenProcessing +hideFromNav: true +order: 2 +description: One free month of OpenProcessing ProfessorPlus +draft: false +hideToc: true +partnerCard: + logo: ../../../images/openprocessing_logo.svg + summary: Get one free month of ProfessorPlus membership for your workshop during October 2026. +--- + +[OpenProcessing](https://openprocessing.org/) is a creative coding platform and community for creating, sharing, and exploring sketches in the browser. + +## Free ProfessorPlus for your workshop + +Sinan from OpenProcessing is offering PCD organizers one free month of ProfessorPlus membership for their workshop during October 2026. + +You can use the membership to try features such as collaborative code editing in your workshop. + +## How to request access + +Contact Sinan at OpenProcessing directly to request the one-month ProfessorPlus membership for your PCD workshop. diff --git a/pcd-website/src/content/organizer-kit/partners.md b/pcd-website/src/content/organizer-kit/partners.md new file mode 100644 index 00000000..93d20863 --- /dev/null +++ b/pcd-website/src/content/organizer-kit/partners.md @@ -0,0 +1,7 @@ +--- +title: Discover our Partners +description: Meet our partners and explore what they offer PCD organizers. +hideToc: true +--- + +Meet the platforms supporting our community and discover what they offer PCD organizers. diff --git a/pcd-website/src/images/butter_logo.svg b/pcd-website/src/images/butter_logo.svg new file mode 100644 index 00000000..3e66d58f --- /dev/null +++ b/pcd-website/src/images/butter_logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/pcd-website/src/layouts/DocsLayout.astro b/pcd-website/src/layouts/DocsLayout.astro index 8c424068..845b7a41 100644 --- a/pcd-website/src/layouts/DocsLayout.astro +++ b/pcd-website/src/layouts/DocsLayout.astro @@ -1,11 +1,13 @@ --- -import type { MarkdownHeading } from 'astro'; +import type { ImageMetadata, MarkdownHeading } from 'astro'; +import { Image } from 'astro:assets'; import BaseLayout from './BaseLayout.astro'; import Header from '../components/Header.astro'; import Footer from '../components/Footer.astro'; import DocsSidebar from '../components/DocsSidebar.astro'; import DocsTableOfContents from '../components/DocsTableOfContents.astro'; import DocsPageActions from '../components/DocsPageActions.astro'; +import BackButton from '../components/BackButton.astro'; import { getKitNav } from '../config/organizer-kit-nav'; import '../styles/base.css'; import '../styles/docs.css'; @@ -15,8 +17,12 @@ interface Props { description: string; /** Rendered above the h1 as the section label. */ eyebrow?: string; + /** Parent navigation shown in place of the eyebrow. */ + backLink?: { href: string; label: string }; /** Page heading. Falls back to `title` when omitted. */ heading?: string; + /** Optional logo displayed within the h1, using the heading as alt text. */ + headingLogo?: ImageMetadata; headings?: MarkdownHeading[]; /** Suppresses the "On this page" table of contents. */ hideToc?: boolean; @@ -26,7 +32,7 @@ interface Props { editHref?: string; } -const { title, description, eyebrow, heading, headings = [], hideToc = false, markdown, editHref } = Astro.props; +const { title, description, eyebrow, backLink, heading, headingLogo, headings = [], hideToc = false, markdown, editHref } = Astro.props; const nav = await getKitNav(); const permalink = new URL(Astro.url.pathname, Astro.site ?? Astro.url.origin).href; @@ -49,9 +55,13 @@ const permalink = new URL(Astro.url.pathname, Astro.site ?? Astro.url.origin).hr
- {eyebrow &&

{eyebrow}

} + {backLink + ? + : eyebrow &&

{eyebrow}

}
-

{heading ?? title}

+

{headingLogo + ? + : heading ?? title}

{markdown && editHref && ( )} @@ -64,6 +74,18 @@ const permalink = new URL(Astro.url.pathname, Astro.site ?? Astro.url.origin).hr