Project Gallery System Refactor - Dynamic Content Loading and Slug Matching
Summary
Refactored the project gallery system to use configuration-driven content loading from Astro content collections instead of hardcoded imports, implemented consistent slug matching using established slugify utilities, and resolved content loading issues for specific project paths.
Why Care
This refactor eliminates hardcoded content dependencies, establishes a maintainable configuration-driven architecture, and ensures consistent slug matching across the entire project gallery system. The changes make the system more scalable and easier to maintain while fixing critical content loading bugs that were preventing users from accessing specific project documentation.
Implementation
Changes Made
Core Architecture Refactor
- Replaced hardcoded content imports in
site/src/pages/projects/gallery/[...slug].astrowith dynamic collection-based loading - Implemented configuration-driven content paths using
site/src/config/project-gallery.jsonas the single source of truth - Simplified
loadContentFromSlug()function to useprocessEntries()andgetReferenceSlug()from established slugify utilities - Removed manual collection ID generation that was duplicating logic already present in
processEntries() - Deprecated
ProjectGallery.sveltecomponent - No longer used in the gallery system but preserved for potential future overlay functionality
File Structure Changes
text
site/src/pages/projects/gallery/[...slug].astro
├── Removed hardcoded markdown imports (mdWorkflow, mdRecordCollector, etc.)
├── Replaced manual collection ID logic with processEntries() + getReferenceSlug()
├── Simplified debug logging to essential information only
└── Streamlined content loading pipeline
site/src/config/project-gallery.json
├── Fixed contentPath for API-Connector-Service step
├── Corrected filename from "API-Connector-Service.md" to "apiConnectorService.md"
└── Ensured all contentPath values match actual filesystem filenames
site/src/utils/projectGalleryUtils.ts
├── Cleaned up debug logging in findProjectBySlug()
├── Removed excessive console output
└── Maintained core functionality while reducing noise
site/src/components/projects/ProjectGallery.svelte
├── Component deprecated and no longer imported/used
├── Preserved in codebase for potential future overlay functionality
└── All gallery functionality moved to direct Astro page rendering Debug Logging Optimization
- Reduced debug output from verbose multi-line logs to essential information only
- Consolidated log prefixes from
[GALLERY CONTENT LOAD],[FIND PROJECT BY SLUG], etc. to simple[GALLERY] - Removed redundant logging in template rendering sections
- Maintained critical debugging information for content loading failures
Content Path Corrections
- Fixed API-Connector-Service contentPath in project-gallery.json to match actual filename
- Identified filename mismatch between config (
API-Connector-Service.md) and filesystem (apiConnectorService.md) - Ensured consistent naming across all project demo steps
Technical Details
Slug Matching Implementation
typescript
// Before: Manual collection ID generation
const contentPathWithoutExt = step.contentPath.replace(/\.(md|mdx)$/i, '');
const collectionId = contentPathWithoutExt.toLowerCase();
// After: Using established slugify utilities
const processedEntries = processEntries(projectsCollection);
const referenceSlug = getReferenceSlug(step.contentPath);
const entry = processedEntries.find(entry => entry.slug === referenceSlug); Collection Processing Pipeline
typescript
// Simplified content loading using processEntries
async function loadContentFromSlug(slugPath: string) {
const projectInfo = findProjectBySlug(slugPath);
if (!projectInfo) return { mdastNode: null, contentData: null };
const { step } = projectInfo;
if (step.contentPath) {
const projectsCollection = await getCollection('projects');
const processedEntries = processEntries(projectsCollection);
const referenceSlug = getReferenceSlug(step.contentPath);
const entry = processedEntries.find(entry => entry.slug === referenceSlug);
if (entry) {
return await processMarkdown(entry.body, entry.id, entry.data.title || step.title);
}
}
return { mdastNode: null, contentData: null };
} Debug Logging Structure
typescript
// Essential logging only
console.log(`[GALLERY] Looking for:`, referenceSlug);
console.log(`[GALLERY] Found entry:`, entry.id);
console.log(`[GALLERY] No entry found for:`, referenceSlug);
console.log(`[GALLERY] Available slugs:`, processedEntries.map(e => e.slug).slice(0, 5)); Integration Points
Dependencies
@utils/slugify: Added import forprocessEntriesfunction@utils/projectGalleryUtils: Maintained existing imports for core functionality- Astro content collections: Leveraged
getCollection('projects')for dynamic content loading
Configuration Files
project-gallery.json: Central configuration for all project metadata and content paths- Content collection schema: Relies on existing projects collection structure
- Slug generation: Uses established
getReferenceSlug()utility for consistency
Migration Impact
- No breaking changes to existing functionality
- Backward compatible with current project gallery URLs
- Improved maintainability through configuration-driven approach
Documentation
Related Files
site/src/pages/projects/gallery/[...slug].astro- Main dynamic routing implementationsite/src/config/project-gallery.json- Project configuration and content pathssite/src/utils/projectGalleryUtils.ts- Gallery utility functionssite/src/utils/slugify.ts- Slug generation utilitiessite/src/components/projects/ProjectGallery.svelte- Deprecated overlay component (preserved for future use)
Usage Examples
typescript
// Content loading now works automatically for all configured project steps
// No need to manually import markdown files or maintain content maps
const content = await loadContentFromSlug('augment-it/specs/shared-services/apiconnectorservice'); Debug Information
When content loading fails, the system now provides clear information:
- Available slugs from the collection
- Reference slug being searched for
- Project and step information found
Testing Results
Fixed Issues
- ✅ API-Connector-Service content loading - Now works correctly with corrected filename
- ✅ Consistent slug matching - All project steps use same slug generation logic
- ✅ Reduced debug noise - Essential logging only for troubleshooting
- ✅ Configuration-driven architecture - No more hardcoded content dependencies
Verified Functionality
- ✅ Project finding -
findProjectBySlug()correctly identifies projects and steps - ✅ Content loading -
loadContentFromSlug()successfully loads content from collections - ✅ Slug consistency - All slugs generated using established utilities
- ✅ Error handling - Clear error messages when content is not found
Performance Impact
- Improved maintainability - Configuration changes only require JSON updates
- Reduced bundle size - No more hardcoded markdown imports
- Better debugging - Essential logs only, easier to troubleshoot issues
- Simplified architecture - Removed complex overlay system in favor of direct page rendering