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

wu-sheng pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/skywalking-website.git


The following commit(s) were added to refs/heads/master by this push:
     new 0d047d8994d feat(docs/downloads): card permalink hooks, date-sorted 
latest releases, content cleanup (#847)
0d047d8994d is described below

commit 0d047d8994d8288c6f551e905004c986ecf37002
Author: 吴晟 Wu Sheng <[email protected]>
AuthorDate: Fri May 22 09:15:41 2026 +0800

    feat(docs/downloads): card permalink hooks, date-sorted latest releases, 
content cleanup (#847)
    
    - Add clickable permalink hook + selectable :target highlight to docs and
      download project cards; clicking copies the deep link, clicking the box
      selects it and updates the URL hash.
    - Downloads 'Latest releases' now sorts projects by actual release date
      (parsing both 'Mon. DDth, YYYY' and ISO dates) and shows the 5 newest with
      dates; dropped the GPG/SHA-512/mirrors tag row.
    - Horizon UI: drop the inaccurate 'Included in the main repo release' note
      (still on voting, not released).
    - docs.yml: remove the SkyWalking Servers and Database descriptionItem 
notes;
      move SourceMarker to Ecosystem Retired Projects.
---
 assets/scss/_custom_docs.scss           |  6 ++++
 assets/scss/_custom_home.scss           | 34 ++++++++++++++++++----
 data/docs.yml                           | 12 +++-----
 data/releases.yml                       |  1 -
 layouts/docs/baseof.html                |  4 +++
 layouts/downloads/baseof.html           |  1 +
 layouts/downloads/list.html             | 50 +++++++++++++++++++++++++--------
 layouts/partials/card-permalink.html    | 37 ++++++++++++++++++++++++
 layouts/shortcodes/downloads-block.html |  3 ++
 9 files changed, 122 insertions(+), 26 deletions(-)

diff --git a/assets/scss/_custom_docs.scss b/assets/scss/_custom_docs.scss
index 1ee4d81c184..e8419534453 100644
--- a/assets/scss/_custom_docs.scss
+++ b/assets/scss/_custom_docs.scss
@@ -473,9 +473,15 @@
   .docs-card {
     display: flex; flex-direction: column;
     background: #fff; border: 1px solid $line; border-radius: 14px; padding: 
16px 18px;
+    scroll-margin-top: 84px;   // clear the sticky navbar when jumped to via 
#anchor
     transition: box-shadow .18s ease, border-color .18s ease, transform .18s 
ease;
     &:hover { box-shadow: 0 16px 40px -22px rgba(17,24,39,.24); border-color: 
#d6e4f5; transform: translateY(-2px); }
   }
+  // selected state when navigated to via a #project anchor
+  .docs-card:target {
+    border-color: $brand;
+    box-shadow: 0 0 0 3px rgba(55, 136, 208, .25), 0 16px 40px -22px rgba(17, 
24, 39, .3);
+  }
   .docs-card-head { display: flex; align-items: center; gap: 9px; 
margin-bottom: 8px; min-height: 30px; }
   .docs-icon { flex: 0 0 30px; width: 30px; height: 30px; object-fit: contain; 
}
   .docs-card-title { margin: 0; font-size: 14.5px; font-weight: 700; color: 
$ink; line-height: 1.25; flex: 1; }
diff --git a/assets/scss/_custom_home.scss b/assets/scss/_custom_home.scss
index 6e084da6566..02e8184d0b2 100644
--- a/assets/scss/_custom_home.scss
+++ b/assets/scss/_custom_home.scss
@@ -948,17 +948,14 @@ $brand-grad: linear-gradient(180deg, #479EEB 0%, #3788D0 
100%);
   .dl-latest-head { font-size: 11px; font-weight: 700; letter-spacing: .1em; 
text-transform: uppercase; color: $muted; margin-bottom: 10px; }
   .dl-latest-item {
     display: flex; align-items: baseline; justify-content: space-between; gap: 
10px;
-    padding: 7px 0; border-bottom: 1px solid $line; text-decoration: none;
+    padding: 8px 0; border-bottom: 1px solid $line; text-decoration: none;
     &:last-of-type { border-bottom: 0; }
     .dl-latest-name { font-size: 13.5px; color: $ink; font-weight: 600; }
+    .dl-latest-meta { display: flex; flex-direction: column; align-items: 
flex-end; gap: 1px; flex: 0 0 auto; text-align: right; }
     .dl-latest-ver { font-family: ui-monospace, "SF Mono", Menlo, monospace; 
font-size: 13px; color: $brand; font-weight: 700; }
+    .dl-latest-date { font-size: 11px; color: $muted; }
     &:hover .dl-latest-name { color: $brand; }
   }
-  .dl-latest-tags { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 
12px; }
-  .dl-tag {
-    font-size: 10.5px; font-weight: 600; padding: 2px 8px; border-radius: 
999px;
-    background: #eef1f5; color: #5b6573; border: 1px solid #e1e6ee;
-  }
 
   .dl-wrap { padding-top: 28px; padding-bottom: 64px; }
 
@@ -972,9 +969,15 @@ $brand-grad: linear-gradient(180deg, #479EEB 0%, #3788D0 
100%);
   .dl-card {
     display: flex; flex-direction: column;
     background: #fff; border: 1px solid $line; border-radius: 12px; padding: 
14px;
+    scroll-margin-top: 84px;   // clear the sticky navbar when jumped to via 
#anchor
     transition: box-shadow .18s ease, border-color .18s ease;
     &:hover { box-shadow: 0 14px 34px -22px rgba(17,24,39,.22); border-color: 
#d6e4f5; }
   }
+  // selected state when navigated to via a #project anchor (e.g. the "Latest 
releases" panel)
+  .dl-card:target {
+    border-color: $brand;
+    box-shadow: 0 0 0 3px rgba(55, 136, 208, .25), 0 14px 34px -22px rgba(17, 
24, 39, .3);
+  }
   .dl-card-head {
     display: flex; gap: 9px; align-items: center; margin-bottom: 8px;
     min-height: 44px;   // fits icon + up to a 2-line title, so SOURCE aligns 
across cards
@@ -1171,3 +1174,22 @@ $brand-grad: linear-gradient(180deg, #479EEB 0%, #3788D0 
100%);
   // hide the little caret arrows; the groups read fine as labels
   .dropdown-wrapper .dropdown-title .arrow { display: none; }
 }
+
+// ── Permalink "hook" on project cards (docs landing + downloads) 
──────────────
+// Global (cards live under different page scopes); copies the deep link on 
click.
+.card-anchor {
+  flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: 
center;
+  width: 24px; height: 24px; border-radius: 7px; position: relative;
+  color: $muted; background: transparent; text-decoration: none;
+  opacity: 0; transition: opacity .15s ease, color .15s ease, background .15s 
ease;
+  svg { width: 13px; height: 13px; }
+  &:hover { color: $brand; background: #eef4fb; }
+  &:focus-visible { opacity: 1; outline: 2px solid rgba(55, 136, 208, .5); 
outline-offset: 1px; }
+  &.copied::after {
+    content: "Link copied"; position: absolute; bottom: calc(100% + 6px); 
right: 0;
+    background: $ink; color: #fff; font-size: 10.5px; font-weight: 600;
+    padding: 3px 7px; border-radius: 6px; white-space: nowrap; pointer-events: 
none; z-index: 5;
+  }
+}
+.docs-card:hover .card-anchor,
+.dl-card:hover .card-anchor { opacity: 1; }
diff --git a/data/docs.yml b/data/docs.yml
index a5f39d3682b..5e39079fc88 100644
--- a/data/docs.yml
+++ b/data/docs.yml
@@ -19,8 +19,6 @@
 - type: SkyWalking Servers
   description:
   list:
-    - name:
-      descriptionItem: SkyWalking servers include the Observability Analysis 
Platform (OAP) server and the native UI server. SkyWalking primary docs 
introduce the concepts, designs, setup, and corresponding APIs referred to 
telemetry data reports and queries.
     - name: SkyWalking
       icon: skywalking
       description: SkyWalking primary repository and docs.
@@ -350,8 +348,6 @@
       repo: skywalking-goapi
 - type: Database
   list:
-    - name:
-      descriptionItem: BanyanDB server and clients are incubated under 
SkyWalking umbrella, which aims to provide better native supports to the 
SkyWalking APM use cases, including better performance and lower resource costs.
     - name: BanyanDB
       icon: banyan-db
       description: An observability database aims to ingest, analyze and store 
Metrics, Tracing and Logging data.
@@ -464,10 +460,6 @@
       description: Distributed tracing and monitor SDK in CPP for Apache 
SkyWalking APM.
       user: SkyAPM
       repo: cpp2sky
-    - name: SourceMarker
-      description: JetBrains-powered plugin. Continuous Feedback for 
Developers / Feedback-Driven Development Tool.
-      user: sourceplusplus
-      repo: SourceMarker
     - name: Java Plugin Extensions
       description: Java agent plugin extensions for Apache SkyWalking.
       user: SkyAPM
@@ -484,6 +476,10 @@
   list:
     - name:
       descriptionItem: All following repositories are a part of SkyWalking 
ecosystem, but now are retired and archived as read-only.
+    - name: (Retired) SourceMarker
+      description: JetBrains-powered plugin. Continuous Feedback for 
Developers / Feedback-Driven Development Tool.
+      user: sourceplusplus
+      repo: SourceMarker
     - name: (Retired) Transporter Plugins
       description: 3rd-party transporter implementation of Apache SkyWalking. 
No one is maintaining this.
       user: SkyAPM
diff --git a/data/releases.yml b/data/releases.yml
index 3931a886154..d74cae57e6b 100644
--- a/data/releases.yml
+++ b/data/releases.yml
@@ -258,7 +258,6 @@
     - name: Horizon UI
       icon: skywalking
       description: Apache SkyWalking next-generation UI (Horizon), natively 
supporting SkyWalking since v11, and partially for v10.
-      sourceText: Included in the main repo release
     - name: Grafana Plugins
       icon: skywalking
       description: SkyWalking Grafana Plugins provide extensions to visualize 
topology on Grafana.
diff --git a/layouts/docs/baseof.html b/layouts/docs/baseof.html
index 2c8b1476169..ba03d37593f 100644
--- a/layouts/docs/baseof.html
+++ b/layouts/docs/baseof.html
@@ -90,6 +90,9 @@
                 <span>{{ .stars }}</span>
               </a>
               {{ end }}
+              <a class="card-anchor" href="#{{ $id }}" data-anchor="{{ $id }}" 
title="Copy link to {{ .name }}" aria-label="Copy link to {{ .name }}">
+                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" 
stroke-width="2" stroke-linecap="round" stroke-linejoin="round" 
aria-hidden="true"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 
0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 
7.07l1.71-1.71"/></svg>
+              </a>
             </header>
             <p class="docs-card-desc">{{ .description | markdownify }}</p>
             <footer class="docs-card-foot">
@@ -147,5 +150,6 @@
         });
       });
     </script>
+    {{ partial "card-permalink.html" . }}
   </body>
 </html>
diff --git a/layouts/downloads/baseof.html b/layouts/downloads/baseof.html
index 55e99f57c41..2e3d130e8fe 100644
--- a/layouts/downloads/baseof.html
+++ b/layouts/downloads/baseof.html
@@ -27,5 +27,6 @@
     }
   })
 </script>
+{{ partial "card-permalink.html" . }}
 </body>
 </html>
diff --git a/layouts/downloads/list.html b/layouts/downloads/list.html
index 4cd8933984f..b7dde41285b 100644
--- a/layouts/downloads/list.html
+++ b/layouts/downloads/list.html
@@ -18,20 +18,48 @@
       </div>
       <aside class="dl-latest">
         <div class="dl-latest-head">Latest releases</div>
-        {{ range first 4 (index .Site.Data.releases 0).list }}
-        {{ if and .source .name }}
-        {{ $id := replace .name " " "" }}
-        <a class="dl-latest-item" href="#{{ $id }}">
+        {{- /* Genuinely "latest": collect each project's newest release 
across all
+               categories, turn its "Mon. DDth, YYYY" date into a sortable 
YYYYMMDD
+               key, then sort descending and take the 4 most recent. */ -}}
+        {{ $mon := dict "Jan" 1 "Feb" 2 "Mar" 3 "Apr" 4 "May" 5 "Jun" 6 "Jul" 
7 "Aug" 8 "Sep" 9 "Oct" 10 "Nov" 11 "Dec" 12 }}
+        {{ $items := slice }}
+        {{ range .Site.Data.releases }}
+          {{ range .list }}
+          {{ $rels := or .source .distribution }}
+          {{ if and .name $rels }}
+            {{ $rel := index $rels 0 }}
+            {{ $key := 0 }}
+            {{ with $rel.date }}
+              {{ if findRE `^\d{4}-\d{2}-\d{2}` . }}
+                {{- /* ISO date: YYYY-MM-DD -> YYYYMMDD */ -}}
+                {{ $key = int (replace (substr . 0 10) "-" "") }}
+              {{ else }}
+                {{- /* "Mon. DDth, YYYY" -> YYYYMMDD */ -}}
+                {{ $c := replaceRE `(\d+)(st|nd|rd|th)` `$1` . }}
+                {{ $c = replace $c "." "" }}
+                {{ $c = replace $c "," "" }}
+                {{ $p := split (trim (replaceRE `\s+` " " $c) " ") " " }}
+                {{ if eq (len $p) 3 }}
+                  {{ $mn := index $mon (index $p 0) }}
+                  {{ if $mn }}
+                    {{ $key = add (add (mul (int (index $p 2)) 10000) (mul $mn 
100)) (int (index $p 1)) }}
+                  {{ end }}
+                {{ end }}
+              {{ end }}
+            {{ end }}
+            {{ $items = $items | append (dict "name" .name "ver" $rel.version 
"date" $rel.date "id" (replace .name " " "") "key" $key) }}
+          {{ end }}
+          {{ end }}
+        {{ end }}
+        {{ range first 5 (sort $items "key" "desc") }}
+        <a class="dl-latest-item" href="#{{ .id }}">
           <span class="dl-latest-name">{{ .name }}</span>
-          <span class="dl-latest-ver">{{ (index .source 0).version }}</span>
+          <span class="dl-latest-meta">
+            <span class="dl-latest-ver">{{ .ver }}</span>
+            {{ with .date }}<span class="dl-latest-date">{{ . }}</span>{{ end 
}}
+          </span>
         </a>
         {{ end }}
-        {{ end }}
-        <div class="dl-latest-tags">
-          <span class="dl-tag">GPG keys</span>
-          <span class="dl-tag">SHA-512</span>
-          <span class="dl-tag">Apache mirrors</span>
-        </div>
       </aside>
     </div>
   </div>
diff --git a/layouts/partials/card-permalink.html 
b/layouts/partials/card-permalink.html
new file mode 100644
index 00000000000..2c7930b2f90
--- /dev/null
+++ b/layouts/partials/card-permalink.html
@@ -0,0 +1,37 @@
+{{- /* Deep-link "hook" for project cards (docs landing + downloads).
+       - clicking the # hook copies the full anchored URL and selects the card
+       - clicking anywhere on the card (off real links) selects it + updates 
the URL hash */ -}}
+<script>
+  (function () {
+    function selectAndCopy(id, withCopy, badge) {
+      if (!id) return;
+      // history.replaceState keeps the back button clean; setting hash drives 
:target
+      if (location.hash !== '#' + id) { history.replaceState(null, '', '#' + 
id); }
+      // re-assert :target even if the hash was already set
+      location.hash = id;
+      if (withCopy && navigator.clipboard) {
+        navigator.clipboard.writeText(location.href).then(function () {
+          if (!badge) return;
+          badge.classList.add('copied');
+          setTimeout(function () { badge.classList.remove('copied'); }, 1400);
+        });
+      }
+    }
+
+    document.querySelectorAll('.card-anchor').forEach(function (a) {
+      a.addEventListener('click', function (e) {
+        e.preventDefault();
+        e.stopPropagation();
+        selectAndCopy(a.getAttribute('data-anchor'), true, a);
+      });
+    });
+
+    document.querySelectorAll('.docs-card[id], .dl-card[id]').forEach(function 
(card) {
+      card.addEventListener('click', function (e) {
+        // don't hijack clicks on real interactive elements inside the card
+        if (e.target.closest('a, button, summary, details, input')) return;
+        selectAndCopy(card.id, false, null);
+      });
+    });
+  })();
+</script>
diff --git a/layouts/shortcodes/downloads-block.html 
b/layouts/shortcodes/downloads-block.html
index 505669b7600..12f4aee8d86 100755
--- a/layouts/shortcodes/downloads-block.html
+++ b/layouts/shortcodes/downloads-block.html
@@ -11,6 +11,9 @@
     <header class="dl-card-head">
       {{ if .icon }}<img class="dl-icon" width="34" height="34" 
src="/images/project/{{ .icon }}.svg" alt="">{{ end }}
       <h5 class="dl-card-title">{{ .name }}</h5>
+      <a class="card-anchor" href="#{{ $id }}" data-anchor="{{ $id }}" 
title="Copy link to {{ $name }}" aria-label="Copy link to {{ $name }}">
+        <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" 
stroke-width="2" stroke-linecap="round" stroke-linejoin="round" 
aria-hidden="true"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 
0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 
7.07l1.71-1.71"/></svg>
+      </a>
     </header>
     {{ with .description }}<p class="dl-card-desc">{{ . }}</p>{{ end }}
 

Reply via email to