Skip to content

Link calendar entries back to their user group - #526

Merged
HeyItsGilbert merged 6 commits into
mainfrom
calendar-user-group-linking
Nov 3, 2026
Merged

HeyItsGilbert merged 6 commits into
mainfrom
calendar-user-group-linking

Conversation

@HeyItsGilbert

Copy link
Copy Markdown
Member

Summary

 themes/powershell-community/layouts/
 ├── _default/calendar.html        # upcoming card: <a> → <div>, title/arrow become their own links,
 │                                  # badge slotted into the meta row on both upcoming + past cards
 └── partials/
+    ├── calendar-matched-user-group.html   # match externalUrl's Meetup host → user-group page
+    └── calendar-user-group-badge.html     # render logo/icon + name link to /user-groups/<slug>/

 content/calendar/ohio-powershell-user-group.md   # drop now-redundant hand-written group link

 docs/adr/0006-calendar-user-group-linking.md     # why: runtime URL match, not a stored field
flowchart LR
  A[calendar entry<br/>Params.externalUrl] -->|meetup.com host| B[calendar-matched-user-group.html]
  B -->|scans| C[/user-groups/*.md<br/>Params.links/]
  C -->|slug match| D[matched Page]
  D --> E[calendar-user-group-badge.html]
  E -->|renders| F[logo/icon + name<br/>→ /user-groups/slug/]
Loading

Matching happens at render time against the Meetup slug embedded in both
the calendar entry's externalUrl and the user group's links[].url — no
new frontmatter field, no resync of existing entries. Rationale and
rejected alternatives (explicit userGroup field, hybrid) are in
ADR 0006.

Evidence

  • Before: calendar cards were visually identical regardless of source
    group; the whole card was one <a> to the external event, with no path
    back to the group's page (Ohio's one manual entry had a hand-written
    prose link as the only exception).
  • After: built the site with hugo --gc and inspected public/calendar/index.html:
    • 15/15 Meetup-linked entries (13 synced + 2 hand-authored, including one
      I'd initially miscategorized as a plain conference until its
      externalUrl turned out to be a Meetup link) render a badge to the
      correct /user-groups/<slug>/ page.
    • Groups with a logo (Ohio, Swiss, Inn-Salzach) render their image;
      groups without one (Hamburg, Research Triangle) fall back to the same
      fa-people-group icon the user-groups list page already uses.
    • Genuine non-group conferences (PSConfEU, Summit, SQL Saturday, Day of
      Data) confirmed to render with no badge — unchanged.

Merge Danger

Door: Two-way — template/partial change only, trivially revertable.

Blast Radius: /calendar/ page only. Upcoming-event cards change
structure (no longer one whole-card link; title and the arrow icon are now
separate click targets), which is a layout/interaction change worth a
visual check but not a breaking one — no other templates or content
schemas are touched.

Copilot AI balanced review requested due to automatic review settings November 3, 2026 16:53
@netlify

netlify Bot commented Nov 3, 2026 •

Copy link
Copy Markdown

✅ Deploy Preview for powershellorg ready!

Name Link
🔨 Latest commit 0298ba5
🔍 Latest deploy log https://app.netlify.com/projects/powershellorg/deploys/6aea355afd18baae6fb94473
😎 Deploy Preview https://deploy-preview-526--powershellorg.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

Unresolved issues include stale badge styles, incorrect Meetup URL matching, accessibility problems, and missing user-group links on individual event pages.

5 open issues
1 file not reviewed
  • assets/css/tailwind.css: Generated file
What changed in this PR

Adds links from calendar entries to their user-group pages by matching Meetup group slugs at Hugo build time, without adding front matter fields or resyncing events.

Changes:

  • Adds reusable group-matching and logo/name badge partials.
  • Displays badges on upcoming and past events, with separate event links on upcoming cards.
  • Documents the approach and removes Ohio’s hand-written group link.
File Description
themes/​powershell-community/​layouts/​partials/​calendar-user-group-badge.html Renders a linked group name with a logo or fallback icon.
themes/​powershell-community/​layouts/​partials/​calendar-matched-user-group.html Resolves an event’s Meetup slug to a user-group page.
themes/​powershell-community/​layouts/​_default/​calendar.html Adds badges and separates upcoming-card link targets.
docs/​adr/​0006-calendar-user-group-linking.md Records the matching decision, alternatives, and limitations.
content/​calendar/​ohio-powershell-user-group.md Removes the prose link to the Ohio group page.

Review effort: Balanced

Copilot AI balanced review requested due to automatic review settings November 3, 2026 17:00
@HeyItsGilbert

Copy link
Copy Markdown
Member Author

Fixed oversized user-group logo badges reported in the field. Added native width="20" height="20" attributes to the badge <img> so sizing is pinned at the HTML level, not solely by Tailwind classes — verified locally that the image stays 20×20 even with the stylesheet disabled entirely. Pushed in 9b2d502.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

A date-dependent CSS purge can fail CI when no upcoming events exist, while group matching, event-page navigation, and accessibility defects remain unresolved.

7 open issues
1 file not reviewed
  • assets/css/tailwind.css: Generated file

Review effort: Balanced

Copilot AI balanced review requested due to automatic review settings November 3, 2026 17:06

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🔵 Needs a closer look

The event-dependent CSS purge can cause CI failures as dates change, and group matching, event-page links, and accessibility issues remain unresolved.

7 open issues
1 previously missed issue

In code that hasn't changed since last review

Medium severity Mark the linked logo as decorative to avoid repeating the name

themes/​powershell-community/​layouts/​partials/​calendar-user-group-badge.html:10

The logo and adjacent group title are both included in the link's accessible name, so screen readers announce the group name twice. Since the text already identifies the destination, please mark the logo as decorative.

1 file not reviewed
  • assets/css/tailwind.css: Generated file

Review effort: Balanced

Calendar entries whose externalUrl is a Meetup link now render a small
logo/icon + name badge linking back to the owning user group's page,
matched at render time by Meetup URL host rather than a stored field
(see docs/adr/0006). Upcoming cards are restructured from a single
whole-card anchor to separate title and arrow links so the badge can
be its own link without nesting anchors. Removes the now-redundant
hand-written group link in the Ohio calendar entry.
The logo rendered oversized in the field (user report w/ screenshot);
Tailwind sizing classes alone weren't enough to constrain it in that
environment. Adding native width/height HTML attributes makes the
sizing robust independent of CSS load order/purge state — verified
locally that the image stays pinned at 20x20 even with Tailwind CSS
disabled entirely.
- Anchor Meetup host match to scheme+host (case-insensitive), no
  longer false-matches lookalike hosts like notmeetup.com
- Swap Tailwind v3-only classes (shrink-0, text-[10px]) for v2
  equivalents (flex-shrink-0, text-xs) actually supported by the
  pinned Tailwind 2.2.19 build
- Safelist group-hover:text-purple-600 in purgecss config since it
  only renders inside the upcoming-events loop and would otherwise be
  purged on a build with zero upcoming events
- Mark the badge logo as decorative (empty alt) since the adjacent
  group name already supplies the link's accessible name
- Give each upcoming-card arrow link a unique aria-label including
  the event title
- Drop opacity-75 from past-event cards so the badge (and all past
  card text) keeps sufficient contrast; existing gray tones already
  distinguish past from upcoming
- Render the group badge on individual calendar event pages too, so
  removing Ohio's hand-written prose link doesn't orphan that page
@HeyItsGilbert
HeyItsGilbert force-pushed the calendar-user-group-linking branch from 9b2d502 to f94ff29 Compare November 3, 2026 17:27
Copilot AI balanced review requested due to automatic review settings November 3, 2026 17:27
@HeyItsGilbert

Copy link
Copy Markdown
Member Author

Addressed every open review finding:

  • Meetup host matching — anchored the regex to ^https?://(?:www\.)?meetup\.com/, case-insensitive. Verified with go run against lookalikes (notmeetup.com, meetup.com.evil.com) and an uppercase-host URL — all behave correctly now.
  • Tailwind v2 compatibility — swapped shrink-0/text-[10px] (Tailwind v3-only syntax, silently absent from the pinned v2.2.19 build) for flex-shrink-0/text-xs.
  • Safelisted group-hover:text-purple-600 in purgecss.config.cjs since it only appears in the built HTML when an upcoming event exists — a CI run with zero upcoming events would otherwise purge it.
  • Decorative badge logo — alt="" on the <img>; the link's accessible name now comes once from the adjacent group-name text instead of twice.
  • Unique arrow aria-labels — now View details for {{ .Title }} per event instead of one repeated label.
  • Past-card contrast — dropped the card-wide opacity-75; the existing gray palette (bg/border/text) already reads as "past" without alpha-blending the new blue badge below 4.5:1.
  • Individual event pages — the calendar-matched-user-group partial now also renders on _default/single.html for the calendar section, so Ohio's event page (and every other group-linked event's own page) still links back to its group now that the hand-written prose link is gone.

All verified live: rebuilt assets/css/tailwind.css/icons (byte-identical, confirming nothing was missing), ran a local Hugo dev server, and checked in a real browser — decorative alt present, 3 unique arrow labels, past cards have no opacity-75, and the Ohio single event page now renders the group badge. Also rebased onto latest origin/main.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

- Add a persistent underline to the event-title link (previously only
  color-coded on hover, with the external-link icon hidden below md
  — no visible indicator at all on touch devices)
- Add a persistent underline to the group badge link for the same
  reason (blue-on-gray color alone is an insufficient indicator)
- Skip an optional locale prefix (e.g. /de-DE/) before the group slug
  when parsing Meetup URLs, so localized links don't parse 'de-DE' as
  the slug
- Compare extracted slugs case-insensitively, since group submissions
  preserve URL casing as entered while synced event URLs come from
  Meetup's own (lowercase) feed
Copilot AI balanced review requested due to automatic review settings November 3, 2026 19:00
@HeyItsGilbert

Copy link
Copy Markdown
Member Author

Addressed the 4th-round findings and resolved all review threads (11/11):

  • Persistent link indicators (non-color) — added underline to both the event-title link and the group badge link. Previously the title had no visible affordance until hover (and the external-link icon is hidden below md, so touch devices had zero indication it was tappable), and the badge's blue-on-gray was color-only.
  • Locale-prefixed Meetup URLs — the slug regex now skips an optional /xx-XX/ locale segment before capturing the group slug, so meetup.com/de-DE/powershell-usergroup-inn-salzach/ resolves to powershell-usergroup-inn-salzach, not de-DE. Verified with go run against a locale-prefixed, a plain, and a non-Meetup URL.
  • Case-insensitive slug comparison — group URLs preserve submitter casing while synced event URLs come from Meetup's own feed; slugs are now lowercased before comparing.

Also manually resolved the 5 threads that were still open from the prior round even though the fixes had already landed (Ohio's event page badge, Tailwind v2 class swap, the group-hover safelist, and past-card opacity) — GitHub's bot had auto-resolved some equivalent threads but not these, so I confirmed each fix against the pushed branch content before resolving.

Pushed as a91f5a3c2.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The previous locale-prefix regex used (?i) across the whole pattern,
so the lowercase-language/lowercase-region shape it was matching
(e.g. [a-z]{2}-[a-z]{2}) also matched legitimate two-letter-pair group
slugs like 'ps-ug': the group's own URL (.../ps-ug/) still resolved
correctly by regex backtracking, but its event URLs
(.../ps-ug/events/123/) misfired, consuming 'ps-ug' as a locale and
capturing 'events' as the slug instead.

Scope (?i) to the scheme+host only via Go's (?flags:re) syntax, and
require Meetup's actual locale convention — lowercase language,
UPPERCASE region (de-DE, en-US) — to recognize a locale prefix. Real
Meetup group slugs are always lowercase, so this cleanly disambiguates
without needing to inspect path depth. Verified with go run against
both the locale and two-letter-slug cases; confirmed no regression
against the 4 real synced groups (still 15/15 badges).
Copilot AI balanced review requested due to automatic review settings November 3, 2026 19:26
@HeyItsGilbert

Copy link
Copy Markdown
Member Author

Fixed the locale-detection regression (ps-ug style two-letter-pair group slugs misidentified as locale prefixes):

Scoped (?i) to scheme+host only (via Go's (?flags:re) syntax) and tightened the locale sub-pattern to require Meetup's actual convention — lowercase language, uppercase region (de-DE, en-US) — rather than any lowercase xx-xx shape. Real Meetup group slugs are always lowercase, so this cleanly distinguishes a locale prefix from a slug without needing to inspect path depth, and without the case-insensitive flag accidentally folding the region code to lowercase and making every two-letter-pair slug look like a locale.

Verified with go run against both cases (de-DE/groupslug/ and bare ps-ug/events/123/), and confirmed no regression against the live site: still 15/15 badges across all 4 real synced groups after rebuilding and checking in a browser.

Pushed as 0298ba5ad. All 12/12 review threads now resolved.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🔵 Needs a closer look

The icon-only link’s contrast against its background warrants human accessibility assessment for users with low vision.

No open issues 🎉

1 resolved since last review
1 file not reviewed
  • assets/css/tailwind.css: Generated file

Review effort: Balanced

@HeyItsGilbert
HeyItsGilbert merged commit cffbdca into main Nov 3, 2026
6 checks passed
@HeyItsGilbert
HeyItsGilbert deleted the calendar-user-group-linking branch November 3, 2026 19:53
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.

2 participants