Windows App Community
Windows App Community - PostPageFolder Refactor Planning - Virtual IFolder Pattern
By Arlo Godfrey 2025-11-08 Planning
Planning document defining source and destination requirements for refactoring PostPageGenerator to PostPageFolder virtual IFolder pattern, enabling Multi-Page composition while maintaining backward compatibility. Transformation approach deliberately excluded.
Windows App Community
PostPageGenerator PostPageFolder Virtual IFolder Refactor Planning Lazy Generation Composition Backward Compatibility Blog Generator Single-Page Multi-Page Windows App Community Project Planning

Introduction

This document defines source and destination requirements for refactoring PostPageGenerator from side-effect orchestrator to PostPageFolder virtual IFolder pattern. Refactor enables Multi-Page scenario implementation by introducing composable virtual structure while maintaining backward compatibility with existing Single-Page usage.

Scope: Single-Page (Post/Page) refactor only. Multi-Page implementation deliberately excluded from this planning document.

Purpose: Establish clear what/where requirements for review before implementation execution. Transformation "how" deliberately omitted per planning phase separation.

Context: PostPageGenerator currently operational (October 25-26, 2025 implementation). Design investigation completed November 1-3, 2025, confirming virtual IFolder pattern viability across all three scenarios and invalidating "perfect reuse" assumption.


Table of Contents


Source Requirements: PostPageGenerator Current State

Architecture

Pattern: Side-effect orchestrator with immediate write operations

Structure:

Design Characteristics:

Behavior

GenerateAsync() Current Operation:

Processing Flow:

  1. Resolve template (IFile or IFolder)
  2. Extract YAML front-matter from markdown
  3. Transform markdown body to HTML (Markdig)
  4. Apply Scriban template with data model
  5. Create output folder structure
  6. Write index.html
  7. Copy template assets (if folder template)

Components

PostPageGenerator (Core Transformer):

PostPageDataModel (Scriban Data Contract):

PostPageCommand (CLI Interface):

WacsdkBlogCommands (Command Aggregator):


Destination Requirements

Virtual IFolder Implementation

Pattern: PostPageFolder implements IFolder interface representing single-page output structure

Characteristics:

Scope:

Three Component Types (from Gap 1 investigation):

  1. PostPageFolder (Main virtual folder):

    • Implements IFolder interface
    • Wraps source markdown IFile
    • Yields IndexHtmlFile + template assets via GetItemsAsync
    • Constructor: PostPageFolder(IFile markdownSource, IStorable templateSource, string? templateFileName = null)
    • Identity: Derived from source markdown IFile.Id, sanitized filename for Name
  2. PostPageAssetFolder (Recursive template asset wrapper):

    • Implements IChildFolder interface (includes GetParentAsync)
    • Recursively mirrors template folder structure
    • Stores Parent property for proper folder hierarchy
    • Constructor: PostPageAssetFolder(IFolder wrappedFolder, IFolder parent, IFile? templateFileToExclude)
    • Identity: Passthrough from wrapped template folder (Id, Name)
  3. IndexHtmlFile (Virtual markdown→HTML file):

    • Implements IFile interface
    • Renders markdown→HTML only when OpenStreamAsync called
    • Constructor: IndexHtmlFile(string id, IFile markdownSource, IStorable templateSource, string? templateFileName)
    • Identity: Parent-derived ID (format TBD), constant "index.html" name

Wrapper Architecture:

Lazy Generation

Requirement: Content created on access, not during construction

Trigger Points:

Not Triggered By:

Rationale: Enables composition scenarios where PostPageFolder instances created but not materialized until consumer explicitly requests output.

Generation Timing Decision (from Gap 2 investigation):

State Storage:

Error Handling Timing:

Composition Enablement

Requirement: PostPageFolder instances composable by higher-level orchestrators

Target Scenario: PagesFolder (Multi-Page) composes multiple PostPageFolder instances to create multi-page output

Composition Characteristics:

Architectural Validation: PostPageFolder ready for PagesFolder composition (implementation of PagesFolder deliberately excluded from this planning document)

Consumer Control

Requirement: Consumer determines when and where output materializes

Current Behavior Preserved:

New Capability Added:


IFolder Method Implementation Scope

Requirement: Specify which IFolder/IChildFolder/IFile methods required vs omitted

Interface Analysis (from Gap 4 investigation):

PostPageFolder Method Scope (implements IFolder):

PostPageAssetFolder Method Scope (implements IChildFolder):

IndexHtmlFile Method Scope (implements IFile):

GetItemsAsync Enumeration Patterns:

Capabilities Interfaces: None required - base interfaces sufficient for read-only virtual structure


Component Decomposition

Requirement: Pure transformation logic extractable and reusable across implementation patterns

Investigation Status (from Gap 3): Deferred to implementation phase - extraction boundaries emerge naturally during refactoring, October implementation provides working reference (3 partials: Markdown, Template, Main)

Components to Extract:

Markdown Processing:

Template Processing:

Asset Management:

Rationale: Extracting pure transformation logic:

Asset Virtual Representation (from Gap 5 investigation):


External Dependencies

Requirement: External libraries and configurations preserved across refactor

Required Libraries:

Markdig (Markdown → HTML transformation):

Scriban (Template rendering engine):

YamlDotNet (YAML front-matter parsing):

OwlCore.Storage Extensions:

Rationale: Dependencies unchanged by refactor. Virtual IFolder pattern works with same libraries, just changes when/where transformations execute (lazy vs eager).


Configuration Preservation

Requirement: Configuration decisions from October implementation maintained

Markdig Configuration:

Template File Convention:

Folder Name Sanitization:

Overwrite Behavior:

YAML Front-Matter Handling:

Rationale: These configurations proven operational in October implementation. Virtual IFolder pattern preserves same decisions, changes only orchestration timing.


Error Handling

Requirement: Exception patterns and bubbling behavior preserved

YamlException Wrapping:

Template File Not Found:

Path Resolution Failures:

Framework Integration:

Rationale: Virtual IFolder pattern maintains same exception patterns. Errors during lazy generation bubble same way as errors during eager generation.


Capabilities Preservation

Requirement: All 9 features from October implementation must continue working post-refactor

Feature Checklist:

  1. Markdown → HTML Body Conversion

    • Markdig Advanced Extensions (tables, strikethrough, task lists, autolinks)
    • Pure text transformation
    • Populates PostPageDataModel.Body
  2. YAML Front-Matter Extraction

    • Parse arbitrary key-value pairs
    • Handle absence gracefully (empty string → empty dictionary)
    • Populates PostPageDataModel.Frontmatter
  3. Front-Matter → HTML Meta Tags

    • Generator provides frontmatter dictionary with all keys
    • Template generates <meta> tags from dictionary
    • No special handling of any keys (template responsibility)
  4. Scriban Template Application

    • Template receives PostPageDataModel
    • Template generates all HTML including meta tags
    • Generator invokes, template transforms
  5. Template Source Resolution

    • Type detection: IFile vs IFolder (pattern matching)
    • Convention: template.html default, parameter override
    • Error: InvalidOperationException if not found
  6. Template Folder Asset Copying

    • DepthFirstRecursiveFolder for recursive enumeration
    • Path-based copying preserves folder structure
    • Template file exclusion via ID comparison
  7. Output Folderization

    • Sanitized folder name from markdown filename
    • Structure: {sanitized-name}/index.html + assets
    • Silent overwrite for regeneration workflows
  8. Open Graph Meta Tag Support

    • Generator includes og:* keys in frontmatter (no filtering)
    • Template generates <meta property="og:*"> tags
    • Template controls which keys become meta tags
  9. Template-Defined HTML Structure

    • Template receives model, generates complete HTML
    • Generator does not generate any HTML structure
    • Clear boundary: Generator = data, Template = HTML

Validation: PostPageCommand tests must pass unchanged (backward compatibility requirement enforces feature preservation)

Rationale: Refactor changes orchestration pattern (eager → lazy), not feature set. All capabilities remain functional through virtual IFolder pattern.


Backward Compatibility Requirements

Direct Integration (No Facade)

Decision: PostPageGenerator removed, PostPageFolder integrated directly into PostPageCommand

Integration Strategy:

Preserved API:

Rationale: Facade adds unnecessary complexity when direct integration achieves same backward compatibility goals. PostPageCommand is the user-facing API, internal implementation can be replaced cleanly.

Validation Criteria

Requirement: Output matches baseline from community planning.md generation

Validation Approach:

Validation Targets:

Error Timing Note: Errors thrown on access (GetFileAsync/CopyToAsync) per lazy generation pattern, not during PostPageFolder construction. Exception types preserved, timing shifted.


Success Criteria

Refactor complete when ALL criteria met:


Explicit Exclusion: Transformation "How"

Deliberately Excluded from this Planning Document:

Rationale: Planning phase establishes direction and requirements (what/where). Implementation phase determines approach and execution (how). Premature specification of transformation approach risks over-constraint and reduces implementation flexibility.

Gap Analysis Complete (2025-11-08):

Implementation Readiness: All critical gaps resolved, sufficient architectural certainty established. Ready to proceed with implementation execution.

Next Phase: Implementation execution following established patterns from gap analysis investigation.


References

Primary Planning Context:

Historical Context:

Requirements Documentation:

Investigation Records:

Session Records:

Methodology:

October Implementation Reference:

Gap Analysis:


Document Status: Planning complete with comprehensive gap analysis integrated (November 8, 2025). Source requirements (PostPageGenerator current architecture) and destination requirements (PostPageFolder virtual IFolder pattern with implementation preservation) fully documented with HIGH architectural certainty. All critical gaps resolved through systematic investigation: virtual structure pattern (3 component types), lazy generation mechanics (Option A direct passthrough), IFolder method scope, and asset representation patterns established. Implementation-ready - sufficient certainty achieved for execution phase.