wpheadless-lib 1.0.0
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/dist/api/categories.d.ts +29 -0
- package/dist/api/categories.js +91 -0
- package/dist/api/index.d.ts +6 -0
- package/dist/api/index.js +6 -0
- package/dist/api/mappers.d.ts +5 -0
- package/dist/api/mappers.js +30 -0
- package/dist/api/posts.d.ts +44 -0
- package/dist/api/posts.js +104 -0
- package/dist/api/translations.d.ts +16 -0
- package/dist/api/translations.js +28 -0
- package/dist/api/types.d.ts +30 -0
- package/dist/api/types.js +1 -0
- package/dist/api/wpClient.d.ts +31 -0
- package/dist/api/wpClient.js +23 -0
- package/dist/app/config.d.ts +5 -0
- package/dist/app/config.js +28 -0
- package/dist/app/globals.css +326 -0
- package/dist/base/category/index.d.ts +38 -0
- package/dist/base/category/index.js +104 -0
- package/dist/base/category/pagination.d.ts +44 -0
- package/dist/base/category/pagination.js +114 -0
- package/dist/base/home/index.d.ts +13 -0
- package/dist/base/home/index.js +20 -0
- package/dist/base/home/pagination.d.ts +36 -0
- package/dist/base/home/pagination.js +83 -0
- package/dist/base/index.d.ts +7 -0
- package/dist/base/index.js +7 -0
- package/dist/base/layout/RootLayoutBase.d.ts +22 -0
- package/dist/base/layout/RootLayoutBase.js +15 -0
- package/dist/base/legal/index.d.ts +31 -0
- package/dist/base/legal/index.js +167 -0
- package/dist/base/post/index.d.ts +31 -0
- package/dist/base/post/index.js +97 -0
- package/dist/components/Breadcrumbs/index.d.ts +9 -0
- package/dist/components/Breadcrumbs/index.js +11 -0
- package/dist/components/Breadcrumbs/index.module.css +39 -0
- package/dist/components/Paginator/index.d.ts +10 -0
- package/dist/components/Paginator/index.js +16 -0
- package/dist/components/Paginator/index.module.css +13 -0
- package/dist/components/Paginator/index.utils.d.ts +7 -0
- package/dist/components/Paginator/index.utils.js +19 -0
- package/dist/components/PostCard/index.d.ts +10 -0
- package/dist/components/PostCard/index.js +22 -0
- package/dist/components/PostCard/index.module.css +56 -0
- package/dist/components/PostCard/index.types.d.ts +7 -0
- package/dist/components/PostCard/index.types.js +1 -0
- package/dist/components/PostCard/index.utils.d.ts +8 -0
- package/dist/components/PostCard/index.utils.js +23 -0
- package/dist/components/index.d.ts +5 -0
- package/dist/components/index.js +5 -0
- package/dist/components/layout/Footer/index.d.ts +12 -0
- package/dist/components/layout/Footer/index.js +36 -0
- package/dist/components/layout/Footer/index.module.css +61 -0
- package/dist/components/layout/Header/index.d.ts +13 -0
- package/dist/components/layout/Header/index.js +36 -0
- package/dist/components/layout/Header/index.module.css +48 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +6 -0
- package/dist/plugins/index.d.ts +1 -0
- package/dist/plugins/index.js +1 -0
- package/dist/plugins/yoast/index.d.ts +16 -0
- package/dist/plugins/yoast/index.js +44 -0
- package/dist/utils/hreflang.d.ts +37 -0
- package/dist/utils/hreflang.js +95 -0
- package/dist/utils/html.d.ts +4 -0
- package/dist/utils/html.js +8 -0
- package/dist/utils/i18n.d.ts +12 -0
- package/dist/utils/i18n.js +161 -0
- package/dist/utils/index.d.ts +6 -0
- package/dist/utils/index.js +6 -0
- package/dist/utils/routing.d.ts +40 -0
- package/dist/utils/routing.js +84 -0
- package/dist/utils/seo.d.ts +75 -0
- package/dist/utils/seo.js +97 -0
- package/dist/utils/sitemap.d.ts +26 -0
- package/dist/utils/sitemap.js +327 -0
- package/dist/views/CategoryListView/index.d.ts +12 -0
- package/dist/views/CategoryListView/index.js +17 -0
- package/dist/views/CategoryListView/index.module.css +39 -0
- package/dist/views/CategoryListView/index.utils.d.ts +5 -0
- package/dist/views/CategoryListView/index.utils.js +14 -0
- package/dist/views/CategoryPaginationView/index.d.ts +13 -0
- package/dist/views/CategoryPaginationView/index.js +18 -0
- package/dist/views/CategoryPaginationView/index.module.css +39 -0
- package/dist/views/CategoryPaginationView/index.utils.d.ts +5 -0
- package/dist/views/CategoryPaginationView/index.utils.js +4 -0
- package/dist/views/HomePaginationView/index.d.ts +13 -0
- package/dist/views/HomePaginationView/index.js +9 -0
- package/dist/views/HomePaginationView/index.module.css +38 -0
- package/dist/views/HomePaginationView/index.utils.d.ts +7 -0
- package/dist/views/HomePaginationView/index.utils.js +10 -0
- package/dist/views/HomeView/index.d.ts +13 -0
- package/dist/views/HomeView/index.js +21 -0
- package/dist/views/HomeView/index.module.css +78 -0
- package/dist/views/HomeView/index.utils.d.ts +23 -0
- package/dist/views/HomeView/index.utils.js +44 -0
- package/dist/views/LegalPageView/index.d.ts +8 -0
- package/dist/views/LegalPageView/index.js +12 -0
- package/dist/views/LegalPageView/index.module.css +39 -0
- package/dist/views/LegalPageView/index.utils.d.ts +11 -0
- package/dist/views/LegalPageView/index.utils.js +16 -0
- package/dist/views/PostView/index.d.ts +10 -0
- package/dist/views/PostView/index.js +26 -0
- package/dist/views/PostView/index.module.css +80 -0
- package/dist/views/PostView/index.types.d.ts +2 -0
- package/dist/views/PostView/index.types.js +1 -0
- package/dist/views/PostView/index.utils.d.ts +15 -0
- package/dist/views/PostView/index.utils.js +22 -0
- package/dist/views/index.d.ts +6 -0
- package/dist/views/index.js +6 -0
- package/package.json +45 -0
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
import { createPageEndpoints, createPostsEndpoints } from "wpjsapi-lib";
|
|
2
|
+
import { createWpClient } from "../api/wpClient";
|
|
3
|
+
import { listPostsWithEmbeds } from "../api/posts";
|
|
4
|
+
import { getCategoryPaginationStaticParams } from "../base";
|
|
5
|
+
import { getHomePaginationStaticParams } from "../base/home/pagination";
|
|
6
|
+
import { getAbsoluteUrl, ensureTrailingSlash } from "./routing";
|
|
7
|
+
import { getTranslationKey, getEntityLanguageId, withXDefault, } from "./hreflang";
|
|
8
|
+
const resolveWpApiUrl = (cfg) => cfg.wpApiUrl ?? process.env.WP_API_URL ?? "";
|
|
9
|
+
const resolveSiteUrl = (cfg) => cfg.siteUrl ?? process.env.NEXT_PUBLIC_SITE_URL;
|
|
10
|
+
const buildHomeAlternates = (cfg) => withXDefault(cfg.languages.reduce((acc, langCfg) => {
|
|
11
|
+
const basePath = ensureTrailingSlash(langCfg.basePath || "/");
|
|
12
|
+
acc[langCfg.code] = getAbsoluteUrl(basePath, resolveSiteUrl(cfg));
|
|
13
|
+
return acc;
|
|
14
|
+
}, {}));
|
|
15
|
+
export function renderSitemap(entries) {
|
|
16
|
+
const items = entries
|
|
17
|
+
.map((entry) => {
|
|
18
|
+
const links = entry.alternates &&
|
|
19
|
+
Object.entries(entry.alternates)
|
|
20
|
+
.map(([code, href]) => `<xhtml:link rel="alternate" hreflang="${code}" href="${href}" />`)
|
|
21
|
+
.join("");
|
|
22
|
+
return `<url><loc>${entry.url}</loc>${entry.lastmod ? `<lastmod>${entry.lastmod}</lastmod>` : ""}${links ?? ""}</url>`;
|
|
23
|
+
})
|
|
24
|
+
.join("");
|
|
25
|
+
return (`<?xml version="1.0" encoding="UTF-8"?>` +
|
|
26
|
+
`<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml">` +
|
|
27
|
+
items +
|
|
28
|
+
`</urlset>`);
|
|
29
|
+
}
|
|
30
|
+
export function renderSitemapIndex(sitemaps) {
|
|
31
|
+
const items = sitemaps
|
|
32
|
+
.map((s) => `<sitemap><loc>${s.url}</loc>${s.lastmod ? `<lastmod>${s.lastmod}</lastmod>` : ""}</sitemap>`)
|
|
33
|
+
.join("");
|
|
34
|
+
return (`<?xml version="1.0" encoding="UTF-8"?>` +
|
|
35
|
+
`<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">` +
|
|
36
|
+
items +
|
|
37
|
+
`</sitemapindex>`);
|
|
38
|
+
}
|
|
39
|
+
export async function getHomeEntries(cfg) {
|
|
40
|
+
const entries = [];
|
|
41
|
+
const { languages, runtimeConfig } = cfg;
|
|
42
|
+
const wpApiUrl = resolveWpApiUrl(cfg);
|
|
43
|
+
const siteUrl = resolveSiteUrl(cfg);
|
|
44
|
+
const homeAlternates = buildHomeAlternates(cfg);
|
|
45
|
+
for (const langCfg of languages) {
|
|
46
|
+
const basePath = ensureTrailingSlash(langCfg.basePath || "/");
|
|
47
|
+
const homeUrl = getAbsoluteUrl(basePath, siteUrl);
|
|
48
|
+
const homePosts = await listPostsWithEmbeds({
|
|
49
|
+
baseApiUrl: wpApiUrl,
|
|
50
|
+
perPage: runtimeConfig.postsPerPagePagination,
|
|
51
|
+
page: 1,
|
|
52
|
+
langId: langCfg.langId,
|
|
53
|
+
orderby: "date",
|
|
54
|
+
order: "desc",
|
|
55
|
+
});
|
|
56
|
+
const latest = homePosts.ok ? homePosts.data?.items[0] : undefined;
|
|
57
|
+
const lastmod = latest?.modified ||
|
|
58
|
+
latest?.date;
|
|
59
|
+
entries.push({
|
|
60
|
+
url: homeUrl,
|
|
61
|
+
lastmod: lastmod ? new Date(lastmod).toISOString() : undefined,
|
|
62
|
+
alternates: homeAlternates ?? undefined,
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
return entries;
|
|
66
|
+
}
|
|
67
|
+
export async function getHomePaginationEntries(cfg) {
|
|
68
|
+
const entries = [];
|
|
69
|
+
const { languages, runtimeConfig } = cfg;
|
|
70
|
+
const wpApiUrl = resolveWpApiUrl(cfg);
|
|
71
|
+
const siteUrl = resolveSiteUrl(cfg);
|
|
72
|
+
for (const langCfg of languages) {
|
|
73
|
+
const basePath = ensureTrailingSlash(langCfg.basePath || "/");
|
|
74
|
+
const pages = await getHomePaginationStaticParams({
|
|
75
|
+
baseApiUrl: wpApiUrl,
|
|
76
|
+
perPage: runtimeConfig.postsPerPagePagination,
|
|
77
|
+
langId: langCfg.langId,
|
|
78
|
+
});
|
|
79
|
+
for (const p of pages) {
|
|
80
|
+
const url = getAbsoluteUrl(`${basePath}page/${p.page}/`, siteUrl);
|
|
81
|
+
const pagePosts = await listPostsWithEmbeds({
|
|
82
|
+
baseApiUrl: wpApiUrl,
|
|
83
|
+
perPage: runtimeConfig.postsPerPagePagination,
|
|
84
|
+
page: Number(p.page),
|
|
85
|
+
langId: langCfg.langId,
|
|
86
|
+
orderby: "date",
|
|
87
|
+
order: "desc",
|
|
88
|
+
});
|
|
89
|
+
const latest = pagePosts.ok ? pagePosts.data?.items[0] : undefined;
|
|
90
|
+
const lastmod = latest?.modified ||
|
|
91
|
+
latest?.date;
|
|
92
|
+
entries.push({
|
|
93
|
+
url,
|
|
94
|
+
lastmod: lastmod ? new Date(lastmod).toISOString() : undefined,
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return entries;
|
|
99
|
+
}
|
|
100
|
+
export async function getCategoryEntries(cfg) {
|
|
101
|
+
const entries = [];
|
|
102
|
+
const { languages, runtimeConfig } = cfg;
|
|
103
|
+
const wpApiUrl = resolveWpApiUrl(cfg);
|
|
104
|
+
const siteUrl = resolveSiteUrl(cfg);
|
|
105
|
+
const categoriesPerLang = {};
|
|
106
|
+
const categoryAlternates = {};
|
|
107
|
+
for (const langCfg of languages) {
|
|
108
|
+
const { categoriesApi } = createWpClient({ baseUrl: wpApiUrl });
|
|
109
|
+
const categories = await categoriesApi.listAll({
|
|
110
|
+
lang: langCfg.code,
|
|
111
|
+
_fields: ["id", "slug", "name", "description", "meta"],
|
|
112
|
+
});
|
|
113
|
+
categoriesPerLang[langCfg.code] = categories;
|
|
114
|
+
const basePath = ensureTrailingSlash(langCfg.basePath || "/");
|
|
115
|
+
for (const cat of categories) {
|
|
116
|
+
const translationKey = getTranslationKey(cat);
|
|
117
|
+
if (!translationKey)
|
|
118
|
+
continue;
|
|
119
|
+
const url = getAbsoluteUrl(`${basePath}${cat.slug}/`, siteUrl);
|
|
120
|
+
if (!categoryAlternates[translationKey]) {
|
|
121
|
+
categoryAlternates[translationKey] = {};
|
|
122
|
+
}
|
|
123
|
+
categoryAlternates[translationKey][langCfg.code] = url;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
for (const langCfg of languages) {
|
|
127
|
+
const basePath = ensureTrailingSlash(langCfg.basePath || "/");
|
|
128
|
+
const categories = categoriesPerLang[langCfg.code] ?? [];
|
|
129
|
+
for (const cat of categories) {
|
|
130
|
+
const url = getAbsoluteUrl(`${basePath}${cat.slug}/`, siteUrl);
|
|
131
|
+
const catPosts = await listPostsWithEmbeds({
|
|
132
|
+
baseApiUrl: wpApiUrl,
|
|
133
|
+
categories: [cat.id],
|
|
134
|
+
perPage: runtimeConfig.postsPerPagePagination,
|
|
135
|
+
page: 1,
|
|
136
|
+
langId: langCfg.langId || "",
|
|
137
|
+
orderby: "date",
|
|
138
|
+
order: "desc",
|
|
139
|
+
});
|
|
140
|
+
const latest = catPosts.ok ? catPosts.data?.items[0] : undefined;
|
|
141
|
+
const lastmod = latest?.modified ||
|
|
142
|
+
latest?.date;
|
|
143
|
+
const alt = (() => {
|
|
144
|
+
const key = getTranslationKey(cat);
|
|
145
|
+
if (!key)
|
|
146
|
+
return undefined;
|
|
147
|
+
const a = withXDefault(categoryAlternates[key]);
|
|
148
|
+
return a;
|
|
149
|
+
})();
|
|
150
|
+
entries.push({
|
|
151
|
+
url,
|
|
152
|
+
lastmod: lastmod ? new Date(lastmod).toISOString() : undefined,
|
|
153
|
+
alternates: alt,
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
return entries;
|
|
158
|
+
}
|
|
159
|
+
export async function getCategoryPaginationEntries(cfg) {
|
|
160
|
+
const entries = [];
|
|
161
|
+
const { languages, runtimeConfig } = cfg;
|
|
162
|
+
const wpApiUrl = resolveWpApiUrl(cfg);
|
|
163
|
+
const siteUrl = resolveSiteUrl(cfg);
|
|
164
|
+
const catIdsBySlugByLang = {};
|
|
165
|
+
for (const langCfg of languages) {
|
|
166
|
+
const { categoriesApi } = createWpClient({ baseUrl: wpApiUrl });
|
|
167
|
+
const categories = await categoriesApi.listAll({
|
|
168
|
+
lang: langCfg.code,
|
|
169
|
+
_fields: ["id", "slug"],
|
|
170
|
+
});
|
|
171
|
+
catIdsBySlugByLang[langCfg.code] = Object.fromEntries(categories.map((c) => [c.slug, c.id]));
|
|
172
|
+
}
|
|
173
|
+
for (const langCfg of languages) {
|
|
174
|
+
const catPages = await getCategoryPaginationStaticParams({
|
|
175
|
+
baseApiUrl: wpApiUrl,
|
|
176
|
+
perPage: runtimeConfig.postsPerPagePagination,
|
|
177
|
+
lang: langCfg.code,
|
|
178
|
+
langId: langCfg.langId || "",
|
|
179
|
+
});
|
|
180
|
+
const basePath = ensureTrailingSlash(langCfg.basePath || "/");
|
|
181
|
+
for (const page of catPages) {
|
|
182
|
+
const url = getAbsoluteUrl(`${basePath}${page.category}/page/${page.page}/`, siteUrl);
|
|
183
|
+
const catId = catIdsBySlugByLang[langCfg.code]?.[page.category];
|
|
184
|
+
let lastmod;
|
|
185
|
+
if (catId) {
|
|
186
|
+
const pagePosts = await listPostsWithEmbeds({
|
|
187
|
+
baseApiUrl: wpApiUrl,
|
|
188
|
+
categories: [catId],
|
|
189
|
+
perPage: runtimeConfig.postsPerPagePagination,
|
|
190
|
+
page: Number(page.page),
|
|
191
|
+
langId: langCfg.langId || "",
|
|
192
|
+
orderby: "date",
|
|
193
|
+
order: "desc",
|
|
194
|
+
});
|
|
195
|
+
const latest = pagePosts.ok ? pagePosts.data?.items[0] : undefined;
|
|
196
|
+
lastmod =
|
|
197
|
+
latest?.modified ||
|
|
198
|
+
latest?.date;
|
|
199
|
+
}
|
|
200
|
+
entries.push({
|
|
201
|
+
url,
|
|
202
|
+
lastmod: lastmod ? new Date(lastmod).toISOString() : undefined,
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
return entries;
|
|
207
|
+
}
|
|
208
|
+
export async function getPostEntriesForLang(langCode, cfg) {
|
|
209
|
+
const { languages } = cfg;
|
|
210
|
+
const langCfg = languages.find((l) => l.code === langCode);
|
|
211
|
+
if (!langCfg)
|
|
212
|
+
return [];
|
|
213
|
+
const wpApiUrl = resolveWpApiUrl(cfg);
|
|
214
|
+
const siteUrl = resolveSiteUrl(cfg);
|
|
215
|
+
const postsApi = createPostsEndpoints({ baseUrl: wpApiUrl });
|
|
216
|
+
const posts = await postsApi.listAll({
|
|
217
|
+
per_page: 100,
|
|
218
|
+
_embed: true,
|
|
219
|
+
taxonomies: { language: [Number(langCfg.langId)] },
|
|
220
|
+
});
|
|
221
|
+
const postAlternates = {};
|
|
222
|
+
for (const l of languages) {
|
|
223
|
+
const base = ensureTrailingSlash(l.basePath || "/");
|
|
224
|
+
const langPosts = l.code === langCfg.code
|
|
225
|
+
? posts
|
|
226
|
+
: await postsApi.listAll({
|
|
227
|
+
per_page: 100,
|
|
228
|
+
_embed: true,
|
|
229
|
+
taxonomies: { language: [Number(l.langId)] },
|
|
230
|
+
});
|
|
231
|
+
for (const p of langPosts) {
|
|
232
|
+
const translationKey = getTranslationKey(p);
|
|
233
|
+
if (!translationKey)
|
|
234
|
+
continue;
|
|
235
|
+
const category = p._embedded?.["wp:term"]?.[0]?.[0];
|
|
236
|
+
const categorySlug = category?.slug;
|
|
237
|
+
if (!categorySlug)
|
|
238
|
+
continue;
|
|
239
|
+
const url = getAbsoluteUrl(`${base}${categorySlug}/${p.slug}/`, siteUrl);
|
|
240
|
+
if (!postAlternates[translationKey])
|
|
241
|
+
postAlternates[translationKey] = {};
|
|
242
|
+
postAlternates[translationKey][l.code] = url;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
const basePath = ensureTrailingSlash(langCfg.basePath || "/");
|
|
246
|
+
return posts
|
|
247
|
+
.map((p) => {
|
|
248
|
+
const category = p._embedded?.["wp:term"]?.[0]?.[0];
|
|
249
|
+
const categorySlug = category?.slug;
|
|
250
|
+
if (!categorySlug)
|
|
251
|
+
return null;
|
|
252
|
+
const url = getAbsoluteUrl(`${basePath}${categorySlug}/${p.slug}/`, siteUrl);
|
|
253
|
+
const lastmod = p.modified ||
|
|
254
|
+
p.date;
|
|
255
|
+
const translationKey = getTranslationKey(p);
|
|
256
|
+
const alts = translationKey
|
|
257
|
+
? withXDefault(postAlternates[translationKey])
|
|
258
|
+
: undefined;
|
|
259
|
+
return {
|
|
260
|
+
url,
|
|
261
|
+
lastmod: lastmod ? new Date(lastmod).toISOString() : undefined,
|
|
262
|
+
alternates: alts,
|
|
263
|
+
};
|
|
264
|
+
})
|
|
265
|
+
.filter(Boolean);
|
|
266
|
+
}
|
|
267
|
+
export async function getLegalEntries(cfg) {
|
|
268
|
+
const entries = [];
|
|
269
|
+
const { languages } = cfg;
|
|
270
|
+
const siteUrl = resolveSiteUrl(cfg);
|
|
271
|
+
const wpApiUrl = resolveWpApiUrl(cfg);
|
|
272
|
+
const pagesApi = createPageEndpoints({ baseUrl: wpApiUrl });
|
|
273
|
+
const pagesPerLang = {};
|
|
274
|
+
const alternatesByKey = {};
|
|
275
|
+
for (const langCfg of languages) {
|
|
276
|
+
const parent = await pagesApi.list({
|
|
277
|
+
slug: "legal",
|
|
278
|
+
per_page: 1,
|
|
279
|
+
_fields: ["id", "language", "taxonomies", "meta"],
|
|
280
|
+
});
|
|
281
|
+
const parentId = parent.items.find((p) => getEntityLanguageId(p)?.toString() === langCfg.langId?.toString())?.id ?? parent.items[0]?.id;
|
|
282
|
+
if (!parentId)
|
|
283
|
+
continue;
|
|
284
|
+
const pages = await pagesApi.listAll({
|
|
285
|
+
parent: parentId,
|
|
286
|
+
_fields: [
|
|
287
|
+
"slug",
|
|
288
|
+
"date",
|
|
289
|
+
"modified",
|
|
290
|
+
"meta",
|
|
291
|
+
"taxonomies",
|
|
292
|
+
"parent",
|
|
293
|
+
"language",
|
|
294
|
+
],
|
|
295
|
+
});
|
|
296
|
+
const filtered = pages.filter((p) => getEntityLanguageId(p)?.toString() === langCfg.langId?.toString());
|
|
297
|
+
pagesPerLang[langCfg.code] = filtered;
|
|
298
|
+
const basePath = ensureTrailingSlash(langCfg.basePath || "/");
|
|
299
|
+
for (const p of filtered) {
|
|
300
|
+
const translationKey = getTranslationKey(p);
|
|
301
|
+
if (!translationKey)
|
|
302
|
+
continue;
|
|
303
|
+
const url = getAbsoluteUrl(`${basePath}legal/${p.slug}/`, siteUrl);
|
|
304
|
+
if (!alternatesByKey[translationKey])
|
|
305
|
+
alternatesByKey[translationKey] = {};
|
|
306
|
+
alternatesByKey[translationKey][langCfg.code] = url;
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
for (const langCfg of languages) {
|
|
310
|
+
const basePath = ensureTrailingSlash(langCfg.basePath || "/");
|
|
311
|
+
const pages = pagesPerLang[langCfg.code] ?? [];
|
|
312
|
+
for (const p of pages) {
|
|
313
|
+
const url = getAbsoluteUrl(`${basePath}legal/${p.slug}/`, siteUrl);
|
|
314
|
+
const lastmod = p.modified || p.date;
|
|
315
|
+
const translationKey = getTranslationKey(p);
|
|
316
|
+
const alts = translationKey
|
|
317
|
+
? withXDefault(alternatesByKey[translationKey])
|
|
318
|
+
: undefined;
|
|
319
|
+
entries.push({
|
|
320
|
+
url,
|
|
321
|
+
lastmod: lastmod ? new Date(lastmod).toISOString() : undefined,
|
|
322
|
+
alternates: alts,
|
|
323
|
+
});
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
return entries;
|
|
327
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type WPCategory, type WPPost } from "wpjsapi-lib";
|
|
2
|
+
import { type Locale } from "../../utils";
|
|
3
|
+
type CategoryListViewProps = {
|
|
4
|
+
category: WPCategory;
|
|
5
|
+
posts: WPPost[];
|
|
6
|
+
totalPages: number;
|
|
7
|
+
baseUrl?: string;
|
|
8
|
+
locale?: Locale;
|
|
9
|
+
dateLocale?: string;
|
|
10
|
+
};
|
|
11
|
+
export declare function CategoryListView({ category, posts, totalPages, baseUrl, locale, dateLocale, }: CategoryListViewProps): import("react/jsx-runtime").JSX.Element;
|
|
12
|
+
export {};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import Paginator from "../../components/Paginator";
|
|
3
|
+
import PostCard from "../../components/PostCard";
|
|
4
|
+
import styles from "./index.module.css";
|
|
5
|
+
import { getCountLabel, getEmptyLabel, getPaginatorBase } from "./index.utils";
|
|
6
|
+
import { Breadcrumbs } from "../../components";
|
|
7
|
+
import { getTranslator } from "../../utils";
|
|
8
|
+
export function CategoryListView({ category, posts, totalPages, baseUrl, locale, dateLocale = "en-US", }) {
|
|
9
|
+
const paginatorBase = getPaginatorBase(category, baseUrl);
|
|
10
|
+
const countLabel = getCountLabel(category, locale);
|
|
11
|
+
const emptyLabel = getEmptyLabel(locale);
|
|
12
|
+
const t = getTranslator(locale);
|
|
13
|
+
return (_jsxs("div", { className: `container ${styles.container}`, children: [_jsxs("header", { className: styles.header, children: [_jsx(Breadcrumbs, { items: [
|
|
14
|
+
{ label: "Home", href: baseUrl || "/" },
|
|
15
|
+
{ label: category.name },
|
|
16
|
+
] }), _jsx("h1", { className: styles.title, children: category.name }), category.description && (_jsx("div", { className: styles.description, dangerouslySetInnerHTML: { __html: category.description } })), countLabel && _jsx("p", { className: styles.count, children: countLabel })] }), posts.length === 0 ? (_jsx("p", { className: styles.empty, children: emptyLabel })) : (_jsxs("section", { "aria-label": t("home.title"), className: styles.gridSection, children: [_jsx("div", { className: styles.grid, children: posts.map((post) => (_jsx(PostCard, { post: post, categorySlug: category.slug, locale: locale, dateLocale: dateLocale }, post.id))) }), _jsx(Paginator, { currentPage: 1, totalPages: totalPages, baseUrl: paginatorBase, locale: locale })] }))] }));
|
|
17
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
.container {
|
|
2
|
+
padding-top: var(--spacing-xl);
|
|
3
|
+
padding-bottom: var(--spacing-xl);
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
.header {
|
|
7
|
+
margin-bottom: var(--spacing-xl);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
.title {
|
|
11
|
+
font-size: clamp(2rem, 4vw, 2.5rem);
|
|
12
|
+
font-weight: 800;
|
|
13
|
+
margin-bottom: var(--spacing-sm);
|
|
14
|
+
color: var(--foreground);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.description {
|
|
18
|
+
font-size: 1.125rem;
|
|
19
|
+
color: var(--foreground-light);
|
|
20
|
+
line-height: 1.6;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.count {
|
|
24
|
+
font-size: 0.875rem;
|
|
25
|
+
color: var(--foreground-light);
|
|
26
|
+
margin-top: var(--spacing-xs);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.empty {
|
|
30
|
+
text-align: center;
|
|
31
|
+
color: var(--foreground-light);
|
|
32
|
+
padding: var(--spacing-xl);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.grid {
|
|
36
|
+
display: grid;
|
|
37
|
+
grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
|
|
38
|
+
gap: var(--spacing-md);
|
|
39
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { type WPCategory } from "wpjsapi-lib";
|
|
2
|
+
import { type Locale } from "../../utils";
|
|
3
|
+
export declare const getPaginatorBase: (category: WPCategory, baseUrl?: string) => string;
|
|
4
|
+
export declare const getCountLabel: (category: WPCategory, locale?: Locale) => string | null;
|
|
5
|
+
export declare const getEmptyLabel: (locale?: Locale) => string;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { getTranslator } from "../../utils";
|
|
2
|
+
export const getPaginatorBase = (category, baseUrl) => baseUrl ?? `/${category.slug}`;
|
|
3
|
+
export const getCountLabel = (category, locale) => {
|
|
4
|
+
const t = getTranslator(locale);
|
|
5
|
+
const countValue = typeof category.count === "number" && !Number.isNaN(category.count)
|
|
6
|
+
? category.count
|
|
7
|
+
: null;
|
|
8
|
+
if (countValue === null)
|
|
9
|
+
return null;
|
|
10
|
+
return countValue === 1
|
|
11
|
+
? t("category.countOne", { count: countValue })
|
|
12
|
+
: t("category.countMany", { count: countValue });
|
|
13
|
+
};
|
|
14
|
+
export const getEmptyLabel = (locale) => getTranslator(locale)("category.empty");
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type WPCategory, type WPPost } from "wpjsapi-lib";
|
|
2
|
+
import { type Locale } from "../../utils";
|
|
3
|
+
type CategoryPaginationViewProps = {
|
|
4
|
+
category: WPCategory;
|
|
5
|
+
posts: WPPost[];
|
|
6
|
+
currentPage: number;
|
|
7
|
+
totalPages: number;
|
|
8
|
+
baseUrl?: string;
|
|
9
|
+
locale?: Locale;
|
|
10
|
+
dateLocale?: string;
|
|
11
|
+
};
|
|
12
|
+
export declare function CategoryPaginationView({ category, posts, currentPage, totalPages, baseUrl, locale, dateLocale, }: CategoryPaginationViewProps): import("react/jsx-runtime").JSX.Element;
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import Paginator from "../../components/Paginator";
|
|
3
|
+
import PostCard from "../../components/PostCard";
|
|
4
|
+
import styles from "./index.module.css";
|
|
5
|
+
import { getEmptyLabel, getPageLabel, getPaginatorBase } from "./index.utils";
|
|
6
|
+
import { Breadcrumbs } from "../../components";
|
|
7
|
+
import { getTranslator } from "../../utils";
|
|
8
|
+
export function CategoryPaginationView({ category, posts, currentPage, totalPages, baseUrl, locale, dateLocale = "en-US", }) {
|
|
9
|
+
const paginatorBase = getPaginatorBase(category, baseUrl);
|
|
10
|
+
const pageLabel = getPageLabel(locale, currentPage);
|
|
11
|
+
const emptyLabel = getEmptyLabel(locale);
|
|
12
|
+
const t = getTranslator(locale);
|
|
13
|
+
return (_jsxs("div", { className: `container ${styles.container}`, children: [_jsxs("header", { className: styles.header, children: [_jsx(Breadcrumbs, { items: [
|
|
14
|
+
{ label: "Home", href: paginatorBase || "/" },
|
|
15
|
+
{ label: category.name },
|
|
16
|
+
{ label: pageLabel },
|
|
17
|
+
] }), _jsx("h1", { className: styles.title, children: category.name }), category.description && (_jsx("p", { className: styles.description, dangerouslySetInnerHTML: { __html: category.description } })), _jsx("p", { className: styles.pageLabel, children: pageLabel })] }), posts.length === 0 ? (_jsx("p", { className: styles.empty, children: emptyLabel })) : (_jsxs("section", { "aria-label": t("category.pageLabel", { page: currentPage }), className: styles.gridSection, children: [_jsx("div", { className: styles.grid, children: posts.map((post) => (_jsx(PostCard, { post: post, categorySlug: category.slug, locale: locale, dateLocale: dateLocale }, post.id))) }), _jsx(Paginator, { currentPage: currentPage, totalPages: totalPages, baseUrl: paginatorBase, locale: locale })] }))] }));
|
|
18
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
.container {
|
|
2
|
+
padding-top: var(--spacing-xl);
|
|
3
|
+
padding-bottom: var(--spacing-xl);
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
.header {
|
|
7
|
+
margin-bottom: var(--spacing-xl);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
.title {
|
|
11
|
+
font-size: clamp(2rem, 4vw, 2.5rem);
|
|
12
|
+
font-weight: 800;
|
|
13
|
+
margin-bottom: var(--spacing-sm);
|
|
14
|
+
color: var(--foreground);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.description {
|
|
18
|
+
font-size: 1.125rem;
|
|
19
|
+
color: var(--foreground-light);
|
|
20
|
+
line-height: 1.6;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.pageLabel {
|
|
24
|
+
font-size: 0.875rem;
|
|
25
|
+
color: var(--foreground-light);
|
|
26
|
+
margin-top: var(--spacing-xs);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.empty {
|
|
30
|
+
text-align: center;
|
|
31
|
+
color: var(--foreground-light);
|
|
32
|
+
padding: var(--spacing-xl);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.grid {
|
|
36
|
+
display: grid;
|
|
37
|
+
grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
|
|
38
|
+
gap: var(--spacing-md);
|
|
39
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { type WPCategory } from "wpjsapi-lib";
|
|
2
|
+
import { type Locale } from "../../utils";
|
|
3
|
+
export declare const getPaginatorBase: (category: WPCategory, baseUrl?: string) => string;
|
|
4
|
+
export declare const getPageLabel: (locale: Locale | undefined, page: number) => string;
|
|
5
|
+
export declare const getEmptyLabel: (locale?: Locale) => string;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { getTranslator } from "../../utils";
|
|
2
|
+
export const getPaginatorBase = (category, baseUrl) => baseUrl ?? `/${category.slug}`;
|
|
3
|
+
export const getPageLabel = (locale, page) => getTranslator(locale)("category.pageLabel", { page });
|
|
4
|
+
export const getEmptyLabel = (locale) => getTranslator(locale)("category.emptyPage");
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type WPPost } from "wpjsapi-lib";
|
|
2
|
+
import { type Locale } from "../../utils";
|
|
3
|
+
type HomePaginationViewProps = {
|
|
4
|
+
posts: WPPost[];
|
|
5
|
+
currentPage: number;
|
|
6
|
+
totalPages: number;
|
|
7
|
+
error?: string | null;
|
|
8
|
+
baseUrl?: string;
|
|
9
|
+
locale?: Locale;
|
|
10
|
+
dateLocale?: string;
|
|
11
|
+
};
|
|
12
|
+
export declare function HomePaginationView({ posts, currentPage, totalPages, error, baseUrl, locale, dateLocale, }: HomePaginationViewProps): import("react/jsx-runtime").JSX.Element;
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import Paginator from "../../components/Paginator";
|
|
3
|
+
import PostCard from "../../components/PostCard";
|
|
4
|
+
import styles from "./index.module.css";
|
|
5
|
+
import { buildHomePaginationCopy } from "./index.utils";
|
|
6
|
+
export function HomePaginationView({ posts, currentPage, totalPages, error, baseUrl = "", locale, dateLocale = "en-US", }) {
|
|
7
|
+
const copy = buildHomePaginationCopy(locale, currentPage, error);
|
|
8
|
+
return (_jsxs("div", { className: `container ${styles.container}`, children: [_jsxs("header", { className: styles.header, children: [_jsx("h1", { className: styles.title, children: copy.title }), _jsx("p", { className: styles.subtitle, children: copy.subtitle })] }), error ? (_jsx("div", { className: `card ${styles.errorCard}`, children: copy.errorText && _jsx("p", { children: copy.errorText }) })) : posts.length === 0 ? (_jsx("p", { className: styles.empty, children: copy.empty })) : (_jsxs("section", { "aria-label": copy.title, className: styles.gridSection, role: "region", children: [_jsx("div", { className: styles.grid, children: posts.map((post) => (_jsx(PostCard, { post: post, locale: locale, dateLocale: dateLocale }, post.id))) }), _jsx(Paginator, { currentPage: currentPage, totalPages: totalPages, baseUrl: baseUrl, locale: locale })] }))] }));
|
|
9
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
.container {
|
|
2
|
+
padding-top: var(--spacing-xl);
|
|
3
|
+
padding-bottom: var(--spacing-xl);
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
.header {
|
|
7
|
+
margin-bottom: var(--spacing-xl);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
.title {
|
|
11
|
+
font-size: clamp(2rem, 4vw, 2.5rem);
|
|
12
|
+
font-weight: 800;
|
|
13
|
+
color: var(--foreground);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
.subtitle {
|
|
17
|
+
font-size: 1.125rem;
|
|
18
|
+
color: var(--foreground-light);
|
|
19
|
+
margin-top: var(--spacing-sm);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.errorCard {
|
|
23
|
+
padding: var(--spacing-lg);
|
|
24
|
+
color: #ef4444;
|
|
25
|
+
text-align: center;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.empty {
|
|
29
|
+
text-align: center;
|
|
30
|
+
color: var(--foreground-light);
|
|
31
|
+
padding: var(--spacing-xl);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.grid {
|
|
35
|
+
display: grid;
|
|
36
|
+
grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
|
|
37
|
+
gap: var(--spacing-md);
|
|
38
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { getTranslator } from "../../utils";
|
|
2
|
+
export const buildHomePaginationCopy = (locale, page, error) => {
|
|
3
|
+
const t = getTranslator(locale);
|
|
4
|
+
return {
|
|
5
|
+
title: t("home.title"),
|
|
6
|
+
subtitle: t("home.pageLabel", { page }),
|
|
7
|
+
empty: t("home.empty"),
|
|
8
|
+
errorText: error ? t("home.loadError", { error }) : null,
|
|
9
|
+
};
|
|
10
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type WPPost } from "wpjsapi-lib";
|
|
2
|
+
import { type Locale } from "../../utils";
|
|
3
|
+
type HomeViewProps = {
|
|
4
|
+
featuredPost?: WPPost;
|
|
5
|
+
regularPosts: WPPost[];
|
|
6
|
+
error?: string | null;
|
|
7
|
+
totalPages: number;
|
|
8
|
+
baseUrl?: string;
|
|
9
|
+
locale?: Locale;
|
|
10
|
+
dateLocale?: string;
|
|
11
|
+
};
|
|
12
|
+
export declare function HomeView({ featuredPost, regularPosts, error, totalPages, baseUrl, locale, dateLocale, }: HomeViewProps): import("react/jsx-runtime").JSX.Element;
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { jsxs as _jsxs, jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import Image from "next/image";
|
|
3
|
+
import Link from "next/link";
|
|
4
|
+
import Paginator from "../../components/Paginator";
|
|
5
|
+
import PostCard from "../../components/PostCard";
|
|
6
|
+
import styles from "./index.module.css";
|
|
7
|
+
import { buildFeaturedViewModel, getHomeCopy } from "./index.utils";
|
|
8
|
+
export function HomeView({ featuredPost, regularPosts, error, totalPages, baseUrl = "", locale, dateLocale = "en-US", }) {
|
|
9
|
+
const copy = getHomeCopy(locale);
|
|
10
|
+
const featuredModel = featuredPost
|
|
11
|
+
? buildFeaturedViewModel(featuredPost, locale, dateLocale)
|
|
12
|
+
: null;
|
|
13
|
+
return (_jsx("div", { className: `container ${styles.container}`, children: error ? (_jsxs("div", { className: styles.errorBox, children: [_jsxs("p", { children: [copy.errorTitle, ": ", error] }), _jsx("p", { className: styles.errorHint, children: copy.errorHint })] })) : !featuredModel && regularPosts.length === 0 ? (_jsx("p", { className: styles.empty, children: copy.empty })) : (_jsxs(_Fragment, { children: [featuredModel && (_jsxs("article", { className: `card ${styles.featured} ${featuredModel.image
|
|
14
|
+
? styles.featuredWithImage
|
|
15
|
+
: styles.featuredNoImage}`, children: [featuredModel.image && (_jsx(Link, { href: featuredModel.postUrl, className: styles.featuredImageLink, children: _jsx(Image, { src: featuredModel.image.src, alt: featuredModel.image.alt, fill: true, className: styles.featuredImage, priority: true, sizes: "(max-width: 768px) 100vw, 50vw" }) })), _jsxs("div", { className: styles.featuredBody, children: [featuredModel.badgeLabel &&
|
|
16
|
+
(featuredModel.badgeUrl ? (_jsx(Link, { href: featuredModel.badgeUrl, className: `${styles.featuredBadge} badge`, children: featuredModel.badgeLabel })) : (_jsx("span", { className: `${styles.featuredBadge} badge`, children: featuredModel.badgeLabel }))), _jsx(Link, { href: featuredModel.postUrl, children: _jsx("h2", { dangerouslySetInnerHTML: {
|
|
17
|
+
__html: featuredModel.titleHtml,
|
|
18
|
+
}, className: styles.featuredTitle }) }), _jsx("div", { dangerouslySetInnerHTML: {
|
|
19
|
+
__html: featuredModel.excerptHtml,
|
|
20
|
+
}, className: `text-muted ${styles.featuredExcerpt}` }), _jsx("time", { dateTime: featuredModel.dateTime, className: `text-muted ${styles.featuredDate}`, children: featuredModel.dateLabel })] })] })), _jsx("section", { className: styles.postsGrid, "aria-label": copy.title, role: "region", children: regularPosts.map((post) => (_jsx(PostCard, { post: post, locale: locale }, post.id))) }), _jsx(Paginator, { currentPage: 1, totalPages: totalPages, baseUrl: baseUrl, locale: locale })] })) }));
|
|
21
|
+
}
|