-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy patheleventy.ts
128 lines (117 loc) · 3.62 KB
/
eleventy.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
import { z } from "zod";
const MenuSchema = z
.object({
data: z.object({ title: z.string() }),
url: z.string(),
})
.transform((entry) => ({
title: entry.data.title,
url: entry.url,
}))
.array();
export const ViewSchema = z
.object({
collections: z.object({ menu: MenuSchema }).default({ menu: [] }),
page: z.object({ url: z.string() }),
content: z.string().nonempty(),
title: z.string().nonempty(),
})
.transform((data) => ({
content: data.content,
currentUrl: data.page.url,
links: data.collections.menu,
title: data.title,
}));
export type ViewProps = z.infer<typeof ViewSchema>;
export type Links = z.infer<typeof MenuSchema>;
const absoluteUrl = (base: string, url: string): string | URL => {
if (base) {
try {
return new URL(url, base).href;
} catch (err) {
console.error(err);
return url;
}
} else {
return url;
}
};
export const headDefaultProps = {
baseUrl: "",
title: "Breathe Easy Sheffield",
description:
"An eclectic series of Covid safer social & cultural events, designed with enhanced safety measures in place to reduce transmission risk. Launching autumn 2024.",
socialImage: "/static/img/ogimage-default.png",
socialImageAlt: "Breath Easy's logo",
};
export const HeadSchema = z
.object({
baseUrl: z.string().default(headDefaultProps.baseUrl),
description: z.string().default(headDefaultProps.description),
socialImage: z.string().default(headDefaultProps.socialImage),
socialImageAlt: z.string().default(headDefaultProps.socialImageAlt),
title: z.string(),
page: z.object({ url: z.string() }),
})
.transform((props) => {
return {
description: props.description,
socialImage:
// if no alt description for image is provided fallback to default
props.socialImageAlt === headDefaultProps.socialImageAlt
? absoluteUrl(props.baseUrl, headDefaultProps.socialImage)
: absoluteUrl(props.baseUrl, props.socialImage),
socialImageAlt:
// prevent alt description being overridden when custom social image not in use
props.socialImage === headDefaultProps.socialImage
? headDefaultProps.socialImageAlt
: props.socialImageAlt,
title:
props.page.url === "/"
? props.title
: `${headDefaultProps.title} | ${props.title}`,
url: absoluteUrl(props.baseUrl, props.page.url),
};
});
export type HeadProps = z.infer<typeof HeadSchema>;
/**
* These are really just notes to for myself to keep track of the shape of data incomming to an 11ty page.
*
* We rely on the zod parsers to ensure the data we want is there at build time and produce reliable types.
*/
type CollectionItem = {
content?: any[];
data?: any[];
date?: string;
filePathStem?: string;
fileSlug?: string;
groupNumber?: number;
inputPath?: string;
outputPath?: string;
page?: any[];
rawInput?: string;
template?: any;
templateContent?: any[];
url?: string;
};
type Page = {
date?: Date;
filePathStem?: string;
fileSlug?: string;
inputPath?: string;
outputFileExtension?: string;
outputPath?: string;
rawInput?: string;
templateSyntax?: string;
url?: string;
};
export type ViewInput = {
baseUrl?: string;
content?: string;
description?: string; // " for opengraph metadata"
page?: Page;
socialImage?: string; // " for opengraph metadata (external link or path to file)"
socialImageAlt?: string; // " alt text describing social preview image, if you do not include this then it will fallback to the default image / alt"
title?: string;
collections?: { [k: string]: CollectionItem[] };
};