Skip to content

Commit 45de981

Browse files
authored
Merge pull request #562 from fronteers/aankondigingen-events-2026
2 parents 0b5cf52 + d196a4f commit 45de981

File tree

269 files changed

+3498
-528
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

269 files changed

+3498
-528
lines changed

.eleventy.js

Lines changed: 146 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,9 @@ const syntaxHighlight = require("@11ty/eleventy-plugin-syntaxhighlight");
1313

1414
module.exports = function (eleventyConfig) {
1515
const quick = Boolean(process.env.BUILD_QUICK);
16+
const isDev = process.env.ELEVENTY_ENV === "development" || process.argv.includes("--serve") || process.argv.includes("--watch");
1617
const now = new Date();
17-
18+
//
1819
/**
1920
* There is a quick build function (npm run start:quick) that only loads the
2021
* recent content (YTD and previous year), by excluding all year folders from
@@ -53,35 +54,92 @@ module.exports = function (eleventyConfig) {
5354
eleventyConfig.ignores.add("src/nl/vereniging/bestuur/notulen");
5455
}
5556

57+
/**
58+
* Read .eleventyignore file and apply ignores programmatically for faster builds.
59+
* This is more effective than relying on Eleventy's built-in ignore file reading
60+
* because it happens earlier in the process.
61+
*/
62+
if (isDev || quick) {
63+
const ignoreFile = ".eleventyignore";
64+
if (fs.existsSync(ignoreFile)) {
65+
const ignoreContent = fs.readFileSync(ignoreFile, "utf-8");
66+
const ignorePatterns = ignoreContent
67+
.split("\n")
68+
.map((line) => line.trim())
69+
.filter((line) => line && !line.startsWith("#"));
70+
71+
ignorePatterns.forEach((pattern) => {
72+
// Convert glob pattern to actual file paths
73+
const files = glob.sync(pattern, { cwd: process.cwd() });
74+
files.forEach((file) => {
75+
eleventyConfig.ignores.add(file);
76+
});
77+
});
78+
console.debug(`[ignore] Applied ${ignorePatterns.length} ignore patterns from .eleventyignore`);
79+
}
80+
}
81+
5682
// Custom date filter
5783
eleventyConfig.addFilter("localizedDate", function (dateObj, locale = "en") {
5884
return DateTime.fromJSDate(dateObj)
5985
.setLocale(locale)
6086
.toFormat("d LLLL yyyy");
6187
});
6288

89+
// Event date filter that handles tentative dates (hides day if tentative)
90+
// Usage: {{ activity.data.eventdate | eventDate: locale, activity.data.eventdateTentative }}
91+
eleventyConfig.addFilter("eventDate", function (dateObj, locale = "en", isTentative = false) {
92+
const dateTime = DateTime.fromJSDate(dateObj).setLocale(locale);
93+
94+
if (!dateTime.isValid) {
95+
return String(dateObj);
96+
}
97+
98+
// If tentative, show only month and year
99+
if (isTentative) {
100+
if (locale === "nl") {
101+
return dateTime.toFormat("LLLL yyyy"); // "april 2026"
102+
} else {
103+
return dateTime.toFormat("LLLL yyyy"); // "April 2026"
104+
}
105+
}
106+
107+
// Otherwise show full date
108+
if (locale === "nl") {
109+
return dateTime.toFormat("d LLLL yyyy"); // "1 april 2026"
110+
} else {
111+
return dateTime.toFormat("LLLL d, yyyy"); // "April 1, 2026"
112+
}
113+
});
114+
63115
/* Add id to heading elements */
64116
eleventyConfig.addPlugin(pluginAddIdToHeadings);
65117

66-
eleventyConfig.addPlugin(brokenLinksPlugin, {
67-
redirect: "warn",
68-
broken: "warn",
69-
cacheDuration: "1d",
70-
loggingLevel: 1,
71-
excludeUrls: [
72-
"https://www.openstreetmap.org*",
73-
"https://www.youtube.com*",
74-
"http://www.example.com*",
75-
"https://codepen.io*",
76-
"https://twitter.com*",
77-
"http://api.dojotoolkit.org*",
78-
"http://www.webdesignermagazine.nl/*",
79-
"http://meetup.com*",
80-
"https://github.com/fronteers/website*",
81-
],
82-
excludeInputs: [],
83-
callback: null,
84-
});
118+
// Only run broken links plugin in production builds (it's very slow)
119+
if (!isDev) {
120+
eleventyConfig.addPlugin(brokenLinksPlugin, {
121+
redirect: "warn",
122+
broken: "warn",
123+
cacheDuration: "1d",
124+
loggingLevel: 1,
125+
excludeUrls: [
126+
"https://www.openstreetmap.org*",
127+
"https://www.youtube.com*",
128+
"http://www.example.com*",
129+
"https://codepen.io*",
130+
"https://twitter.com*",
131+
"http://api.dojotoolkit.org*",
132+
"http://www.webdesignermagazine.nl/*",
133+
"http://meetup.com*",
134+
"https://github.com/fronteers/website*",
135+
"https://www.w3.org/*"
136+
],
137+
excludeInputs: [],
138+
callback: null,
139+
});
140+
} else {
141+
console.debug("[dev] Skipping broken links plugin for faster builds");
142+
}
85143

86144
eleventyConfig.addPlugin(pluginRss);
87145

@@ -220,63 +278,68 @@ module.exports = function (eleventyConfig) {
220278
return lines;
221279
});
222280

223-
eleventyConfig.on('afterBuild', async () => {
224-
async function convertSvgToJpeg(inputDir, outputDir) {
225-
const browser = await puppeteer.launch();
226-
const page = await browser.newPage();
227-
228-
// Read all files in the input directory
229-
const files = fs.readdirSync(inputDir);
230-
231-
for (const filename of files) {
232-
if (filename.endsWith(".svg")) {
233-
const inputPath = path.join(inputDir, filename);
234-
const outputPath = path.join(outputDir, filename.replace('.svg', '.jpg'));
235-
236-
// Read the SVG content
237-
const svgContent = fs.readFileSync(inputPath, 'utf8');
238-
239-
// Extract width and height from SVG (Optional: If SVG has explicit size)
240-
const matchWidth = svgContent.match(/width="([0-9]+)"/);
241-
const matchHeight = svgContent.match(/height="([0-9]+)"/);
242-
243-
const width = matchWidth ? parseInt(matchWidth[1], 10) : 1200; // Default to 1200px
244-
const height = matchHeight ? parseInt(matchHeight[1], 10) : 675; // Default to 630px
245-
246-
// Set the viewport size to match SVG size
247-
await page.setViewport({ width, height });
248-
249-
// Set SVG content inside an HTML wrapper
250-
await page.setContent(`
251-
<html>
252-
<body style="margin:0;padding:0;overflow:hidden;">
253-
<div style="width:${width}px; height:${height}px;">
254-
${svgContent}
255-
</div>
256-
</body>
257-
</html>
258-
`);
259-
260-
// Take a screenshot and save as JPEG
261-
await page.screenshot({
262-
path: outputPath,
263-
type: 'jpeg',
264-
quality: 100,
265-
clip: { x: 0, y: 0, width, height } // Ensure clipping matches viewport
266-
});
267-
268-
console.log(`Converted: ${filename} -> ${outputPath}`);
281+
// Only run SVG to JPEG conversion in production builds (puppeteer is slow)
282+
if (!isDev) {
283+
eleventyConfig.on('afterBuild', async () => {
284+
async function convertSvgToJpeg(inputDir, outputDir) {
285+
const browser = await puppeteer.launch();
286+
const page = await browser.newPage();
287+
288+
// Read all files in the input directory
289+
const files = fs.readdirSync(inputDir);
290+
291+
for (const filename of files) {
292+
if (filename.endsWith(".svg")) {
293+
const inputPath = path.join(inputDir, filename);
294+
const outputPath = path.join(outputDir, filename.replace('.svg', '.jpg'));
295+
296+
// Read the SVG content
297+
const svgContent = fs.readFileSync(inputPath, 'utf8');
298+
299+
// Extract width and height from SVG (Optional: If SVG has explicit size)
300+
const matchWidth = svgContent.match(/width="([0-9]+)"/);
301+
const matchHeight = svgContent.match(/height="([0-9]+)"/);
302+
303+
const width = matchWidth ? parseInt(matchWidth[1], 10) : 1200; // Default to 1200px
304+
const height = matchHeight ? parseInt(matchHeight[1], 10) : 675; // Default to 630px
305+
306+
// Set the viewport size to match SVG size
307+
await page.setViewport({ width, height });
308+
309+
// Set SVG content inside an HTML wrapper
310+
await page.setContent(`
311+
<html>
312+
<body style="margin:0;padding:0;overflow:hidden;">
313+
<div style="width:${width}px; height:${height}px;">
314+
${svgContent}
315+
</div>
316+
</body>
317+
</html>
318+
`);
319+
320+
// Take a screenshot and save as JPEG
321+
await page.screenshot({
322+
path: outputPath,
323+
type: 'jpeg',
324+
quality: 100,
325+
clip: { x: 0, y: 0, width, height } // Ensure clipping matches viewport
326+
});
327+
328+
console.log(`Converted: ${filename} -> ${outputPath}`);
329+
}
269330
}
270-
}
271331

272-
await browser.close();
273-
}
332+
await browser.close();
333+
}
274334

275-
// Execute conversion
276-
const inputDir = 'dist/assets/images/social-preview-images/';
277-
const outputDir = 'dist/assets/images/social-preview-images/';
278-
await convertSvgToJpeg(inputDir, outputDir);
279-
});
335+
// Execute conversion
336+
const inputDir = 'dist/assets/images/social-preview-images/';
337+
const outputDir = 'dist/assets/images/social-preview-images/';
338+
await convertSvgToJpeg(inputDir, outputDir);
339+
});
340+
} else {
341+
console.debug("[dev] Skipping SVG to JPEG conversion for faster builds");
342+
}
280343

281344
// Allows you to debug a json object in eleventy templates data | stringify
282345
eleventyConfig.addFilter("stringify", (data) => {
@@ -300,9 +363,15 @@ module.exports = function (eleventyConfig) {
300363
});
301364

302365
/* This log will appear before the first build. It is tied to the plugin that checks broken links. */
303-
console.debug(
304-
"Eleventy will now generate RSS feeds and then look for broken links. This may take a while. When its done, you should see logs appear."
305-
);
366+
if (!isDev) {
367+
console.debug(
368+
"Eleventy will now generate RSS feeds and then look for broken links. This may take a while. When its done, you should see logs appear."
369+
);
370+
} else {
371+
console.debug(
372+
"[dev] Running in development mode - broken links checking and SVG conversion disabled for faster builds"
373+
);
374+
}
306375

307376
/* All templates in the content directory are parsed and copied to the dist directory */
308377
return {

src/_assets/css/common/colors.css

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,14 @@
22
--purple: #646ee0;
33
--purple-wcag-darker: #192280;
44
--yellow: #ffce2e;
5+
--yellow-light: #fae190;
56
--lilac: #b7b7fd;
67
--lilac-light: #e5e5ff;
78
--red: #fe796a;
9+
--red-light: #ffaba1;
10+
--green: #5dd9c1;
11+
--green-light: #b3f1e5;
12+
--blue: #75bbfd;
13+
--blue-light: #c2e1ff;
814
--page-background: #f2f2f2;
915
}

src/_assets/css/common/layout.css

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,10 @@ main section > .h {
7777
background-color: white;
7878
}
7979

80+
.page-content--activity {
81+
padding: 0;
82+
}
83+
8084
.page-content:has(> .visually-hidden:only-child) {
8185
background-color: transparent;
8286
}
@@ -151,7 +155,7 @@ main section > .h {
151155

152156
.list-item--job,
153157
.list-item--blog {
154-
margin-block: var(--spacing-double);
158+
margin-block: var(--spacing-half);
155159
}
156160

157161
@media all and (min-width: 46.875em) {

src/_assets/css/common/typography.css

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ a:focus {
5959
color: white;
6060
background-color: var(--purple-wcag-darker);
6161
text-decoration: none;
62+
63+
box-shadow: 0 0 0 7px var(--purple-wcag-darker);
6264
}
6365

6466
.tag-link {
@@ -77,11 +79,13 @@ a:focus {
7779
}
7880

7981
.tag-link--large .tag {
80-
font-size: var(--font-size-14);
82+
font-size: var(--font-size-16);
8183
}
8284

83-
.tag-link--active .tag {
84-
background-color: black;
85+
.tag-link--active .tag,
86+
.tag-link[aria-current="page"] .tag {
87+
background-color: var(--purple-wcag-darker);
88+
color: white;
8589
}
8690

8791
.tag {

src/_assets/css/elements/category-list.css

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@
55
**/
66

77
.categories {
8-
margin-block-end: 3em;
98
text-align: center;
9+
max-width: var(--inner-width);
10+
padding: var(--spacing);
11+
margin-inline: auto;
1012
}
1113

1214
.category-list {

src/_assets/css/style.css

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
@import "../_includes/partials/page-header/navigation-triggers.css";
5050
@import "../_includes/partials/page-header/translate.css";
5151
@import "../_includes/partials/activity.css";
52+
@import "../_includes/partials/activity-calendar-item.css";
5253
@import "../_includes/partials/blogpost.css";
5354
@import "../_includes/partials/job.css";
5455
@import "../_includes/partials/member.css";

0 commit comments

Comments
 (0)