@canopy-iiif/app 1.8.14 → 1.9.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/lib/build/iiif.js +176 -102
- package/lib/build/mdx.js +39 -3
- package/lib/build/pages.js +15 -1
- package/lib/build/search-index.js +3 -2
- package/lib/build/search-workflow.js +16 -5
- package/lib/common.js +272 -15
- package/lib/components/referenced.js +7 -2
- package/lib/locales.js +172 -0
- package/lib/search/search-app.jsx +68 -7
- package/lib/search/search-form-runtime.js +46 -1
- package/lib/search/search.js +82 -16
- package/package.json +1 -1
- package/ui/dist/index.mjs +674 -285
- package/ui/dist/index.mjs.map +4 -4
- package/ui/dist/server.mjs +668 -279
- package/ui/dist/server.mjs.map +4 -4
- package/ui/styles/components/_gallery.scss +57 -86
- package/ui/styles/components/header/_header.scss +113 -1
- package/ui/styles/index.css +141 -64
package/lib/build/iiif.js
CHANGED
|
@@ -16,7 +16,14 @@ const {
|
|
|
16
16
|
readSiteMetadata,
|
|
17
17
|
readPrimaryNavigation,
|
|
18
18
|
withBase,
|
|
19
|
+
resolveLocaleFromHref,
|
|
20
|
+
getLocaleRouteEntries,
|
|
21
|
+
getDefaultRoute,
|
|
22
|
+
buildRouteRelativePath,
|
|
23
|
+
getLocaleRouteConfig,
|
|
24
|
+
getDefaultLocaleCode,
|
|
19
25
|
} = require("../common");
|
|
26
|
+
const {readCanopyLocalesWithMessages} = require("../locales");
|
|
20
27
|
const {resolveCanopyConfigPath} = require("../config-path");
|
|
21
28
|
const mdx = require("./mdx");
|
|
22
29
|
const {log, logLine, logResponse} = require("./log");
|
|
@@ -174,9 +181,9 @@ function normalizeSlugBase(value, fallback) {
|
|
|
174
181
|
return clampSlugLength(safeFallback, MAX_ENTRY_SLUG_LENGTH) || safeFallback;
|
|
175
182
|
}
|
|
176
183
|
|
|
177
|
-
function manifestHrefFromSlug(slug) {
|
|
184
|
+
function manifestHrefFromSlug(slug, routePath) {
|
|
178
185
|
if (!slug) return "";
|
|
179
|
-
const rel =
|
|
186
|
+
const rel = buildRouteRelativePath(routePath || getDefaultRoute("works"), `${String(slug).trim()}.html`);
|
|
180
187
|
return rootRelativeHref(rel);
|
|
181
188
|
}
|
|
182
189
|
|
|
@@ -203,10 +210,10 @@ function extractHomepageId(resource) {
|
|
|
203
210
|
return "";
|
|
204
211
|
}
|
|
205
212
|
|
|
206
|
-
function resolveManifestCanonical(manifest, slug) {
|
|
213
|
+
function resolveManifestCanonical(manifest, slug, routePath) {
|
|
207
214
|
const homepageId = extractHomepageId(manifest);
|
|
208
215
|
if (homepageId) return homepageId;
|
|
209
|
-
return manifestHrefFromSlug(slug);
|
|
216
|
+
return manifestHrefFromSlug(slug, routePath);
|
|
210
217
|
}
|
|
211
218
|
|
|
212
219
|
function resolveCollectionCanonical(collection) {
|
|
@@ -223,9 +230,9 @@ function assignEntryCanonical(entry, canonical) {
|
|
|
223
230
|
return value;
|
|
224
231
|
}
|
|
225
232
|
|
|
226
|
-
function applyManifestEntryCanonical(entry, manifest, slug) {
|
|
233
|
+
function applyManifestEntryCanonical(entry, manifest, slug, routePath) {
|
|
227
234
|
if (!entry || entry.type !== "Manifest") return "";
|
|
228
|
-
const canonical = resolveManifestCanonical(manifest, slug);
|
|
235
|
+
const canonical = resolveManifestCanonical(manifest, slug, routePath);
|
|
229
236
|
return assignEntryCanonical(entry, canonical);
|
|
230
237
|
}
|
|
231
238
|
|
|
@@ -1127,7 +1134,7 @@ async function loadCachedManifestById(id) {
|
|
|
1127
1134
|
slug,
|
|
1128
1135
|
parent: "",
|
|
1129
1136
|
};
|
|
1130
|
-
applyManifestEntryCanonical(entry, null, slug);
|
|
1137
|
+
applyManifestEntryCanonical(entry, null, slug, getDefaultRoute("works"));
|
|
1131
1138
|
if (existingEntryIdx >= 0) index.byId[existingEntryIdx] = entry;
|
|
1132
1139
|
else index.byId.push(entry);
|
|
1133
1140
|
await saveManifestIndex(index);
|
|
@@ -1160,6 +1167,7 @@ async function loadCachedManifestById(id) {
|
|
|
1160
1167
|
entry,
|
|
1161
1168
|
normalized,
|
|
1162
1169
|
slug,
|
|
1170
|
+
getDefaultRoute("works"),
|
|
1163
1171
|
);
|
|
1164
1172
|
if (nextCanonical !== prevCanonical) {
|
|
1165
1173
|
await saveManifestIndex(index);
|
|
@@ -1202,7 +1210,7 @@ async function saveCachedManifest(manifest, id, parentId) {
|
|
|
1202
1210
|
slug,
|
|
1203
1211
|
parent: parentId ? String(parentId) : "",
|
|
1204
1212
|
};
|
|
1205
|
-
applyManifestEntryCanonical(entry, normalizedManifest, slug);
|
|
1213
|
+
applyManifestEntryCanonical(entry, normalizedManifest, slug, getDefaultRoute("works"));
|
|
1206
1214
|
if (existingEntryIdx >= 0) index.byId[existingEntryIdx] = entry;
|
|
1207
1215
|
else index.byId.push(entry);
|
|
1208
1216
|
await saveManifestIndex(index);
|
|
@@ -1860,6 +1868,16 @@ async function buildIiifCollectionPages(CONFIG) {
|
|
|
1860
1868
|
const iiifRecords = [];
|
|
1861
1869
|
const navPlaceRecords = [];
|
|
1862
1870
|
const {size: thumbSize, unsafe: unsafeThumbs} = resolveThumbnailPreferences();
|
|
1871
|
+
let workRouteEntries = getLocaleRouteEntries("works");
|
|
1872
|
+
if (!workRouteEntries.length) {
|
|
1873
|
+
workRouteEntries = [
|
|
1874
|
+
{
|
|
1875
|
+
locale: getDefaultLocaleCode(),
|
|
1876
|
+
route: getDefaultRoute("works"),
|
|
1877
|
+
isDefault: true,
|
|
1878
|
+
},
|
|
1879
|
+
];
|
|
1880
|
+
}
|
|
1863
1881
|
|
|
1864
1882
|
// Compile the works layout component once per run
|
|
1865
1883
|
const worksLayoutPath = path.join(CONTENT_DIR, "works", "_layout.mdx");
|
|
@@ -2028,10 +2046,20 @@ async function buildIiifCollectionPages(CONFIG) {
|
|
|
2028
2046
|
if (normalizedManifestId) renderedManifestIds.add(normalizedManifestId);
|
|
2029
2047
|
logDebug(`Resolved slug ${slug} for ${manifestLabel}`);
|
|
2030
2048
|
const references = referenced.getReferencesForManifest(manifestId);
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2049
|
+
for (const routeEntry of workRouteEntries) {
|
|
2050
|
+
const routeBase =
|
|
2051
|
+
routeEntry && routeEntry.route
|
|
2052
|
+
? routeEntry.route
|
|
2053
|
+
: getDefaultRoute("works");
|
|
2054
|
+
const isDefaultRoute = routeEntry && routeEntry.isDefault === true;
|
|
2055
|
+
const localeFromRoute =
|
|
2056
|
+
routeEntry && routeEntry.locale
|
|
2057
|
+
? routeEntry.locale
|
|
2058
|
+
: getDefaultLocaleCode();
|
|
2059
|
+
const href = buildRouteRelativePath(routeBase, `${slug}.html`);
|
|
2060
|
+
const outPath = path.join(OUT_DIR, href);
|
|
2061
|
+
ensureDirSync(path.dirname(outPath));
|
|
2062
|
+
try {
|
|
2035
2063
|
let components = {};
|
|
2036
2064
|
try {
|
|
2037
2065
|
components = await mdx.loadUiComponents();
|
|
@@ -2062,8 +2090,9 @@ async function buildIiifCollectionPages(CONFIG) {
|
|
|
2062
2090
|
}
|
|
2063
2091
|
const normalizedHref = href.split(path.sep).join("/");
|
|
2064
2092
|
const pageHref = rootRelativeHref(normalizedHref);
|
|
2093
|
+
const pageLocale = localeFromRoute || resolveLocaleFromHref(pageHref);
|
|
2065
2094
|
const pageDescription = summaryForMeta || title;
|
|
2066
|
-
const canonical = resolveManifestCanonical(manifest, slug);
|
|
2095
|
+
const canonical = resolveManifestCanonical(manifest, slug, routeBase);
|
|
2067
2096
|
const pageDetails = {
|
|
2068
2097
|
title,
|
|
2069
2098
|
href: pageHref,
|
|
@@ -2074,12 +2103,14 @@ async function buildIiifCollectionPages(CONFIG) {
|
|
|
2074
2103
|
manifestId,
|
|
2075
2104
|
referencedBy: references,
|
|
2076
2105
|
canonical,
|
|
2106
|
+
locale: pageLocale,
|
|
2077
2107
|
meta: {
|
|
2078
2108
|
title,
|
|
2079
2109
|
description: pageDescription,
|
|
2080
2110
|
type: "work",
|
|
2081
2111
|
url: pageHref,
|
|
2082
2112
|
canonical,
|
|
2113
|
+
locale: pageLocale,
|
|
2083
2114
|
},
|
|
2084
2115
|
};
|
|
2085
2116
|
const ogImageForPage =
|
|
@@ -2095,11 +2126,33 @@ async function buildIiifCollectionPages(CONFIG) {
|
|
|
2095
2126
|
navigationRoots && Object.keys(navigationRoots).length
|
|
2096
2127
|
? {allRoots: navigationRoots}
|
|
2097
2128
|
: null;
|
|
2098
|
-
const primaryNav = readPrimaryNavigation();
|
|
2129
|
+
const primaryNav = readPrimaryNavigation(pageLocale);
|
|
2130
|
+
const siteMeta = readSiteMetadata ? {...readSiteMetadata()} : null;
|
|
2131
|
+
const siteLanguageToggle = (() => {
|
|
2132
|
+
try {
|
|
2133
|
+
const data = readCanopyLocalesWithMessages();
|
|
2134
|
+
if (data && Array.isArray(data.locales) && data.locales.length) {
|
|
2135
|
+
return {locales: data.locales, messages: data.messages || {}};
|
|
2136
|
+
}
|
|
2137
|
+
} catch (_) {}
|
|
2138
|
+
return null;
|
|
2139
|
+
})();
|
|
2140
|
+
const siteContext = siteMeta ? {...siteMeta} : {};
|
|
2141
|
+
if (siteLanguageToggle) {
|
|
2142
|
+
siteContext.languageToggle = siteLanguageToggle;
|
|
2143
|
+
}
|
|
2144
|
+
try {
|
|
2145
|
+
const localeRoutes = getLocaleRouteConfig(pageLocale);
|
|
2146
|
+
if (localeRoutes) siteContext.routes = localeRoutes;
|
|
2147
|
+
} catch (_) {}
|
|
2148
|
+
try {
|
|
2149
|
+
const defaultRoutes = getLocaleRouteConfig(getDefaultLocaleCode());
|
|
2150
|
+
if (defaultRoutes) siteContext.routesDefault = defaultRoutes;
|
|
2151
|
+
} catch (_) {}
|
|
2099
2152
|
const pageContextValue = {
|
|
2100
2153
|
navigation: navigationContext,
|
|
2101
2154
|
page: pageDetails,
|
|
2102
|
-
site:
|
|
2155
|
+
site: siteContext && Object.keys(siteContext).length ? siteContext : null,
|
|
2103
2156
|
primaryNavigation: Array.isArray(primaryNav) ? primaryNav : [],
|
|
2104
2157
|
};
|
|
2105
2158
|
if (
|
|
@@ -2329,6 +2382,7 @@ async function buildIiifCollectionPages(CONFIG) {
|
|
|
2329
2382
|
scriptHref: jsRel,
|
|
2330
2383
|
headExtra,
|
|
2331
2384
|
bodyClass,
|
|
2385
|
+
lang: pageLocale,
|
|
2332
2386
|
});
|
|
2333
2387
|
try {
|
|
2334
2388
|
html = require("../common").applyBaseToHtml(html);
|
|
@@ -2501,104 +2555,124 @@ async function buildIiifCollectionPages(CONFIG) {
|
|
|
2501
2555
|
}
|
|
2502
2556
|
}
|
|
2503
2557
|
} catch (_) {}
|
|
2504
|
-
|
|
2505
|
-
|
|
2506
|
-
|
|
2507
|
-
|
|
2508
|
-
const metadataEntries = extractMetadataEntries(manifest, {
|
|
2509
|
-
includeAll: metadataCollectAllLabels,
|
|
2510
|
-
labelsSet: metadataLabelSet,
|
|
2511
|
-
});
|
|
2512
|
-
if (metadataEntries && metadataEntries.length) {
|
|
2513
|
-
for (const entry of metadataEntries) recordMetadataIndexEntry(entry);
|
|
2514
|
-
}
|
|
2515
|
-
} catch (_) {}
|
|
2516
|
-
if (metadataOptions && metadataOptions.enabled) {
|
|
2558
|
+
if (isDefaultRoute) {
|
|
2559
|
+
let metadataValues = [];
|
|
2560
|
+
let summaryValue = "";
|
|
2561
|
+
let annotationValue = "";
|
|
2517
2562
|
try {
|
|
2518
|
-
|
|
2519
|
-
|
|
2520
|
-
|
|
2563
|
+
const metadataEntries = extractMetadataEntries(manifest, {
|
|
2564
|
+
includeAll: metadataCollectAllLabels,
|
|
2565
|
+
labelsSet: metadataLabelSet,
|
|
2566
|
+
});
|
|
2567
|
+
if (metadataEntries && metadataEntries.length) {
|
|
2568
|
+
for (const entry of metadataEntries) recordMetadataIndexEntry(entry);
|
|
2569
|
+
}
|
|
2570
|
+
} catch (_) {}
|
|
2571
|
+
if (metadataOptions && metadataOptions.enabled) {
|
|
2572
|
+
try {
|
|
2573
|
+
metadataValues = extractMetadataValues(manifest, metadataOptions);
|
|
2574
|
+
} catch (_) {
|
|
2575
|
+
metadataValues = [];
|
|
2576
|
+
}
|
|
2521
2577
|
}
|
|
2522
|
-
|
|
2523
|
-
|
|
2524
|
-
|
|
2525
|
-
|
|
2526
|
-
|
|
2527
|
-
|
|
2528
|
-
|
|
2529
|
-
|
|
2530
|
-
|
|
2578
|
+
if (summaryOptions && summaryOptions.enabled) {
|
|
2579
|
+
summaryValue = summaryRaw || "";
|
|
2580
|
+
}
|
|
2581
|
+
if (annotationsOptions && annotationsOptions.enabled) {
|
|
2582
|
+
try {
|
|
2583
|
+
annotationValue = await extractAnnotationText(
|
|
2584
|
+
manifest,
|
|
2585
|
+
annotationsOptions,
|
|
2586
|
+
);
|
|
2587
|
+
} catch (_) {
|
|
2588
|
+
annotationValue = "";
|
|
2589
|
+
}
|
|
2590
|
+
}
|
|
2591
|
+
const fallbackThumbnail =
|
|
2592
|
+
(heroMedia && heroMedia.heroThumbnail) || "";
|
|
2593
|
+
const fallbackThumbWidth =
|
|
2594
|
+
heroMedia && typeof heroMedia.heroThumbnailWidth === "number"
|
|
2595
|
+
? heroMedia.heroThumbnailWidth
|
|
2596
|
+
: undefined;
|
|
2597
|
+
const fallbackThumbHeight =
|
|
2598
|
+
heroMedia && typeof heroMedia.heroThumbnailHeight === "number"
|
|
2599
|
+
? heroMedia.heroThumbnailHeight
|
|
2600
|
+
: undefined;
|
|
2601
|
+
const navThumbnail = thumbUrl || fallbackThumbnail;
|
|
2602
|
+
const navThumbWidth =
|
|
2603
|
+
typeof thumbWidth === "number" ? thumbWidth : fallbackThumbWidth;
|
|
2604
|
+
const navThumbHeight =
|
|
2605
|
+
typeof thumbHeight === "number" ? thumbHeight : fallbackThumbHeight;
|
|
2606
|
+
const navRecord = navPlace.buildManifestNavPlaceRecord({
|
|
2607
|
+
manifest,
|
|
2608
|
+
slug,
|
|
2609
|
+
href: pageHref,
|
|
2610
|
+
title,
|
|
2611
|
+
summary: summaryRaw,
|
|
2612
|
+
thumbnail: navThumbnail,
|
|
2613
|
+
thumbnailWidth: navThumbWidth,
|
|
2614
|
+
thumbnailHeight: navThumbHeight,
|
|
2615
|
+
});
|
|
2616
|
+
if (navRecord) navPlaceRecords.push(navRecord);
|
|
2617
|
+
|
|
2618
|
+
const recordThumbnail = navThumbnail;
|
|
2619
|
+
const recordThumbWidth = navThumbWidth;
|
|
2620
|
+
const recordThumbHeight = navThumbHeight;
|
|
2621
|
+
const localeHrefMap = {};
|
|
2622
|
+
for (const entry of workRouteEntries) {
|
|
2623
|
+
const targetBase =
|
|
2624
|
+
entry && entry.route ? entry.route : getDefaultRoute("works");
|
|
2625
|
+
const targetLocale =
|
|
2626
|
+
entry && entry.locale ? entry.locale : getDefaultLocaleCode();
|
|
2627
|
+
const relHref = buildRouteRelativePath(
|
|
2628
|
+
targetBase,
|
|
2629
|
+
`${slug}.html`,
|
|
2630
|
+
);
|
|
2631
|
+
localeHrefMap[targetLocale] = rootRelativeHref(
|
|
2632
|
+
relHref.split(path.sep).join("/"),
|
|
2531
2633
|
);
|
|
2532
|
-
} catch (_) {
|
|
2533
|
-
annotationValue = "";
|
|
2534
2634
|
}
|
|
2635
|
+
iiifRecords.push({
|
|
2636
|
+
id: String(manifest.id || id),
|
|
2637
|
+
title,
|
|
2638
|
+
href: pageHref,
|
|
2639
|
+
type: "work",
|
|
2640
|
+
slug,
|
|
2641
|
+
locale: pageLocale,
|
|
2642
|
+
thumbnail: recordThumbnail || undefined,
|
|
2643
|
+
thumbnailWidth:
|
|
2644
|
+
typeof recordThumbWidth === "number"
|
|
2645
|
+
? recordThumbWidth
|
|
2646
|
+
: undefined,
|
|
2647
|
+
thumbnailHeight:
|
|
2648
|
+
typeof recordThumbHeight === "number"
|
|
2649
|
+
? recordThumbHeight
|
|
2650
|
+
: undefined,
|
|
2651
|
+
searchMetadataValues:
|
|
2652
|
+
metadataValues && metadataValues.length
|
|
2653
|
+
? metadataValues
|
|
2654
|
+
: undefined,
|
|
2655
|
+
searchSummary:
|
|
2656
|
+
summaryValue && summaryValue.length ? summaryValue : undefined,
|
|
2657
|
+
searchAnnotation:
|
|
2658
|
+
annotationValue && annotationValue.length
|
|
2659
|
+
? annotationValue
|
|
2660
|
+
: undefined,
|
|
2661
|
+
routes: localeHrefMap,
|
|
2662
|
+
});
|
|
2663
|
+
logDebug(
|
|
2664
|
+
`Search record queued for ${manifestLabel}: ${pageHref} (metadata values ${
|
|
2665
|
+
metadataValues ? metadataValues.length : 0
|
|
2666
|
+
})`,
|
|
2667
|
+
);
|
|
2535
2668
|
}
|
|
2536
|
-
const fallbackThumbnail =
|
|
2537
|
-
(heroMedia && heroMedia.heroThumbnail) || "";
|
|
2538
|
-
const fallbackThumbWidth =
|
|
2539
|
-
heroMedia && typeof heroMedia.heroThumbnailWidth === "number"
|
|
2540
|
-
? heroMedia.heroThumbnailWidth
|
|
2541
|
-
: undefined;
|
|
2542
|
-
const fallbackThumbHeight =
|
|
2543
|
-
heroMedia && typeof heroMedia.heroThumbnailHeight === "number"
|
|
2544
|
-
? heroMedia.heroThumbnailHeight
|
|
2545
|
-
: undefined;
|
|
2546
|
-
const navThumbnail = thumbUrl || fallbackThumbnail;
|
|
2547
|
-
const navThumbWidth =
|
|
2548
|
-
typeof thumbWidth === "number" ? thumbWidth : fallbackThumbWidth;
|
|
2549
|
-
const navThumbHeight =
|
|
2550
|
-
typeof thumbHeight === "number" ? thumbHeight : fallbackThumbHeight;
|
|
2551
|
-
const navRecord = navPlace.buildManifestNavPlaceRecord({
|
|
2552
|
-
manifest,
|
|
2553
|
-
slug,
|
|
2554
|
-
href: pageHref,
|
|
2555
|
-
title,
|
|
2556
|
-
summary: summaryRaw,
|
|
2557
|
-
thumbnail: navThumbnail,
|
|
2558
|
-
thumbnailWidth: navThumbWidth,
|
|
2559
|
-
thumbnailHeight: navThumbHeight,
|
|
2560
|
-
});
|
|
2561
|
-
if (navRecord) navPlaceRecords.push(navRecord);
|
|
2562
|
-
|
|
2563
|
-
const recordThumbnail = navThumbnail;
|
|
2564
|
-
const recordThumbWidth = navThumbWidth;
|
|
2565
|
-
const recordThumbHeight = navThumbHeight;
|
|
2566
|
-
iiifRecords.push({
|
|
2567
|
-
id: String(manifest.id || id),
|
|
2568
|
-
title,
|
|
2569
|
-
href: pageHref,
|
|
2570
|
-
type: "work",
|
|
2571
|
-
thumbnail: recordThumbnail || undefined,
|
|
2572
|
-
thumbnailWidth:
|
|
2573
|
-
typeof recordThumbWidth === "number"
|
|
2574
|
-
? recordThumbWidth
|
|
2575
|
-
: undefined,
|
|
2576
|
-
thumbnailHeight:
|
|
2577
|
-
typeof recordThumbHeight === "number"
|
|
2578
|
-
? recordThumbHeight
|
|
2579
|
-
: undefined,
|
|
2580
|
-
searchMetadataValues:
|
|
2581
|
-
metadataValues && metadataValues.length
|
|
2582
|
-
? metadataValues
|
|
2583
|
-
: undefined,
|
|
2584
|
-
searchSummary:
|
|
2585
|
-
summaryValue && summaryValue.length ? summaryValue : undefined,
|
|
2586
|
-
searchAnnotation:
|
|
2587
|
-
annotationValue && annotationValue.length
|
|
2588
|
-
? annotationValue
|
|
2589
|
-
: undefined,
|
|
2590
|
-
});
|
|
2591
|
-
logDebug(
|
|
2592
|
-
`Search record queued for ${manifestLabel}: ${pageHref} (metadata values ${
|
|
2593
|
-
metadataValues ? metadataValues.length : 0
|
|
2594
|
-
})`,
|
|
2595
|
-
);
|
|
2596
2669
|
} catch (e) {
|
|
2597
2670
|
lns.push([
|
|
2598
2671
|
`IIIF: failed to render for ${id || "<unknown>"} — ${e.message}`,
|
|
2599
2672
|
"red",
|
|
2600
2673
|
]);
|
|
2601
2674
|
}
|
|
2675
|
+
}
|
|
2602
2676
|
logs[idx] = lns;
|
|
2603
2677
|
tryFlush();
|
|
2604
2678
|
}
|
package/lib/build/mdx.js
CHANGED
|
@@ -13,12 +13,31 @@ const {
|
|
|
13
13
|
withBase,
|
|
14
14
|
readSiteMetadata,
|
|
15
15
|
readPrimaryNavigation,
|
|
16
|
+
getLocaleRouteConfig,
|
|
17
|
+
getDefaultLocaleCode,
|
|
16
18
|
} = require("../common");
|
|
17
|
-
|
|
18
19
|
const globalRoot = typeof globalThis !== "undefined" ? globalThis : global;
|
|
19
20
|
if (globalRoot && typeof globalRoot.__canopyRequire !== "function") {
|
|
20
21
|
globalRoot.__canopyRequire = typeof require === "function" ? require : null;
|
|
21
22
|
}
|
|
23
|
+
const {readCanopyLocalesWithMessages} = require("../locales");
|
|
24
|
+
|
|
25
|
+
function getSiteLanguageToggle() {
|
|
26
|
+
try {
|
|
27
|
+
const data = readCanopyLocalesWithMessages();
|
|
28
|
+
if (
|
|
29
|
+
data &&
|
|
30
|
+
Array.isArray(data.locales) &&
|
|
31
|
+
data.locales.length
|
|
32
|
+
) {
|
|
33
|
+
return {
|
|
34
|
+
locales: data.locales,
|
|
35
|
+
messages: data.messages || {},
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
} catch (_) {}
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
22
41
|
let remarkGfm = null;
|
|
23
42
|
try {
|
|
24
43
|
const mod = require("remark-gfm");
|
|
@@ -1069,12 +1088,29 @@ async function compileMdxFile(filePath, outPath, Layout, extraProps = {}) {
|
|
|
1069
1088
|
const withApp = React.createElement(app.App, null, withLayout);
|
|
1070
1089
|
const PageContext = getPageContext();
|
|
1071
1090
|
const siteMeta = readSiteMetadata();
|
|
1072
|
-
const
|
|
1091
|
+
const pageLocale =
|
|
1092
|
+
extraProps && extraProps.page && typeof extraProps.page.locale === "string"
|
|
1093
|
+
? extraProps.page.locale
|
|
1094
|
+
: undefined;
|
|
1095
|
+
const primaryNav = readPrimaryNavigation(pageLocale);
|
|
1096
|
+
const siteLanguageToggle = getSiteLanguageToggle();
|
|
1097
|
+
const siteContext = siteMeta ? {...siteMeta} : {};
|
|
1098
|
+
if (siteLanguageToggle) {
|
|
1099
|
+
siteContext.languageToggle = siteLanguageToggle;
|
|
1100
|
+
}
|
|
1101
|
+
try {
|
|
1102
|
+
const localeRoutes = getLocaleRouteConfig(pageLocale);
|
|
1103
|
+
if (localeRoutes) siteContext.routes = localeRoutes;
|
|
1104
|
+
} catch (_) {}
|
|
1105
|
+
try {
|
|
1106
|
+
const defaultRoutes = getLocaleRouteConfig(getDefaultLocaleCode());
|
|
1107
|
+
if (defaultRoutes) siteContext.routesDefault = defaultRoutes;
|
|
1108
|
+
} catch (_) {}
|
|
1073
1109
|
const contextValue = {
|
|
1074
1110
|
navigation:
|
|
1075
1111
|
extraProps && extraProps.navigation ? extraProps.navigation : null,
|
|
1076
1112
|
page: extraProps && extraProps.page ? extraProps.page : null,
|
|
1077
|
-
site:
|
|
1113
|
+
site: siteContext && Object.keys(siteContext).length ? siteContext : null,
|
|
1078
1114
|
primaryNavigation: Array.isArray(primaryNav) ? primaryNav : [],
|
|
1079
1115
|
};
|
|
1080
1116
|
const withContext = PageContext
|
package/lib/build/pages.js
CHANGED
|
@@ -8,6 +8,9 @@ const {
|
|
|
8
8
|
htmlShell,
|
|
9
9
|
canopyBodyClassForType,
|
|
10
10
|
rootRelativeHref,
|
|
11
|
+
resolveLocaleFromContentPath,
|
|
12
|
+
canonicalizeLocaleCode,
|
|
13
|
+
getDefaultLocaleCode,
|
|
11
14
|
} = require('../common');
|
|
12
15
|
const { log } = require('./log');
|
|
13
16
|
const mdx = require('./mdx');
|
|
@@ -109,12 +112,20 @@ async function renderContentMdxToHtml(filePath, outPath, extraProps = {}, source
|
|
|
109
112
|
? mdx.parseFrontmatter(source)
|
|
110
113
|
: { data: null, content: source };
|
|
111
114
|
const frontmatterData = frontmatter && isPlainObject(frontmatter.data) ? frontmatter.data : null;
|
|
115
|
+
const frontmatterLocaleRaw = readFrontmatterString(frontmatterData, 'locale');
|
|
116
|
+
const frontmatterLocale = canonicalizeLocaleCode(frontmatterLocaleRaw);
|
|
117
|
+
const pageLocale =
|
|
118
|
+
frontmatterLocale ||
|
|
119
|
+
resolveLocaleFromContentPath(relContentPath) ||
|
|
120
|
+
getDefaultLocaleCode();
|
|
112
121
|
const referencedManifestIdsRaw = frontmatterData ? frontmatterData.referencedManifests : null;
|
|
113
122
|
const referencedManifestIds = referenced.normalizeReferencedManifestList(
|
|
114
123
|
referencedManifestIdsRaw
|
|
115
124
|
);
|
|
116
125
|
const referencedItems = referencedManifestIds.length
|
|
117
|
-
? referenced.buildReferencedItems(referencedManifestIds
|
|
126
|
+
? referenced.buildReferencedItems(referencedManifestIds, {
|
|
127
|
+
locale: pageLocale,
|
|
128
|
+
})
|
|
118
129
|
: [];
|
|
119
130
|
let layoutMeta = null;
|
|
120
131
|
try {
|
|
@@ -141,6 +152,7 @@ async function renderContentMdxToHtml(filePath, outPath, extraProps = {}, source
|
|
|
141
152
|
const frontmatterMeta = frontmatterData && isPlainObject(frontmatterData.meta) ? frontmatterData.meta : null;
|
|
142
153
|
const headings = mdx.extractHeadings(source);
|
|
143
154
|
const basePage = pageInfo ? { ...pageInfo } : {};
|
|
155
|
+
if (pageLocale) basePage.locale = pageLocale;
|
|
144
156
|
if (title) basePage.title = title;
|
|
145
157
|
if (resolvedType) basePage.type = resolvedType;
|
|
146
158
|
if (resolvedDescription) basePage.description = resolvedDescription;
|
|
@@ -171,6 +183,7 @@ async function renderContentMdxToHtml(filePath, outPath, extraProps = {}, source
|
|
|
171
183
|
pageMeta.image = resolvedImage;
|
|
172
184
|
if (!pageMeta.ogImage) pageMeta.ogImage = resolvedImage;
|
|
173
185
|
}
|
|
186
|
+
if (pageLocale) pageMeta.locale = pageLocale;
|
|
174
187
|
if (frontmatterMeta) Object.assign(pageMeta, frontmatterMeta);
|
|
175
188
|
if (Object.keys(pageMeta).length) basePage.meta = pageMeta;
|
|
176
189
|
if (referencedManifestIds.length) {
|
|
@@ -357,6 +370,7 @@ async function renderContentMdxToHtml(filePath, outPath, extraProps = {}, source
|
|
|
357
370
|
scriptHref: jsRel,
|
|
358
371
|
headExtra,
|
|
359
372
|
bodyClass,
|
|
373
|
+
lang: pageLocale,
|
|
360
374
|
});
|
|
361
375
|
const { applyBaseToHtml } = require('../common');
|
|
362
376
|
return applyBaseToHtml(html);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
|
|
2
2
|
const { logLine } = require('./log');
|
|
3
|
-
const { rootRelativeHref } = require('../common');
|
|
3
|
+
const { rootRelativeHref, buildRouteRelativePath, getDefaultRoute } = require('../common');
|
|
4
4
|
|
|
5
5
|
function pagesToRecords(pageRecords) {
|
|
6
6
|
const list = Array.isArray(pageRecords) ? pageRecords : [];
|
|
@@ -29,7 +29,8 @@ function maybeMockRecords() {
|
|
|
29
29
|
const svg = encodeURIComponent('<svg xmlns="http://www.w3.org/2000/svg" width="400" height="300"><rect width="400" height="300" fill="#dbeafe"/><text x="50%" y="50%" dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="24" fill="#1d4ed8">Mock</text></svg>');
|
|
30
30
|
const thumb = `data:image/svg+xml;charset=utf-8,${svg}`;
|
|
31
31
|
for (let i = 1; i <= 120; i++) {
|
|
32
|
-
|
|
32
|
+
const rel = buildRouteRelativePath(getDefaultRoute('works'), `mock-${i}.html`);
|
|
33
|
+
mock.push({ title: `Mock Work #${i}`, href: rootRelativeHref(rel), type: 'work', thumbnail: thumb });
|
|
33
34
|
}
|
|
34
35
|
mock.push({ title: 'Mock Doc A', href: rootRelativeHref('getting-started/index.html'), type: 'docs' });
|
|
35
36
|
mock.push({ title: 'Mock Doc B', href: rootRelativeHref('getting-started/example.html'), type: 'docs' });
|
|
@@ -1,4 +1,11 @@
|
|
|
1
|
-
const {
|
|
1
|
+
const {
|
|
2
|
+
fs,
|
|
3
|
+
path,
|
|
4
|
+
OUT_DIR,
|
|
5
|
+
getLocaleRouteEntries,
|
|
6
|
+
getDefaultRoute,
|
|
7
|
+
getDefaultLocaleCode,
|
|
8
|
+
} = require('../common');
|
|
2
9
|
const search = require('../search/search');
|
|
3
10
|
const runtimes = require('./runtimes');
|
|
4
11
|
const { generateFacets } = require('./facets');
|
|
@@ -10,7 +17,12 @@ const { logLine } = require('./log');
|
|
|
10
17
|
* and build the page so subsequent steps can update artifacts incrementally.
|
|
11
18
|
*/
|
|
12
19
|
async function ensureSearchInitialized() {
|
|
13
|
-
const
|
|
20
|
+
const entries = getLocaleRouteEntries('search');
|
|
21
|
+
const defaultEntry = entries.length
|
|
22
|
+
? entries[0]
|
|
23
|
+
: { locale: getDefaultLocaleCode(), route: getDefaultRoute('search') };
|
|
24
|
+
const rel = search.resolveSearchOutputRelative(defaultEntry.route || '');
|
|
25
|
+
const searchPath = path.join(OUT_DIR, rel);
|
|
14
26
|
const needCreatePage = !fs.existsSync(searchPath);
|
|
15
27
|
if (!needCreatePage) return;
|
|
16
28
|
try { logLine('• Preparing search (initial)...', 'blue', { bright: true }); } catch (_) {}
|
|
@@ -20,7 +32,7 @@ async function ensureSearchInitialized() {
|
|
|
20
32
|
await search.writeSearchIndex([]);
|
|
21
33
|
try { logLine(' - Writing runtime...', 'blue'); } catch (_) {}
|
|
22
34
|
await runtimes.prepareSearchRuntime(process.env.CANOPY_BUNDLE_TIMEOUT || 10000, 'initial');
|
|
23
|
-
try { logLine(' - Building search
|
|
35
|
+
try { logLine(' - Building search page...', 'blue'); } catch (_) {}
|
|
24
36
|
await search.buildSearchPage();
|
|
25
37
|
try { logLine('✓ Created search page', 'cyan'); } catch (_) {}
|
|
26
38
|
}
|
|
@@ -38,7 +50,7 @@ async function finalizeSearch(combinedRecords) {
|
|
|
38
50
|
try { logLine('• Writing search runtime (final)...', 'blue', { bright: true }); } catch (_) {}
|
|
39
51
|
await runtimes.prepareSearchRuntime(process.env.CANOPY_BUNDLE_TIMEOUT || 10000, 'final');
|
|
40
52
|
try { await search.ensureResultTemplate(); } catch (_) {}
|
|
41
|
-
try { logLine('• Updating search
|
|
53
|
+
try { logLine('• Updating search page...', 'blue'); } catch (_) {}
|
|
42
54
|
await search.buildSearchPage();
|
|
43
55
|
try { logLine('✓ Search page updated', 'cyan'); } catch (_) {}
|
|
44
56
|
|
|
@@ -58,4 +70,3 @@ async function finalizeSearch(combinedRecords) {
|
|
|
58
70
|
}
|
|
59
71
|
|
|
60
72
|
module.exports = { ensureSearchInitialized, finalizeSearch };
|
|
61
|
-
|