@xingwangzhe/stalux 1.24.3 → 1.24.5
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.
- package/package.json +1 -1
- package/src/components/stalux/footer/FooterBadges.astro +1 -1
- package/src/components/stalux/layout/head.astro +105 -36
- package/src/components/stalux/links/linkCard.astro +1 -1
- package/src/pages/links.astro +6 -7
- package/src/schemas/config.ts +1 -0
- package/src/utils/badge-generator.ts +1 -0
package/package.json
CHANGED
|
@@ -18,7 +18,7 @@ function badgeImg(opts: Record<string, any>) {
|
|
|
18
18
|
const src = svgToDataUrl(generateBadge(opts));
|
|
19
19
|
const alt = opts.alt || `${opts.label}: ${opts.message}`;
|
|
20
20
|
if (opts.href) {
|
|
21
|
-
return `<a href="${opts.href}" target="_blank" rel="
|
|
21
|
+
return `<a href="${opts.href}" target="_blank" rel="${opts.rel ?? "noopener"}"><img src="${src}" alt="${alt}" class="badge" /></a>`;
|
|
22
22
|
}
|
|
23
23
|
return `<img src="${src}" alt="${alt}" class="badge" />`;
|
|
24
24
|
}
|
|
@@ -43,8 +43,6 @@ interface Props {
|
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
const props = Astro.props as Props;
|
|
46
|
-
const effectiveTitle = siteConfig.seoTitle || props.title;
|
|
47
|
-
const effectiveDescription = props.description;
|
|
48
46
|
const isArticle = props.isArticle ?? false;
|
|
49
47
|
|
|
50
48
|
const canonicalBase = siteConfig.canonical || siteConfig.url;
|
|
@@ -68,12 +66,20 @@ const isNotFoundPage =
|
|
|
68
66
|
Astro.url.pathname === "/404" || Astro.url.pathname === "/404/";
|
|
69
67
|
const routeKind = getRouteKind(Astro.url.pathname);
|
|
70
68
|
const isCollectionPage = routeKind.endsWith("-index") || routeKind.endsWith("-detail");
|
|
69
|
+
// seoTitle 是首页的搜索标题,不应覆盖文章/分类等内页标题。
|
|
70
|
+
const effectiveTitle = routeKind === "home" && siteConfig.seoTitle ? siteConfig.seoTitle : props.title;
|
|
71
|
+
const effectiveDescription = props.description;
|
|
72
|
+
const siteTitleSuffix = siteConfig.title ? ` | ${siteConfig.title}` : "";
|
|
73
|
+
const contentTitle =
|
|
74
|
+
siteTitleSuffix && effectiveTitle.endsWith(siteTitleSuffix)
|
|
75
|
+
? effectiveTitle.slice(0, -siteTitleSuffix.length)
|
|
76
|
+
: effectiveTitle;
|
|
71
77
|
const resolvedNoindex = Boolean(siteConfig.noindex) || isNotFoundPage || Boolean(props.noindex);
|
|
72
78
|
const resolvedNofollow = Boolean(siteConfig.nofollow) || isNotFoundPage;
|
|
73
79
|
|
|
74
80
|
const openGraphConfig: Record<string, unknown> = {
|
|
75
81
|
basic: {
|
|
76
|
-
title:
|
|
82
|
+
title: contentTitle,
|
|
77
83
|
type: isArticle ? "article" : "website",
|
|
78
84
|
image: ogImagePath,
|
|
79
85
|
url: canonicalUrl,
|
|
@@ -85,7 +91,7 @@ const openGraphConfig: Record<string, unknown> = {
|
|
|
85
91
|
},
|
|
86
92
|
image: {
|
|
87
93
|
url: ogImagePath,
|
|
88
|
-
alt:
|
|
94
|
+
alt: contentTitle,
|
|
89
95
|
},
|
|
90
96
|
};
|
|
91
97
|
|
|
@@ -101,11 +107,11 @@ if (isArticle) {
|
|
|
101
107
|
}
|
|
102
108
|
|
|
103
109
|
const twitterConfig = {
|
|
104
|
-
card: "summary_large_image" as TwitterCardType,
|
|
105
|
-
title:
|
|
110
|
+
card: (props.cover ? "summary_large_image" : "summary") as TwitterCardType,
|
|
111
|
+
title: contentTitle,
|
|
106
112
|
description: effectiveDescription,
|
|
107
113
|
image: ogImagePath,
|
|
108
|
-
imageAlt:
|
|
114
|
+
imageAlt: contentTitle,
|
|
109
115
|
...(siteConfig.twitterSite ? { site: siteConfig.twitterSite } : {}),
|
|
110
116
|
};
|
|
111
117
|
|
|
@@ -140,6 +146,14 @@ const extendedLink = [
|
|
|
140
146
|
const extendedMeta = [
|
|
141
147
|
{ name: "viewport", content: "width=device-width, initial-scale=1" },
|
|
142
148
|
{ name: "color-scheme", content: "dark" },
|
|
149
|
+
...(!resolvedNoindex
|
|
150
|
+
? [
|
|
151
|
+
{
|
|
152
|
+
name: "googlebot",
|
|
153
|
+
content: "max-image-preview:large, max-snippet:-1, max-video-preview:-1",
|
|
154
|
+
},
|
|
155
|
+
]
|
|
156
|
+
: []),
|
|
143
157
|
];
|
|
144
158
|
|
|
145
159
|
let schema: Record<string, unknown>;
|
|
@@ -148,55 +162,111 @@ const sameAs = mediaLinksConfig?.items
|
|
|
148
162
|
.filter((link) => /^https?:\/\//i.test(link));
|
|
149
163
|
const authorEntity = {
|
|
150
164
|
"@type": "Person",
|
|
165
|
+
"@id": `${siteUrl}/#author`,
|
|
151
166
|
name: authorConfig.name,
|
|
167
|
+
url: `${siteUrl}/about/`,
|
|
152
168
|
...(toAbsolute(authorConfig.avatar) ? { image: toAbsolute(authorConfig.avatar) } : {}),
|
|
153
169
|
...(sameAs.length ? { sameAs } : {}),
|
|
154
170
|
};
|
|
155
171
|
const publisher = {
|
|
156
172
|
"@type": "Organization",
|
|
173
|
+
"@id": `${siteUrl}/#publisher`,
|
|
157
174
|
name: siteName,
|
|
158
175
|
url: siteUrl,
|
|
159
176
|
...(authorConfig.avatar ? { logo: toAbsolute(authorConfig.avatar) } : {}),
|
|
160
177
|
};
|
|
178
|
+
const websiteEntity = {
|
|
179
|
+
"@type": "WebSite",
|
|
180
|
+
"@id": `${siteUrl}/#website`,
|
|
181
|
+
url: `${siteUrl}/`,
|
|
182
|
+
name: siteName,
|
|
183
|
+
description: siteConfig.description,
|
|
184
|
+
inLanguage: siteConfig.lang || "zh-CN",
|
|
185
|
+
publisher: { "@id": `${siteUrl}/#publisher` },
|
|
186
|
+
};
|
|
187
|
+
const breadcrumbItems: Record<string, unknown>[] = [
|
|
188
|
+
{
|
|
189
|
+
"@type": "ListItem",
|
|
190
|
+
position: 1,
|
|
191
|
+
name: siteName,
|
|
192
|
+
item: `${siteUrl}/`,
|
|
193
|
+
},
|
|
194
|
+
];
|
|
195
|
+
if (isArticle && props.categories?.[0]) {
|
|
196
|
+
breadcrumbItems.push({
|
|
197
|
+
"@type": "ListItem",
|
|
198
|
+
position: breadcrumbItems.length + 1,
|
|
199
|
+
name: props.categories[0],
|
|
200
|
+
item: `${siteUrl}/categories/${encodeURIComponent(props.categories[0])}/`,
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
if (routeKind !== "home") {
|
|
204
|
+
breadcrumbItems.push({
|
|
205
|
+
"@type": "ListItem",
|
|
206
|
+
position: breadcrumbItems.length + 1,
|
|
207
|
+
name: contentTitle,
|
|
208
|
+
item: canonicalUrl,
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
const breadcrumbEntity = {
|
|
212
|
+
"@type": "BreadcrumbList",
|
|
213
|
+
"@id": `${canonicalUrl}#breadcrumb`,
|
|
214
|
+
itemListElement: breadcrumbItems,
|
|
215
|
+
};
|
|
161
216
|
if (isArticle) {
|
|
162
217
|
schema = {
|
|
163
218
|
"@context": "https://schema.org",
|
|
164
|
-
"@
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
219
|
+
"@graph": [
|
|
220
|
+
websiteEntity,
|
|
221
|
+
authorEntity,
|
|
222
|
+
publisher,
|
|
223
|
+
breadcrumbEntity,
|
|
224
|
+
{
|
|
225
|
+
"@type": "BlogPosting",
|
|
226
|
+
"@id": `${canonicalUrl}#article`,
|
|
227
|
+
headline: contentTitle,
|
|
228
|
+
description: effectiveDescription,
|
|
229
|
+
url: canonicalUrl,
|
|
230
|
+
...(ogImagePath ? { image: ogImagePath } : {}),
|
|
231
|
+
...(props.date ? { datePublished: props.date } : {}),
|
|
232
|
+
...(props.updated || props.date ? { dateModified: props.updated || props.date } : {}),
|
|
233
|
+
...(props.tags?.length ? { keywords: props.tags.join(", ") } : {}),
|
|
234
|
+
...(props.categories?.length ? { articleSection: props.categories } : {}),
|
|
235
|
+
author: { "@id": `${siteUrl}/#author`, ...(props.author ? { name: props.author } : {}) },
|
|
236
|
+
publisher: { "@id": `${siteUrl}/#publisher` },
|
|
237
|
+
isPartOf: { "@id": `${siteUrl}/#website` },
|
|
238
|
+
inLanguage: siteConfig.lang || "zh-CN",
|
|
239
|
+
mainEntityOfPage: {
|
|
240
|
+
"@type": "WebPage",
|
|
241
|
+
"@id": canonicalUrl,
|
|
242
|
+
},
|
|
243
|
+
},
|
|
244
|
+
],
|
|
179
245
|
};
|
|
180
246
|
} else if (routeKind === "home") {
|
|
181
247
|
schema = {
|
|
182
248
|
"@context": "https://schema.org",
|
|
183
|
-
"@
|
|
184
|
-
url: canonicalUrl,
|
|
185
|
-
name: effectiveTitle,
|
|
186
|
-
description: effectiveDescription,
|
|
187
|
-
inLanguage: siteConfig.lang || "zh-CN",
|
|
188
|
-
publisher,
|
|
189
|
-
author: authorEntity,
|
|
249
|
+
"@graph": [websiteEntity, authorEntity, publisher],
|
|
190
250
|
};
|
|
191
251
|
} else {
|
|
192
252
|
schema = {
|
|
193
253
|
"@context": "https://schema.org",
|
|
194
|
-
"@
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
254
|
+
"@graph": [
|
|
255
|
+
websiteEntity,
|
|
256
|
+
authorEntity,
|
|
257
|
+
publisher,
|
|
258
|
+
breadcrumbEntity,
|
|
259
|
+
{
|
|
260
|
+
"@type": isCollectionPage ? "CollectionPage" : routeKind === "about" ? "AboutPage" : "WebPage",
|
|
261
|
+
"@id": canonicalUrl,
|
|
262
|
+
url: canonicalUrl,
|
|
263
|
+
name: contentTitle,
|
|
264
|
+
description: effectiveDescription,
|
|
265
|
+
inLanguage: siteConfig.lang || "zh-CN",
|
|
266
|
+
isPartOf: { "@id": `${siteUrl}/#website` },
|
|
267
|
+
breadcrumb: { "@id": `${canonicalUrl}#breadcrumb` },
|
|
268
|
+
},
|
|
269
|
+
],
|
|
200
270
|
};
|
|
201
271
|
}
|
|
202
272
|
const ldJson = JSON.stringify(schema, null, 2).replace(/<\//g, "<\\/");
|
|
@@ -233,4 +303,3 @@ const ldJson = JSON.stringify(schema, null, 2).replace(/<\//g, "<\\/");
|
|
|
233
303
|
<script type="application/ld+json" set:html={ldJson} />
|
|
234
304
|
<VerCount />
|
|
235
305
|
</head>
|
|
236
|
-
|
package/src/pages/links.astro
CHANGED
|
@@ -7,17 +7,16 @@ import { getSiteData, getLinksData } from "@utils/config-utils";
|
|
|
7
7
|
const configEntries = await getCollection("config");
|
|
8
8
|
const siteConfig = getSiteData(configEntries);
|
|
9
9
|
const linksConfig = getLinksData(configEntries)!;
|
|
10
|
-
const siteTitle = siteConfig.title;
|
|
11
10
|
const siteDescription = siteConfig.description;
|
|
12
11
|
const linksTitle = linksConfig.title;
|
|
13
12
|
const linksDescription = linksConfig.description;
|
|
14
13
|
---
|
|
15
14
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
15
|
+
<ListPage
|
|
16
|
+
title={linksTitle}
|
|
17
|
+
description={linksDescription || siteDescription}
|
|
18
|
+
heading={linksTitle}
|
|
19
|
+
subheading={linksDescription}
|
|
20
|
+
>
|
|
22
21
|
<LinkList />
|
|
23
22
|
</ListPage>
|
package/src/schemas/config.ts
CHANGED