Add Portfolio Gallery Directive Support to AstroMarkdown

Summary

Added comprehensive directive support for all gallery types in AstroMarkdown.astro, including tooling galleries, image galleries, and portfolio galleries. This enables markdown content to embed various gallery types using the modern directive architecture (:::) while maintaining backward compatibility with the deprecated YAML code block syntax (```).

Why Care

This enhancement provides content creators with a consistent, reusable way to embed galleries in any markdown content across the site. It leverages the existing directive architecture to maintain consistency with other embedded components while providing specific functionality for showcasing tools, images, and portfolio companies with proper data loading and error handling. The migration from YAML to directive syntax improves parsing reliability and extensibility.

Implementation

Changes Made

  • File Modified: site/src/components/markdown/AstroMarkdown.astro
    • Added import for PortfolioGallery component from @components/tool-components/PortfolioGallery.astro
    • Added import for resolvePortfolioId from @utils/toolUtils
    • Added: Tooling gallery directive support (:::tooling-gallery, :::toolingGallery)
    • Added: Image gallery directive support (:::image-gallery, :::imageGallery)
    • Enhanced: Portfolio gallery directive support (:::portfolio-gallery, :::portfolioGallery)
    • Implemented async loading logic in top-level script section for all gallery types
    • Added directive handlers for all gallery types with proper async/await architecture
    • Added: Deprecation warnings for YAML code block syntax
    • Fixed: Async/await usage by following the established pattern for all directives
    • Added configuration support for small, expanded, fullWidth attributes
    • Implemented comprehensive error handling for missing references
  • File Modified: site/src/utils/toolUtils.ts
    • Added resolvePortfolioId function (lines ~206-262) based on resolveToolId pattern
    • Implements 6-step resolution: exact match, normalized match, filename match, slugified match, partial path matching, routeManager resolution
    • Enables flexible portfolio reference formats in markdown directives
    • Fixed space/dash conversion for portfolio names like "Maven Clinic" ↔ "maven-clinic"
  • File Modified: site/src/components/markdown/ToolingGallery.astro
    • Added errors prop to display missing tool warnings
    • Added error display section with consistent styling
    • Enhanced error handling to match PortfolioGallery functionality
  • File Modified: site/src/components/tool-components/ToolCard.astro & site/src/components/tool-components/PortfolioCard.astro
    • Removed favicon display from both components for cleaner layout
    • Simplified header structure to focus on main content
  • File Created: site/GALLERY_DIRECTIVE_MIGRATION.md
    • Comprehensive migration guide for all gallery types
    • Examples of old vs new syntax
    • Regex patterns for automated migration
    • Benefits and timeline for directive adoption

Technical Details

Async/Await Architecture

Following the established pattern, all gallery loading logic is handled in the top-level script section where await is allowed:
javascript
// site/src/components/markdown/AstroMarkdown.astro
// Gallery Logic - handle async work upfront for all gallery types
const isToolingGalleryDirective = (
  node.type === "containerDirective" && 
  (node.name === 'tooling-gallery' || node.name === 'toolingGallery')
);

const isImageGalleryDirective = (
  node.type === "containerDirective" && 
  (node.name === 'image-gallery' || node.name === 'imageGallery')
);

const isPortfolioGallery = (
  node.type === "containerDirective" && 
  (node.name === 'portfolio-gallery' || node.name === 'portfolioGallery')
);

// Pre-computed variables for all gallery types
let toolingGalleryDirectiveTools = null;
let imageGalleryDirectiveCode = '';
let portfolioGalleryPortfolios = null;

if (isToolingGalleryDirective) {
  // Async tooling collection loading happens here
  const allTools = await getCollection('tooling');
  // Process and store results in variables
}

if (isImageGalleryDirective) {
  // Extract content from directive children
  imageGalleryDirectiveCode = extractedContent;
}

if (isPortfolioGallery) {
  // Async portfolio collection loading happens here
  const allPortfolios = await getCollection('client-portfolios');
  // Process and store results in variables
}

Directive Handler Implementation

javascript
// site/src/components/markdown/AstroMarkdown.astro
// All directive handlers use pre-computed data
if (directiveName === 'tooling-gallery') {
  return <ToolingGallery tools={toolingGalleryDirectiveTools} />
}

if (directiveName === 'image-gallery') {
  return <ImageGallery code={imageGalleryDirectiveCode} />
}

if (directiveName === 'portfolio-gallery') {
  return <PortfolioGallery portfolios={portfolioGalleryPortfolios} />
}

Portfolio Data Processing

  • Extracts portfolio paths from markdown list items with backlinks
  • Loads client-portfolios collection using getCollection()
  • Uses resolvePortfolioId for intelligent portfolio matching with multiple fallback strategies:
    1. Exact Match: Direct ID matching
    2. Normalized Match: Slugified comparison
    3. Filename Match: Case-insensitive filename matching
    4. RouteManager Resolution: Uses routing system for complex path resolution
  • Processes portfolio frontmatter data including url, tags, portfolios arrays
  • Generates proper id and filename properties for component consumption

Configuration Options

  • small: Renders compact portfolio cards
  • expanded: Controls initial gallery expansion state (default: true)
  • fullWidth/full: Makes gallery take full container width

Error Handling

  • Displays warning for missing portfolio references
  • Provides debug information in development
  • Gracefully handles empty directive content

Integration Points

Component Dependencies

  • PortfolioGallery: Main gallery component for rendering portfolio cards
  • getCollection: Astro content collection API for loading portfolio data
  • client-portfolios: Content collection containing portfolio company markdown files
markdown
:::tooling-gallery{small="true"}
- [[Flowise]]
- [[Acree AI]]
- [[LangChain]]
- tag: [[Agentic AI]]
- tag: [[Low-Code]]
:::

Old YAML Syntax ❌ (Deprecated - Shows Warning)

⚠️Deprecation Warning

The ```yaml toolingGallery syntax is deprecated. Please use :::tooling-gallery directive syntax instead.

markdown
:::image-gallery
- screenshot1.png
- screenshot2.jpg
- diagram.svg
- chart.webp
:::

Old YAML Syntax ❌ (Deprecated - Shows Warning)

⚠️Deprecation Warning

The ```yaml imageGallery syntax is deprecated. Please use :::image-gallery directive syntax instead.

markdown
:::portfolio-gallery{small="true"}
- [[Aalo Atomics]]
- [[Maven Clinic]]
- [[Trela]]
- tag: [[Telemedicine]]
:::
markdown
:::portfolio-gallery{small="false" fullWidth="true"}
- [[Aalo Atomics]]
- [[Maven Clinic]]
- [[Trela]]
- [[Ontra]]
- [[Watershed]]
- tag: [[Telemedicine]]
- tag: [[Climate Tech]]
:::

Mixed Reference Formats

markdown
:::portfolio-gallery
- [[Aalo Atomics]]  <!-- filename reference -->
- [[client-content/Hypernova/Portfolio/Watershed]]  <!-- full path -->
- tag: [[Telemedicine]]  <!-- tag filtering -->
:::

Configuration Options

  • small="true" - Display compact tool cards
  • size="small" - Alternative to small="true"
  • columns="3" - Number of columns (default: auto)
  • gap="1rem" - Gap between images
  • small="true" - Display compact portfolio cards
  • expanded="false" - Control initial expansion state
  • fullWidth="true" - Make gallery take full container width
  • full="true" - Alternative to fullWidth="true"

Deprecation Warnings

When using the old YAML syntax, users will see deprecation warnings:
text
⚠️ Deprecation Warning
The ```yaml toolingGallery syntax is deprecated. 
Please use :::tooling-gallery directive syntax instead.
The warnings appear above the galleries but don't prevent them from working, ensuring backward compatibility during migration.

Content Collection Requirements

  • Portfolio files must exist in the client-portfolios collection
  • Files should follow the path pattern: client-content/{Client}/Portfolio/{Company}.md
  • Portfolio frontmatter should include standard fields: url, tags, portfolios, etc.

Documentation

Directive Architecture Consistency

This implementation follows the established pattern used by:
  • tool-showcase directive for tool galleries
  • slides/slideshow directive for presentation embeds
  • figma-embed directive for design embeds

Error States

  • Portfolio Gallery Error: Red-bordered warning showing missing portfolio paths
  • Portfolio Gallery Empty: Debug information when no valid portfolios found
  • Unknown Directive: Fallback for unrecognized directive names

Example Usage in Markdown

The directive can be used in any markdown file processed by AstroMarkdown to embed portfolio galleries with proper data loading, styling, and responsive behavior.

Live Examples

Here are working examples of all the new gallery directive types:
Tooling Gallery (New Directive Syntax):
Tooling Gallery (Old YAML Syntax - Shows Deprecation Warning):
⚠️Deprecation Warning

The ```yaml toolingGallery syntax is deprecated. Please use :::tooling-gallery directive syntax instead.

Portfolio Gallery (Small):
Portfolio Gallery (Large):
Image Gallery (New Directive Syntax):
Image Gallery (Old YAML Syntax - Shows Deprecation Warning):
⚠️Deprecation Warning

The ```yaml imageGallery syntax is deprecated. Please use :::image-gallery directive syntax instead.

Warning Callout (Directive Syntax):

Unknown directive: warning

Debug Info
json
{
  "name": "warning",
  "attributes": {
    "title": "Custom Title"
  }
}
This enhancement extends the site's content authoring capabilities by providing a standardized way to embed all types of galleries (tools, images, and portfolios) while maintaining consistency with the existing directive architecture and component system. The migration from YAML code blocks to directive syntax improves parsing reliability, extensibility, and provides a more semantic approach to structured content embedding.
The comprehensive gallery directive system now supports:
  • Tooling Galleries: Showcase tools with tag filtering and error handling
  • Image Galleries: Display image collections with flexible layout options
  • Portfolio Galleries: Present portfolio companies with size and layout controls
  • Backward Compatibility: YAML syntax continues to work with deprecation warnings
  • Migration Path: Clear guidance for transitioning to directive syntax