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].astro with dynamic collection-based loading
  • Implemented configuration-driven content paths using site/src/config/project-gallery.json as the single source of truth
  • Simplified loadContentFromSlug() function to use processEntries() and getReferenceSlug() from established slugify utilities
  • Removed manual collection ID generation that was duplicating logic already present in processEntries()
  • Deprecated ProjectGallery.svelte component - 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 for processEntries function
  • @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

  • site/src/pages/projects/gallery/[...slug].astro - Main dynamic routing implementation
  • site/src/config/project-gallery.json - Project configuration and content paths
  • site/src/utils/projectGalleryUtils.ts - Gallery utility functions
  • site/src/utils/slugify.ts - Slug generation utilities
  • site/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