Add row selection and expand/collapse behavior matching Dave Winer's
blogroll.js: first click selects, second click (or caret click) expands
to show up to 5 recent items fetched from blogroll API. Items cached
after first fetch. Added dark mode styles for expanded items.
Replicates Dave Winer's blogroll.js visual rendering (240px bordered
container, Ubuntu/Rancho fonts, Title/When sort, caret wedges, truncated
titles, relative timestamps, "Powered by FeedLand" footer) using Alpine.js
and the blogroll API instead of jQuery + external scripts.
Registered in all three sidebar types (homepage, blog listing, blog post)
and in the fallback sidebar.
Sidebar widget now fetches blogs sorted by recently updated and groups
them into tabs by source type (Microsub/FeedLand). Tabs only appear
when multiple source types exist. Each tab shows up to 8 blogs.
When viewing a post that has mpUrl in its frontmatter, the FAB menu
shows an "Edit this post" link at the top that redirects to the
Indiekit admin edit form via /posts/edit?url=<mpUrl>.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- cv-projects-personal.njk: filters projects with projectType=personal (or unset)
- cv-projects-work.njk: filters projects with projectType=work
- CV page now only shows work projects
- Homepage section dispatcher routes both new types
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The defer + DOMContentLoaded queue approach failed silently when
pagefind-ui.js couldn't load. Moving the script to end of body
ensures all DOM elements exist and processes the queue immediately
after the script loads.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Pagefind CSS/JS is now loaded once in base.njk <head> with defer.
A tiny initPagefind() helper queues widget inits until DOMContentLoaded
when PagefindUI is available. Removes duplicate <link>/<script> tags
from all sidebar widgets, search page, and 404 page.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replaces the per-post webmentions sidebar widget (which was redundant
with the main content webmentions section) with a site-wide widget
showing recent inbound webmentions (via API) and outbound interactions
(from Eleventy collections). Available in all sidebars.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Post navigation (prev/next) now renders below the syndication block
in the main content flow, matching how listing pages work. Removed
from sidebar widget system.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Post navigation now uses previousInCollection/nextInCollection filters
to find adjacent posts (avoids Nunjucks loop scoping bug). Webmentions
sidebar widget now uses webmentionsForUrl and webmentionsByType filters
instead of non-existent filter function.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Fix recentPosts collection glob (content/posts/ → content/) so the
widget actually finds posts. Extract blog-sidebar widgets into reusable
partials. Make both sidebar.njk (listing pages) and blog-sidebar.njk
(post pages) configurable via homepageConfig.blogListingSidebar and
homepageConfig.blogPostSidebar, with fallback to current hardcoded
widgets for backward compatibility.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- New /changelog/ page with Alpine.js tabbed interface showing commits
across all indiekit repos, categorized into 7 groups with load-more
- Footer refactored from minimal feed links to responsive 4-zone grid:
Navigate, Content, Connect (social links), Meta (feeds + changelog)
- Footer uses grid-cols-2 on mobile, grid-cols-4 on desktop
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Prevents all layout shift by locking the content area to h-[340px]
with overflow-y-auto for scrolling if content exceeds the area.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add min-h-[320px] to prevent layout shift when switching tabs
- Show 5 items per tab for consistent content height
- Simplify tab buttons to text-only at text-xs for compact layout
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Tab order: Commits (default), Repos, Featured, PRs.
Repos tab fetches full repo list from GitHub public API.
Featured tab shows curated projects from /githubapi.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Uses Alpine.js client-side fetching from /githubapi/api/* for live data.
Three tabs: Projects (featured repos), Commits (recent activity), PRs.
Follows the blogroll widget pattern for dynamic data loading.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Integrates @11ty/eleventy-plugin-syntaxhighlight (PrismJS) for
build-time syntax highlighting of fenced code blocks. Includes
a custom GitHub-inspired theme with dark mode support (.dark class).
All existing articles with triple-backtick code blocks will
automatically get highlighting on next Eleventy rebuild.
Also fixes overflow-x: hidden on .prose/.e-content that was
clipping scrollable code blocks — changed to overflow-x: clip.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Recent Posts widget and Previous/Next navigation now show colored
icons and descriptive labels for likes, bookmarks, reposts, and
replies instead of "Untitled".
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Port the blog page's rich post-type rendering into both the homepage
recent-posts section and the sidebar widget. Likes, bookmarks, reposts,
replies, and photos now show colored icons, target URLs, and content
previews instead of generic "Untitled" cards.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
/now is already in the /slashes submenu dropdown, so having it
top-level was redundant. /cv gets promoted to main navbar.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Move CV content to a standalone /cv page that reuses the section partials
from the homepage builder. Simplify home.njk from a 3-tier to 2-tier
fallback (plugin config OR recent posts + explore links). Add /cv to
the slash pages navigation dropdown.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Change all webmention fetch URLs from /webmentions-api/api/mentions
to /webmentions/api/mentions to match the new @rmdes/indiekit-endpoint-webmention-io
plugin which replaces both the upstream viewer and the proxy plugin.
Build-time feed now fetches from local Indiekit API instead of
webmention.io directly.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Default tab is now "All Blogs" (the actual blogroll)
- Categories become individual tabs replacing single "Recent Posts"
- Items lazy-loaded per category with caching
- "Upcoming" badge on future-dated posts
- Removed category dropdown (tabs replace it)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Wraps footer items in a CSS grid that's 1 column on mobile, 2 on tablet,
3 on desktop. Each custom-html block fills one column.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Projects now show startDate/endDate range. Education supports both
startDate/endDate (new) and year (backward compat) display.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
_data/cv.js now reads from content/.indiekit/cv.json written by the
CV plugin, matching the homepageConfig.js pattern. Falls back to
empty defaults when no plugin is installed.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The homepage builder's sidebar bypass was using homepageConfig (a global
Eleventy data file) to suppress the sidebar on ALL pages, not just the
homepage. Now only bypasses when page.url == "/" so blog, post type, and
plugin pages keep their normal sidebar.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Homepage builder now renders footer section below main content
- Sidebar supports custom-html widget type with title + content
- New homepage-footer.njk component for footer items
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The search widget was only showing a heading with an empty div.
Now loads Pagefind CSS/JS and initializes the search UI.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- base.njk: skip hardcoded sidebar when homepage builder is active
- homepage-builder.njk: implement 3 layouts (single-column, two-column,
full-width-hero) with CSS grid and sidebar rendering
- homepage-section.njk: section type dispatcher (extracted for reuse)
- homepage-sidebar.njk: maps widget types to existing widget partials
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The hardcoded hero section was always rendering, causing a double hero
when the homepage plugin is configured and has its own hero enabled.
Now only shows for Tier 2 (CV) and Tier 3 (default) fallbacks.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
CONTENT_DIR env var wasn't set on Cloudron, so the data file tried
/data/content/.indiekit/homepage.json which doesn't exist. Now resolves
relative to the Eleventy project dir through the content/ symlink.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- cv-experience.njk: work history timeline with highlights
- cv-skills.njk: skills grid grouped by category
- cv-education.njk: education cards + language pills
- cv-projects.njk: project cards with status badges and tech tags
- cv-interests.njk: interest tag cloud
- Update homepage-builder.njk to include cv-education and cv-interests
Part of indiekit-endpoint-cv plugin integration (Phase 2).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- homepage-builder.njk: master section renderer for configured sections
- sections/hero.njk: hero section with avatar, name, title, bio, social
- sections/recent-posts.njk: configurable recent posts section
- sections/custom-html.njk: freeform HTML content block
- Wire home.njk Tier 1 to include homepage-builder when config exists
Part of indiekit-endpoint-homepage plugin integration.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Strip personal data from templates so the theme ships clean for any
deployer. Collection pages now use generatePageOnEmptyData so empty
post types show encouraging placeholders instead of 404s. Navigation
is conditional on enabled post types and installed plugins. Sidebar
widgets split into individual components with plugin-aware visibility.
Slashes page explains required plugins for root-level page creation.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When the webmentions proxy plugin is not installed or WEBMENTION_IO_TOKEN
is not set, the inbound tab now shows a clear setup guide instead of a
red error box and console errors. The filter buttons and webmention list
are hidden, and auto-refresh is skipped when not configured.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
HTML entities in href and value attributes don't decode properly -
browsers treat them as literal strings. Only obfuscate display text.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add obfuscateEmail Eleventy filter that converts email to HTML entities
- Apply to h-card.njk (both mailto: href and display text)
- Apply to blog-sidebar.njk hidden data element
- HTML entities block ~95% of spam harvesters while remaining valid
for IndieWeb microformat parsers (u-email for rel="me" auth)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Sidebar now includes h-card.njk instead of duplicating the code
- Updated h-card.njk with hidden u-photo and full social links
- Homepage hero: replace duplicate bio with unique intro text + Read more link
- Net reduction of ~100 lines by proper component reuse
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add social links nav with rel="me" to sidebar h-card (was only in
standalone h-card.njk component, never included by sidebar)
- Add hidden <data class="u-photo"> for reliable microformat parsing
(some parsers struggle with img nested inside links)
- Fix social links fallback in site.js: auto-generate from feed config
(GITHUB_USERNAME, BLUESKY_HANDLE, etc.) when SITE_SOCIAL is not set
- Add hidden email/org data elements to blog-sidebar compact h-card
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Subscribers discovering via HTML rel="self" subscribe to the
homepage topic, not the feed URL. Must notify hub for all
topic URLs so those subscriptions receive updates.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>