fix(09): revise plans based on checker feedback

- Plan 02: Added key_link clarifying CmsPageService.render populates
  PageRenderContext.components before template rendering. Updated
  Task 2/3 actions to emphasize component initialization flow.

- Plan 03: Split into 03 (storage + library core) and 03b (image
  processing + routes) to reduce scope from 9 files to 7+4 files.
  Estimated context reduced from ~65% to ~45% each.

- Plan 03b: New plan for ImageProcessor and MediaRoutes. Added
  specific curl command with -F flags and expected JSON response.

- Plan 05: Added plugin integration test (MenuPluginIntegrationSpec)
  demonstrating custom menu item type registration, resolution, and
  template rendering per CONT-09 requirement.

- Plan 06: Reframed must_haves truths from implementation details
  to user-observable outcomes (e.g., 'Developer edits template file,
  browser refresh shows changes without server restart')

- Roadmap: Updated Phase 9 from 6 to 7 plans.
This commit is contained in:
Jakub Zych
2026-02-05 15:41:50 +01:00
parent dca89e10cd
commit edbee885ac
6 changed files with 506 additions and 296 deletions

View File

@@ -40,6 +40,10 @@ must_haves:
to: "PageRenderContext.placeholderContent"
via: "checks for put content before rendering default"
pattern: "placeholderContent\\.get"
- from: "CmsPageService.render"
to: "PageRenderContext.components"
via: "initializes components from page config before rendering"
pattern: "PageRenderContext.*components.*="
---
<objective>
@@ -136,6 +140,10 @@ Implement `{% component 'alias' prop1='value' %}`:
- Call component.render() using pageContext.runtime.unsafeRun
- Write rendered HTML to output
**CRITICAL: ComponentTag depends on PageRenderContext.components being pre-populated.**
The components map is populated by CmsPageService.render (Task 3) BEFORE the template is rendered.
ComponentTag only looks up by alias - it does NOT initialize components.
Component lookup: Page's INI section defines components like:
```
[blogPosts posts]
@@ -190,17 +198,24 @@ class CmsPebbleExtension extends Extension:
```
**Update CmsPageService.scala render method:**
Implement two-pass rendering:
Implement two-pass rendering with COMPONENT INITIALIZATION:
1. Initialize components from page config:
- Parse component definitions from page settings
- For each `[componentClass alias]` section, create ComponentInstance
- Run component lifecycle (init, onRun)
1. **Initialize components from page config (CRITICAL - populates PageRenderContext.components):**
- Parse component definitions from page settings (INI format)
- For each `[componentClass alias]` section:
a. Look up component class from ComponentRegistry (from Phase 3)
b. Create ComponentInstance with properties from section
c. Run component lifecycle (init, onRun)
d. Store in components Map keyed by alias
- This Map is passed to PageRenderContext BEFORE any template rendering
2. First pass - render page content:
- Create PageRenderContext with mutable.Map for placeholderContent
- Create PageRenderContext with:
- `components`: the Map populated in step 1
- `placeholderContent`: empty mutable.Map
- Render page.markup with Pebble
- This collects {% put %} content into placeholderContent
- {% component 'alias' %} tags can now resolve from pre-populated components Map
3. Second pass - render layout:
- Get layout from page.config.layout
@@ -219,7 +234,7 @@ End-to-end test: Create sample page with component, partial, and placeholder
Render should produce composed HTML with all elements
</verify>
<done>
CmsPebbleExtension registers all CMS tags with Pebble. CmsPageService.render uses two-pass rendering: first to collect put content, then to render layout with placeholders resolved.
CmsPebbleExtension registers all CMS tags with Pebble. CmsPageService.render initializes components from page config into PageRenderContext.components Map, then uses two-pass rendering: first to collect put content, then to render layout with placeholders resolved.
</done>
</task>
@@ -267,6 +282,8 @@ property = "value"
- {% placeholder 'name' %}default{% endplaceholder %} in layouts with page-fillable content
- {% put 'name' %}content{% endput %} in pages fills layout placeholders
- {% partial 'name' %} includes partials with variables
- CmsPageService.render initializes components from page config BEFORE template rendering
- PageRenderContext.components is populated when ComponentTag executes
- Two-pass rendering correctly resolves all template composition
</success_criteria>