@windcoder/astro-theme-orchid 0.3.0 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,7 @@
1
1
  ---
2
2
  import { getCollection } from "astro:content";
3
3
  import BaseLayout from "virtual:theme/components/BaseLayout.astro";
4
+ import CategoryBar from "virtual:theme/components/CategoryBar.astro";
4
5
  import Pagination from "virtual:theme/components/Pagination.astro";
5
6
  import PostCard from "virtual:theme/components/PostCard.astro";
6
7
  import Sidebar from "virtual:theme/components/Sidebar.astro";
@@ -45,6 +46,8 @@ const pagePosts = await hydratePosts(
45
46
  data-default-layout={config.postList.defaultLayout}
46
47
  data-grid-col={config.postList.gridColumnWidth}
47
48
  >
49
+ {/* 分类导航栏:与首页一致,分页页保留入口 */}
50
+ <CategoryBar />
48
51
  {pagePosts.map((post) => <PostCard post={post} featured={post.data.pinned} />)}
49
52
  <Pagination page={page} total={total} basePath="/" />
50
53
  </div>
@@ -15,6 +15,7 @@ import Sidebar from "virtual:theme/components/Sidebar.astro";
15
15
  import Toc from "virtual:theme/components/Toc.astro";
16
16
  import config from "virtual:theme/config";
17
17
  import { t } from "../../i18n/index.js";
18
+ import { resolveSiteImage } from "../../utils/image.js";
18
19
  import { getLqipStyle } from "../../utils/lqip.js";
19
20
  import { getRelatedPosts } from "../../utils/related.js";
20
21
  import {
@@ -98,14 +99,18 @@ export async function getStaticPaths() {
98
99
 
99
100
  const { post, prev, next, related, posts, seriesInfo } = Astro.props;
100
101
  const d = post.data;
101
- /* 封面解析(§4.33):image:"api" 时取确定性随机图;figure 与分享海报共用同一 URL */
102
- const { cover: articleCover, retries: coverRetries } = resolveCover(
102
+ /* 封面解析(§4.33):image:"api" 时取确定性随机图;figure 与分享海报共用同一 URL。
103
+ §4.110:三格式统一语义(同 PostCard)——相对路径构建期解析为产物 URL */
104
+ const { cover: rawArticleCover, retries: coverRetries } = resolveCover(
103
105
  d.image,
104
106
  d.firstImage,
105
107
  config.postList.fallbackCover,
106
108
  config.postList.randomCover.apis,
107
109
  post.id,
108
110
  );
111
+ const articleCover = rawArticleCover
112
+ ? await resolveSiteImage(rawArticleCover)
113
+ : rawArticleCover;
109
114
  const { Content, headings, remarkPluginFrontmatter } = await render(post);
110
115
  const { words, minutes } = remarkPluginFrontmatter as {
111
116
  words?: number;
@@ -0,0 +1,24 @@
1
+ ---
2
+ // 独立搜索页(§4.104):静态外壳,查询与分页全部在客户端完成(app.ts「独立搜索页」段)。
3
+ // 结果来自 Pagefind 构建期索引;URL 携带 ?q= 关键词与 ?page= 页码,可直接到达与分享。
4
+ // 整页 pagefindIgnore:搜索页自身不进索引,避免搜出无内容空壳页。
5
+ import BaseLayout from "virtual:theme/components/BaseLayout.astro";
6
+ import { t } from "../i18n/index.js";
7
+ ---
8
+
9
+ <BaseLayout title={t('search')} page="search" pagefindIgnore>
10
+ <header class="archive-head reveal">
11
+ <h1 class="page-title">{t('search')}</h1>
12
+ </header>
13
+ <div class="search-page reveal">
14
+ <div class="search-page-bar">
15
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.3-4.3"/></svg>
16
+ <input id="searchPageInput" type="search" placeholder={t('search')} autocomplete="off" enterkeyhint="search" aria-label={t('search')} />
17
+ </div>
18
+ {/* 初始文案由 SSR 输出,客户端按查询状态改写(加载中/结果数/无结果/索引不可用) */}
19
+ <p class="search-page-meta" id="searchPageMeta">{t('searchTypeSomething')}</p>
20
+ <div class="search-page-results" id="searchPageResults"></div>
21
+ {/* 分页条复用列表页 .pagination 样式,内容由客户端按结果总数渲染 */}
22
+ <nav class="pagination" id="searchPagePager" aria-label={t('pagination')} hidden></nav>
23
+ </div>
24
+ </BaseLayout>
@@ -2,10 +2,23 @@
2
2
  import BaseLayout from "virtual:theme/components/BaseLayout.astro";
3
3
  import config from "virtual:theme/config";
4
4
  import { t } from "../i18n/index.js";
5
+ import { resolveSiteImage } from "../utils/image.js";
5
6
 
6
7
  const cfg = config.sponsor;
7
8
  const methods = cfg.methods.filter((m) => m.enabled);
8
9
  const sponsors = cfg.sponsors;
10
+
11
+ // 收款码/打赏者头像三格式解析(§4.97):空串跳过
12
+ const methodImgs = await Promise.all(
13
+ methods.map((m) =>
14
+ m.image ? resolveSiteImage(m.image) : Promise.resolve(""),
15
+ ),
16
+ );
17
+ const sponsorAvatars = await Promise.all(
18
+ sponsors.map((s) =>
19
+ s.avatar ? resolveSiteImage(s.avatar) : Promise.resolve(""),
20
+ ),
21
+ );
9
22
  ---
10
23
 
11
24
  <BaseLayout title={cfg.title} page="sponsor">
@@ -25,7 +38,7 @@ const sponsors = cfg.sponsors;
25
38
  {
26
39
  methods.length > 0 && (
27
40
  <div class="sponsor-grid reveal">
28
- {methods.map((m) => (
41
+ {methods.map((m, i) => (
29
42
  <div class="sponsor-method card">
30
43
  <div class="sm-name">
31
44
  {m.icon && <span class="sm-icon">{m.icon}</span>}
@@ -33,7 +46,7 @@ const sponsors = cfg.sponsors;
33
46
  </div>
34
47
  {m.description && <p class="sm-desc">{m.description}</p>}
35
48
  {m.image ? (
36
- <img class="sponsor-qr" src={m.image} alt={t('qrAlt', { name: m.name })} loading="lazy" />
49
+ <img class="sponsor-qr" src={methodImgs[i]} alt={t('qrAlt', { name: m.name })} loading="lazy" />
37
50
  ) : m.link ? (
38
51
  <a class="btn sm-link" href={m.link} target="_blank" rel="noopener">
39
52
  {t('goSponsor')}
@@ -58,10 +71,10 @@ const sponsors = cfg.sponsors;
58
71
  </h3>
59
72
  {sponsors.length > 0 ? (
60
73
  <div class="sponsor-list">
61
- {sponsors.map((s) => (
74
+ {sponsors.map((s, i) => (
62
75
  <div class="sponsor-item">
63
76
  {s.avatar ? (
64
- <img class="sponsor-item-avatar" src={s.avatar} alt={s.name} loading="lazy" />
77
+ <img class="sponsor-item-avatar" src={sponsorAvatars[i]} alt={s.name} loading="lazy" />
65
78
  ) : (
66
79
  <span class="sponsor-item-avatar avatar-fallback">{s.name.slice(0, 1)}</span>
67
80
  )}