From b4bc2f6f07dcd5d4be11e6294a8ee5a609c8332f Mon Sep 17 00:00:00 2001 From: Ricardo Date: Sun, 8 Feb 2026 19:08:27 +0100 Subject: [PATCH] feat: wire homepage builder layout system and sidebar control - 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 --- _includes/components/homepage-builder.njk | 114 ++++++++++++++-------- _includes/components/homepage-section.njk | 30 ++++++ _includes/components/homepage-sidebar.njk | 28 ++++++ _includes/layouts/base.njk | 5 +- 4 files changed, 138 insertions(+), 39 deletions(-) create mode 100644 _includes/components/homepage-section.njk create mode 100644 _includes/components/homepage-sidebar.njk diff --git a/_includes/components/homepage-builder.njk b/_includes/components/homepage-builder.njk index d0c7807..da718e5 100644 --- a/_includes/components/homepage-builder.njk +++ b/_includes/components/homepage-builder.njk @@ -1,45 +1,83 @@ {# - Homepage Builder - renders configured sections from homepageConfig - Used when indiekit-endpoint-homepage plugin is installed and configured + Homepage Builder - renders configured layout, sections, and sidebar + from homepageConfig (written by indiekit-endpoint-homepage plugin) #} +{% set layout = homepageConfig.layout or "two-column" %} +{% set hasSidebar = homepageConfig.sidebar and homepageConfig.sidebar.length %} + +{# Hero — rendered before layout wrapper when enabled #} {% if homepageConfig.hero and homepageConfig.hero.enabled %} {% include "components/sections/hero.njk" %} {% endif %} -
- {% for section in homepageConfig.sections %} - {% if section.type == "hero" %} - {# Hero is handled above #} - {% elif section.type == "recent-posts" %} - {% include "components/sections/recent-posts.njk" %} - {% elif section.type == "custom-html" %} - {% include "components/sections/custom-html.njk" %} - {% elif section.type == "cv-experience" %} - {% include "components/sections/cv-experience.njk" ignore missing %} - {% elif section.type == "cv-projects" %} - {% include "components/sections/cv-projects.njk" ignore missing %} - {% elif section.type == "cv-skills" %} - {% include "components/sections/cv-skills.njk" ignore missing %} - {% elif section.type == "cv-education" %} - {% include "components/sections/cv-education.njk" ignore missing %} - {% elif section.type == "cv-interests" %} - {% include "components/sections/cv-interests.njk" ignore missing %} - {% elif section.type == "blogroll" %} - {% include "components/sections/blogroll.njk" ignore missing %} - {% elif section.type == "podroll" %} - {% include "components/sections/podroll.njk" ignore missing %} - {% elif section.type == "github-activity" %} - {% include "components/sections/github-activity.njk" ignore missing %} - {% elif section.type == "youtube" %} - {% include "components/sections/youtube.njk" ignore missing %} - {% elif section.type == "funkwhale" %} - {% include "components/sections/funkwhale.njk" ignore missing %} - {% elif section.type == "lastfm" %} - {% include "components/sections/lastfm.njk" ignore missing %} - {% else %} - {# Unknown section type - log warning #} - - {% endif %} - {% endfor %} -
+{# Layout wrapper #} +{% if layout == "single-column" %} + + {# Single column — no sidebar, full width sections #} +
+ {% for section in homepageConfig.sections %} + {% if section.type != "hero" %} + {% include "components/homepage-section.njk" %} + {% endif %} + {% endfor %} +
+ +{% elif layout == "two-column" and hasSidebar %} + + {# Two column — sections + sidebar #} +
+
+
+ {% for section in homepageConfig.sections %} + {% if section.type != "hero" %} + {% include "components/homepage-section.njk" %} + {% endif %} + {% endfor %} +
+
+ +
+ +{% elif layout == "full-width-hero" %} + + {# Full width hero (already rendered above), then two-column below #} + {% if hasSidebar %} +
+
+
+ {% for section in homepageConfig.sections %} + {% if section.type != "hero" %} + {% include "components/homepage-section.njk" %} + {% endif %} + {% endfor %} +
+
+ +
+ {% else %} +
+ {% for section in homepageConfig.sections %} + {% if section.type != "hero" %} + {% include "components/homepage-section.njk" %} + {% endif %} + {% endfor %} +
+ {% endif %} + +{% else %} + + {# Fallback — two-column without sidebar, or unknown layout #} +
+ {% for section in homepageConfig.sections %} + {% if section.type != "hero" %} + {% include "components/homepage-section.njk" %} + {% endif %} + {% endfor %} +
+ +{% endif %} diff --git a/_includes/components/homepage-section.njk b/_includes/components/homepage-section.njk new file mode 100644 index 0000000..c87d360 --- /dev/null +++ b/_includes/components/homepage-section.njk @@ -0,0 +1,30 @@ +{# Homepage Section Dispatcher — maps section.type to the right partial #} +{% if section.type == "recent-posts" %} + {% include "components/sections/recent-posts.njk" %} +{% elif section.type == "custom-html" %} + {% include "components/sections/custom-html.njk" %} +{% elif section.type == "cv-experience" %} + {% include "components/sections/cv-experience.njk" ignore missing %} +{% elif section.type == "cv-projects" %} + {% include "components/sections/cv-projects.njk" ignore missing %} +{% elif section.type == "cv-skills" %} + {% include "components/sections/cv-skills.njk" ignore missing %} +{% elif section.type == "cv-education" %} + {% include "components/sections/cv-education.njk" ignore missing %} +{% elif section.type == "cv-interests" %} + {% include "components/sections/cv-interests.njk" ignore missing %} +{% elif section.type == "blogroll" %} + {% include "components/sections/blogroll.njk" ignore missing %} +{% elif section.type == "podroll" %} + {% include "components/sections/podroll.njk" ignore missing %} +{% elif section.type == "github-activity" %} + {% include "components/sections/github-activity.njk" ignore missing %} +{% elif section.type == "youtube" %} + {% include "components/sections/youtube.njk" ignore missing %} +{% elif section.type == "funkwhale" %} + {% include "components/sections/funkwhale.njk" ignore missing %} +{% elif section.type == "lastfm" %} + {% include "components/sections/lastfm.njk" ignore missing %} +{% else %} + +{% endif %} diff --git a/_includes/components/homepage-sidebar.njk b/_includes/components/homepage-sidebar.njk new file mode 100644 index 0000000..4fe6e6c --- /dev/null +++ b/_includes/components/homepage-sidebar.njk @@ -0,0 +1,28 @@ +{# Homepage Builder Sidebar — renders widgets from homepageConfig.sidebar #} +{% if homepageConfig.sidebar and homepageConfig.sidebar.length %} + {% for widget in homepageConfig.sidebar %} + {% if widget.type == "author-card" %} + {% include "components/widgets/author-card.njk" %} + {% elif widget.type == "social-activity" %} + {% include "components/widgets/social-activity.njk" %} + {% elif widget.type == "github-repos" %} + {% include "components/widgets/github-repos.njk" %} + {% elif widget.type == "funkwhale" %} + {% include "components/widgets/funkwhale.njk" %} + {% elif widget.type == "recent-posts" %} + {% include "components/widgets/recent-posts.njk" %} + {% elif widget.type == "blogroll" %} + {% include "components/widgets/blogroll.njk" %} + {% elif widget.type == "categories" %} + {% include "components/widgets/categories.njk" %} + {% elif widget.type == "search" %} + {# Pagefind search widget #} + + {% else %} + + {% endif %} + {% endfor %} +{% endif %} diff --git a/_includes/layouts/base.njk b/_includes/layouts/base.njk index a5f4c73..bbd906e 100644 --- a/_includes/layouts/base.njk +++ b/_includes/layouts/base.njk @@ -270,7 +270,7 @@
- {% if withSidebar %} + {% if withSidebar and not (homepageConfig and homepageConfig.sections) %}
{{ content | safe }} @@ -279,6 +279,9 @@ {% include "components/sidebar.njk" %}
+ {% elif withSidebar and homepageConfig and homepageConfig.sections %} + {# Homepage builder controls its own layout and sidebar #} + {{ content | safe }} {% elif withBlogSidebar %}