Fixed Build Errors in Digital Garden
Today I fixed several critical build errors in the digital garden:
1. Permalink Conflicts
The main issue was that multiple files were trying to write to the same output path (dist/file/index.html
). This was happening because several notes had permalink: /file/
in their frontmatter, even though they were marked as not published (dg-publish: false
):
rangerschool/25405001531RS.md
25405212211linux.md
25405213405CY.md
25405215534CY.md
25405222022CY.md
rangerschool/25404212849RS.md
rangerschool/25404225038RS.md
This suggests that unpublished notes were still being processed during the build, which shouldn't happen. The fix addresses both the permalink conflict and ensures proper handling of unpublished notes.
The Fix
Modified notes.11tydata.js
to implement a smarter permalink generation system:
-
Files in subdirectories keep their structure:
if (filePath.includes('/rangerschool/')) { return `/rangerschool/${fileName}/`; }
-
Files are categorized by their suffix:
CY
->/cybersecurity/
RS
->/rangerschool/
AI
->/ai/
linux
->/linux/
-
Frontmatter permalinks are only used if they:
- Are not
/file/
(which was causing conflicts) - End with a slash (for consistency)
- Are not
-
All other files default to
/notes/filename/
2. Async Template Issues
Fixed an error with Eleventy's template processing:
Unfortunately you're using code that monkey patched some Eleventy internals and it isn't async-friendly. Change your code to use the async `read()` method on the template instead!
The Fix
- Made graph generation properly async in
graph.js
- Added proper null checks for data objects
- Improved error handling throughout the permalink generation
3. Code Organization
The permalink generation code is now more robust:
permalink: (data) => {
// Handle undefined data
if (!data || !data.page) {
console.warn('Data or page object is undefined');
return '/notes/undefined/';
}
// Handle garden entry
if (data.tags && data.tags.indexOf("gardenEntry") != -1) {
return "/";
}
// Get file info
const filePath = data.page.filePathStem || data.page.inputPath || '';
const fileName = path.basename(filePath).replace(/\.md$/, '');
// Category-based routing
if (filePath.includes('/rangerschool/')) return `/rangerschool/${fileName}/`;
if (fileName.endsWith('CY')) return `/cybersecurity/${fileName}/`;
if (fileName.endsWith('RS')) return `/rangerschool/${fileName}/`;
if (fileName.endsWith('AI')) return `/ai/${fileName}/`;
if (fileName.match(/linux$/i)) return `/linux/${fileName}/`;
// Valid frontmatter permalinks
if (data.permalink &&
data.permalink !== '/file/' &&
data.permalink.endsWith('/')) {
return data.permalink;
}
// Default case
return `/notes/${fileName}/`;
}
4. Unpublished Notes Fix
Fixed the issue with unpublished notes being processed during the build. Modified collections.js
to properly filter out notes with dg-publish: false
:
function sortNotes(collection) {
return collection.getFilteredByTag("note")
// Filter out unpublished notes
.filter(note => {
// Check if note should be published
const shouldPublish = note.data['dg-publish'] === true;
if (!shouldPublish) {
console.log(`Skipping unpublished note: ${note.filePathStem}`);
}
return shouldPublish;
})
.sort((a, b) => {
// Sort daily notes by date
// ... rest of sorting logic ...
});
}
This ensures that:
- Only notes with
dg-publish: true
are included in the build - Unpublished notes are logged for debugging
- The permalink conflicts are prevented at the source
Results
- No more duplicate permalink errors
- Proper async handling in templates
- More organized URL structure based on file categories
- Better error handling and logging
- Proper handling of unpublished notes
- Clear logging of skipped unpublished notes