This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-website.git


The following commit(s) were added to refs/heads/main by this push:
     new 90e6d936 Blog: ten posts per page, a compact post card, and a "Start 
here" list in the rail (#1756)
90e6d936 is described below

commit 90e6d93631ef5c143eb1f592a373effe13e75bf9
Author: Claus Ibsen <[email protected]>
AuthorDate: Tue Sep 15 15:19:03 2026 +0200

    Blog: ten posts per page, a compact post card, and a "Start here" list in 
the rail (#1756)
    
    The blog list and category pages showed three posts per page, spreading
    the 125 listed posts across 42 pages. Page size is now ten (13 pages) and
    the post card is tightened so ten posts read as a list: smaller date
    block, less padding, a 22px title, previews cut at 180 characters, and the
    redundant "Continue reading" link dropped.
    
    The rail now opens with eight hand-picked evergreen posts from
    data/blog-picks.yaml (each resolved with site.GetPage so a wrong path
    fails the build) above the categories, and scrolls in place when it is
    taller than the viewport. The rail markup, previously duplicated in the
    blog list and taxonomy layouts, is a shared partial.
    
    Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
---
 .../{site-ea6acedfb2.css => site-8b1f35b7a5.css}   |  2 +-
 antora-ui-camel/public/_/data/rev-manifest.json    |  2 +-
 antora-ui-camel/public/_/helpers/asset.js          |  2 +-
 antora-ui-camel/public/_/partials/head-styles.hbs  |  2 +-
 antora-ui-camel/public/_/rev-manifest              |  2 +-
 antora-ui-camel/src/css/blog.css                   | 65 +++++++++++++++-------
 data/blog-picks.yaml                               | 23 ++++++++
 layouts/_default/taxonomy.html                     | 16 +-----
 layouts/blog/list.html                             | 16 +-----
 layouts/blog/summary.html                          |  6 +-
 layouts/partials/blog-rail.html                    | 29 ++++++++++
 11 files changed, 109 insertions(+), 56 deletions(-)

diff --git a/antora-ui-camel/public/_/css/site-ea6acedfb2.css 
b/antora-ui-camel/public/_/css/site-8b1f35b7a5.css
similarity index 66%
rename from antora-ui-camel/public/_/css/site-ea6acedfb2.css
rename to antora-ui-camel/public/_/css/site-8b1f35b7a5.css
index b70b0d82..8ee82ec9 100644
--- a/antora-ui-camel/public/_/css/site-ea6acedfb2.css
+++ b/antora-ui-camel/public/_/css/site-8b1f35b7a5.css
@@ -20,4 +20,4 @@
     .line and .cl (line wrappers), and .err (a lexer hiccup is not worth a
     color). .go, generic command output, is content the reader needs rather
     than chrome, so it stays at the base color too. */}@layer content{@media 
screen and (width >= 1025px){.doc{font-size:.88889rem;margin:0 
2rem;max-width:none;min-width:0}}.doc h1,.doc h2,.doc h3,.doc h4,.doc h5,.doc 
h6{color:#211c17;font-weight:700;-webkit-hyphens:none;-ms-hyphens:none;hyphens:none;line-height:1.3;margin:1rem
 0 
0}.doc>h1.page,.static>h1:first-child{font-size:2.33333rem;font-weight:800;letter-spacing:-.03em;line-height:1.05;margin:.55556rem
 0 0}.doc>h1.page img{width:2r [...]
-/*! Asciidoctor Tabs | Copyright (c) 2018-present Dan Allen | MIT License 
*/.tablist>ul li:focus-visible{outline:none}.tablist.ulist,.tablist.ulist>ul 
li{margin:0}.tablist.ulist>ul li+li{margin-left:.25em}.tabs.is-loading .tablist 
li:not(:first-child),.tabs:not(.is-loading) .tablist 
li:not(.is-selected){background-color:#f5f5f5}.tabs.is-loading .tablist 
li:first-child::after,.tabs:not(.is-loading) .tablist 
li.is-selected::after{background-color:inherit;content:"";display:block;height:3px
 [...]
\ No newline at end of file
+/*! Asciidoctor Tabs | Copyright (c) 2018-present Dan Allen | MIT License 
*/.tablist>ul li:focus-visible{outline:none}.tablist.ulist,.tablist.ulist>ul 
li{margin:0}.tablist.ulist>ul li+li{margin-left:.25em}.tabs.is-loading .tablist 
li:not(:first-child),.tabs:not(.is-loading) .tablist 
li:not(.is-selected){background-color:#f5f5f5}.tabs.is-loading .tablist 
li:first-child::after,.tabs:not(.is-loading) .tablist 
li.is-selected::after{background-color:inherit;content:"";display:block;height:3px
 [...]
\ No newline at end of file
diff --git a/antora-ui-camel/public/_/data/rev-manifest.json 
b/antora-ui-camel/public/_/data/rev-manifest.json
index b0495abe..2098854a 100644
--- a/antora-ui-camel/public/_/data/rev-manifest.json
+++ b/antora-ui-camel/public/_/data/rev-manifest.json
@@ -1,5 +1,5 @@
 {
-  "css/site.css": "css/site-ea6acedfb2.css",
+  "css/site.css": "css/site-8b1f35b7a5.css",
   "css/vendor/docsearch.css": "css/vendor/docsearch-5db8a73adb.css",
   "img/algolia.svg": "img/algolia-f4ab98e0de.svg",
   "img/apache-kafka.svg": "img/apache-kafka-88809b7472.svg",
diff --git a/antora-ui-camel/public/_/helpers/asset.js 
b/antora-ui-camel/public/_/helpers/asset.js
index a044e35d..54c1dfa4 100644
--- a/antora-ui-camel/public/_/helpers/asset.js
+++ b/antora-ui-camel/public/_/helpers/asset.js
@@ -1,7 +1,7 @@
 'use strict'
 
 const manifest = {
-  "css/site.css": "css/site-ea6acedfb2.css",
+  "css/site.css": "css/site-8b1f35b7a5.css",
   "css/vendor/docsearch.css": "css/vendor/docsearch-5db8a73adb.css",
   "img/algolia.svg": "img/algolia-f4ab98e0de.svg",
   "img/apache-kafka.svg": "img/apache-kafka-88809b7472.svg",
diff --git a/antora-ui-camel/public/_/partials/head-styles.hbs 
b/antora-ui-camel/public/_/partials/head-styles.hbs
index 15514ed8..c131f696 100644
--- a/antora-ui-camel/public/_/partials/head-styles.hbs
+++ b/antora-ui-camel/public/_/partials/head-styles.hbs
@@ -1,5 +1,5 @@
     <link rel="stylesheet" 
href="{{uiRootPath}}/css/vendor/docsearch-5db8a73adb.css">
-    <link rel="stylesheet" href="{{uiRootPath}}/css/site-ea6acedfb2.css">
+    <link rel="stylesheet" href="{{uiRootPath}}/css/site-8b1f35b7a5.css">
 {{!-- NOTE the asciinema partials are injected into the UI catalog by
       @springio/antora-extensions at Antora build time, so they only exist 
during a site build.
       Guarding on the page attribute the extension sets keeps the assets off 
pages with no cast,
diff --git a/antora-ui-camel/public/_/rev-manifest 
b/antora-ui-camel/public/_/rev-manifest
index b0495abe..2098854a 100644
--- a/antora-ui-camel/public/_/rev-manifest
+++ b/antora-ui-camel/public/_/rev-manifest
@@ -1,5 +1,5 @@
 {
-  "css/site.css": "css/site-ea6acedfb2.css",
+  "css/site.css": "css/site-8b1f35b7a5.css",
   "css/vendor/docsearch.css": "css/vendor/docsearch-5db8a73adb.css",
   "img/algolia.svg": "img/algolia-f4ab98e0de.svg",
   "img/apache-kafka.svg": "img/apache-kafka-88809b7472.svg",
diff --git a/antora-ui-camel/src/css/blog.css b/antora-ui-camel/src/css/blog.css
index 6cdd24d4..1b91af17 100644
--- a/antora-ui-camel/src/css/blog.css
+++ b/antora-ui-camel/src/css/blog.css
@@ -18,7 +18,38 @@
 }
 
 /* .blog-rail / .blog-rail-eyebrow: shared base (sticky offset; mono
-   eyebrow shape + color) lives in primitives.css - see M5, final-review.md. */
+   eyebrow shape + color) lives in primitives.css - see M5, final-review.md.
+   With the picks above the categories the rail can be taller than a short
+   viewport; let it scroll in place rather than stick with its bottom cut
+   off. Matches the sticky top offset in primitives.css. */
+.blog-rail {
+  max-height: calc(100vh - var(--navbar-height) - calc(48 / var(--rem-base) * 
1rem));
+  overflow-y: auto;
+}
+
+/* "Start here" picks (data/blog-picks.yaml): same list shape as the
+   categories below, without the count, so the rail reads as one column. */
+.blog-picks {
+  display: flex;
+  flex-direction: column;
+  margin-top: calc(8 / var(--rem-base) * 1rem);
+  margin-bottom: calc(32 / var(--rem-base) * 1rem);
+}
+
+.blog-pick {
+  display: block;
+  padding: calc(8 / var(--rem-base) * 1rem) 0;
+  font-size: calc(14 / var(--rem-base) * 1rem);
+  font-weight: 600;
+  line-height: 1.35;
+  color: var(--color-ink-2);
+  border-bottom: 1px solid var(--color-line-soft);
+  text-decoration: none;
+}
+
+.blog-pick:hover {
+  color: var(--link_hover-font-color);
+}
 
 .blog-categories {
   display: flex;
@@ -100,9 +131,9 @@
 
 .blog-post {
   display: grid;
-  grid-template-columns: calc(96 / var(--rem-base) * 1rem) 1fr;
-  gap: calc(28 / var(--rem-base) * 1rem);
-  padding: calc(30 / var(--rem-base) * 1rem) 0;
+  grid-template-columns: calc(72 / var(--rem-base) * 1rem) 1fr;
+  gap: calc(24 / var(--rem-base) * 1rem);
+  padding: calc(20 / var(--rem-base) * 1rem) 0;
   border-top: 1px solid var(--color-line);
 }
 
@@ -114,7 +145,7 @@
   display: block;
   font-family: var(--display-font-family);
   font-weight: 800;
-  font-size: calc(40 / var(--rem-base) * 1rem);
+  font-size: calc(32 / var(--rem-base) * 1rem);
   line-height: 1;
   letter-spacing: -0.03em;
   color: var(--color-orange-deep);
@@ -156,10 +187,10 @@
 .blog-post-title {
   font-family: var(--display-font-family);
   font-weight: 700;
-  font-size: calc(24 / var(--rem-base) * 1rem);
+  font-size: calc(22 / var(--rem-base) * 1rem);
   letter-spacing: -0.02em;
   line-height: 1.2;
-  margin: calc(12 / var(--rem-base) * 1rem) 0 0;
+  margin: calc(8 / var(--rem-base) * 1rem) 0 0;
 }
 
 .blog-post-title a {
@@ -172,10 +203,10 @@
 }
 
 .blog-post-summary {
-  font-size: calc(15.5 / var(--rem-base) * 1rem);
-  line-height: 1.6;
+  font-size: calc(15 / var(--rem-base) * 1rem);
+  line-height: 1.55;
   color: var(--color-ink-soft);
-  margin: calc(10 / var(--rem-base) * 1rem) 0 0;
+  margin: calc(8 / var(--rem-base) * 1rem) 0 0;
   text-wrap: pretty;
 }
 
@@ -183,21 +214,11 @@
   display: flex;
   align-items: center;
   gap: calc(16 / var(--rem-base) * 1rem);
-  margin-top: calc(14 / var(--rem-base) * 1rem);
+  margin-top: calc(10 / var(--rem-base) * 1rem);
   font-size: calc(13.5 / var(--rem-base) * 1rem);
   color: var(--color-ink-muted);
 }
 
-.blog-post-continue {
-  font-weight: 700;
-  color: var(--color-orange-deep);
-  text-decoration: none;
-}
-
-.blog-post-continue:hover {
-  color: var(--link_hover-font-color);
-}
-
 /* Numbered pager: mono, ink active pill (blog.md ยง4). Scoped by the shared
    .blog-list root so it never leaks into an unrelated future ".pagination". */
 .blog-list .pagination {
@@ -260,6 +281,8 @@
 
   .blog-rail {
     position: static;
+    max-height: none;
+    overflow-y: visible;
   }
 }
 
diff --git a/data/blog-picks.yaml b/data/blog-picks.yaml
new file mode 100644
index 00000000..8ca2500c
--- /dev/null
+++ b/data/blog-picks.yaml
@@ -0,0 +1,23 @@
+# Hand-picked evergreen posts shown under "Start here" in the blog rail, so
+# the best reads are one click away instead of buried under pagination.
+# path is the post's content file (index.md, so that a directory name with
+# dots such as ...-4.21.0 resolves too), looked up with site.GetPage at build
+# time so a wrong path fails the build; label is a short title that fits the
+# 240px rail.
+picks:
+  - label: Camel by the numbers
+    path: blog/2026/06/camel-by-the-numbers/index.md
+  - label: The DNA of Camel, 19 years on
+    path: blog/2026/06/camel-dna-19-years/index.md
+  - label: "The bug fix track record: 99.8% fixed, median 1 day"
+    path: blog/2026/06/camel-bug-fix-track-record/index.md
+  - label: AI already knows Camel
+    path: blog/2026/06/camel-ai-trained/index.md
+  - label: "Not afraid of AI: 165 bugs fixed"
+    path: blog/2026/07/camel-not-afraid-of-ai/index.md
+  - label: A local model as usability tester
+    path: blog/2026/09/camel-local-model-benchmark/index.md
+  - label: "Built to patch fast: 32 CVEs in one release"
+    path: blog/2026/07/camel-security-advisories-4.21.0/index.md
+  - label: "Echonect: fifteen years on Camel"
+    path: blog/2026/07/echonect-fifteen-years-apache-camel/index.md
diff --git a/layouts/_default/taxonomy.html b/layouts/_default/taxonomy.html
index e5b1c5d7..50a1e35d 100644
--- a/layouts/_default/taxonomy.html
+++ b/layouts/_default/taxonomy.html
@@ -5,26 +5,14 @@
     <div class="content">
       <article class="blog-list" aria-labelledby="blog-title">
         <div class="blog-layout">
-          <aside class="blog-rail" aria-label="Categories">
-            <div class="blog-rail-eyebrow">Categories</div>
-            <div class="blog-categories">
-              {{ range .Site.Taxonomies.categories.Alphabetical }}
-              <a class="blog-category{{ if eq .Page.RelPermalink 
$.RelPermalink }} is-current{{ end }}" href="{{ "/categories/" | relURL }}{{ 
.Name | urlize }}/">
-                <span>{{ .Name }}</span><span class="blog-category-count">{{ 
.Count }}</span>
-              </a>
-              {{ end }}
-            </div>
-            <a class="blog-rss" href="{{ "blog/index.xml" | relURL }}" 
title="Subscribe to RSS Feed">
-              <svg focusable="false" class="brand-icon"><use href="{{ 
path.Join "_" (index .Site.Data "rev-manifest" "img/brand-logos.svg") | relURL 
}}#rss" /></svg> RSS feed &rarr;
-            </a>
-          </aside>
+          {{ partial "blog-rail.html" . }}
           <div class="blog-main">
             <a class="blog-back-link" href="{{ "/blog/" | relURL }}">&larr; 
All posts</a>
             <h1 id="blog-title" class="page-hero-title">{{ .Title }}</h1>
             <p class="page-hero-lead">{{ printf "Posts in the %s category." 
.Title }}</p>
 
             <div class="blog-posts">
-              {{ $pages := (.Paginate .Pages 3).Pages }}
+              {{ $pages := (.Paginate .Pages 10).Pages }}
               {{ range $pages }}
               {{ .Render "summary" }}
               {{ end }}
diff --git a/layouts/blog/list.html b/layouts/blog/list.html
index 1460599e..0a48bc4a 100644
--- a/layouts/blog/list.html
+++ b/layouts/blog/list.html
@@ -5,19 +5,7 @@
     <div class="content">
       <article class="blog-list" aria-labelledby="blog-title">
         <div class="blog-layout">
-          <aside class="blog-rail" aria-label="Categories">
-            <div class="blog-rail-eyebrow">Categories</div>
-            <div class="blog-categories">
-              {{ range .Site.Taxonomies.categories.Alphabetical }}
-              <a class="blog-category" href="{{ "/categories/" | relURL }}{{ 
.Name | urlize }}/">
-                <span>{{ .Name }}</span><span class="blog-category-count">{{ 
.Count }}</span>
-              </a>
-              {{ end }}
-            </div>
-            <a class="blog-rss" href="{{ "blog/index.xml" | relURL }}" 
title="Subscribe to RSS Feed">
-              <svg focusable="false" class="brand-icon"><use href="{{ 
path.Join "_" (index .Site.Data "rev-manifest" "img/brand-logos.svg") | relURL 
}}#rss" /></svg> RSS feed &rarr;
-            </a>
-          </aside>
+          {{ partial "blog-rail.html" . }}
           <div class="blog-main">
             <h1 id="blog-title" class="page-hero-title">Blog</h1>
             <p class="page-hero-lead">Release notes, roadmap updates, and 
engineering notes from the Camel team and community.</p>
@@ -31,7 +19,7 @@
                   {{ $filtered = $filtered | append . }}
                 {{ end }}
               {{ end }}
-              {{ $pages := (.Paginate $filtered 3).Pages }}
+              {{ $pages := (.Paginate $filtered 10).Pages }}
               {{ range $pages }}
               {{ .Render "summary" }}
               {{ end }}
diff --git a/layouts/blog/summary.html b/layouts/blog/summary.html
index d097ad33..f432517f 100644
--- a/layouts/blog/summary.html
+++ b/layouts/blog/summary.html
@@ -10,7 +10,10 @@
         </div>
         {{ end }}
         <h2 class="blog-post-title"><a href="{{ .RelPermalink }}">{{ .Title 
}}</a></h2>
-        <p class="blog-post-summary">{{ with .Params.preview }}{{ . }}{{ else 
}}{{ $.Summary | plainify }}{{ end }}</p>
+        {{/* Previews are written as one or two sentences (median ~70 chars); 
the
+             few long ones are cut so every card stays about the same height 
and
+             ten fit on a page. */}}
+        <p class="blog-post-summary">{{ with .Params.preview }}{{ . | truncate 
180 }}{{ else }}{{ $.Summary | plainify | truncate 180 }}{{ end }}</p>
         <div class="blog-post-meta">
             <span>by
                 {{ $headers := dict }}
@@ -20,7 +23,6 @@
                   {{ $headers = dict "Authorization" (printf "Basic %s" 
(printf "%s:%s" $.Site.Params.GitHubUsername $.Site.Params.GitHubToken | 
base64Encode)) }}
                 {{ end }}
                 {{ range $idx, $author := .Params.authors }}{{ if gt $idx 0 
}}, {{ end }}<span rel="author">{{ (getJSON "https://api.github.com/users/"; 
$author $headers).name }}</span>{{ end }}</span>
-            <a class="blog-post-continue" href="{{ .RelPermalink }}" 
aria-label="Continue reading {{ .Title }}">Continue reading &rarr;</a>
         </div>
     </div>
 </article>
diff --git a/layouts/partials/blog-rail.html b/layouts/partials/blog-rail.html
new file mode 100644
index 00000000..ee04721c
--- /dev/null
+++ b/layouts/partials/blog-rail.html
@@ -0,0 +1,29 @@
+{{- /* Shared rail for the blog list and the category pages: curated picks
+     from data/blog-picks.yaml, categories (marking the current one on a
+     category page) and the RSS link. Called with the page as context. */ -}}
+<aside class="blog-rail" aria-label="Blog navigation">
+  {{ with (index .Site.Data "blog-picks").picks }}
+  <div class="blog-rail-eyebrow">Start here</div>
+  <div class="blog-picks">
+    {{ range . }}
+    {{ $pick := . }}
+    {{ with site.GetPage .path }}
+    <a class="blog-pick" href="{{ .RelPermalink }}" title="{{ .Title }}">{{ 
$pick.label }}</a>
+    {{ else }}
+    {{ errorf "blog-picks: no page at %q" $pick.path }}
+    {{ end }}
+    {{ end }}
+  </div>
+  {{ end }}
+  <div class="blog-rail-eyebrow">Categories</div>
+  <div class="blog-categories">
+    {{ range .Site.Taxonomies.categories.Alphabetical }}
+    <a class="blog-category{{ if eq .Page.RelPermalink $.RelPermalink }} 
is-current{{ end }}" href="{{ "/categories/" | relURL }}{{ .Name | urlize }}/">
+      <span>{{ .Name }}</span><span class="blog-category-count">{{ .Count 
}}</span>
+    </a>
+    {{ end }}
+  </div>
+  <a class="blog-rss" href="{{ "blog/index.xml" | relURL }}" title="Subscribe 
to RSS Feed">
+    <svg focusable="false" class="brand-icon"><use href="{{ path.Join "_" 
(index .Site.Data "rev-manifest" "img/brand-logos.svg") | relURL }}#rss" 
/></svg> RSS feed &rarr;
+  </a>
+</aside>

Reply via email to