Skip to content

Commit bdf2380

Browse files
committed
Implement #192 — prefix-stripping DX for CwaFixtureBuilder uiComponent
layout() and page() now accept a suffix only and prepend the correct framework prefix automatically: $cwa->layout('main', 'Primary') → stores 'CwaLayoutPrimary' $cwa->page('home', 'Blog', ...) → stores 'CwaPageBlog' ComponentBuilder gains uiComponent(string $suffix) which derives the full alt-component name from the entity class: $cwa->component($link)->uiComponent('YouTube') → stores 'CwaComponentNavigationLinkUiYouTube' uiClassNames() on LayoutBuilder, PageBuilder, and ComponentBuilder is now variadic: ->uiClassNames('bold', 'dark') instead of ->uiClassNames([...]). GenerateFixturesCommand strips the CwaLayout/CwaPage prefix when emitting fixture code so the generated output uses the new short-name API. MakeCwaScaffold and skeleton template updated to use suffix-only names.
1 parent 51ed633 commit bdf2380

10 files changed

Lines changed: 173 additions & 86 deletions

File tree

CLAUDE.md

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -352,19 +352,20 @@ Register `AppScaffold` as a service; it's ready to use as a Doctrine fixture wit
352352

353353
```
354354
CwaFixtureBuilder
355-
->layout(ref, uiComponent, ?uiClassNames): LayoutBuilder (deduped by ref; returns same builder if called twice)
356-
->page(ref, uiComponent, layout, ?route, ?routeName, isTemplate=false, ?Closure, ?uiClassNames): PageBuilder
355+
->layout(ref, uiSuffix, ?uiClassNames): LayoutBuilder (deduped by ref; prepends 'CwaLayout' to uiSuffix)
356+
->page(ref, uiSuffix, layout, ?route, ?routeName, isTemplate=false, ?Closure, ?uiClassNames): PageBuilder (prepends 'CwaPage' to uiSuffix)
357357
->pageData(AbstractPageData, ?template, ?route, ?routeName, ?Closure): PageDataBuilder
358+
->component(AbstractComponent): ComponentBuilder
358359
->getRoute(routeName): Route (look up a named route already created)
359360
360361
LayoutBuilder
361362
->group(name, allow: [], ?Closure): GroupBuilder (returns the GroupBuilder; same name = same group)
362-
->uiClassNames(array): self
363+
->uiClassNames(string ...$classes): self
363364
364365
PageBuilder
365366
->title(string): self
366367
->metaDescription(string): self
367-
->uiClassNames(array): self
368+
->uiClassNames(string ...$classes): self
368369
->group(name, ?Closure): GroupBuilder
369370
->nested(Closure): void (Closure receives CwaFixtureBuilder with parent context)
370371
->getRoute(): ?Route (route after builder flushes RouteGenerator)
@@ -374,6 +375,11 @@ PageDataBuilder
374375
->onRoutesCreated(Closure): self (Closure receives array<PageBuilder> of direct child page builders; called after phaseThree so child route paths are available)
375376
->getRoute(): ?Route
376377
378+
ComponentBuilder
379+
->uiComponent(suffix): self (stores 'CwaComponent' + ShortClassName + 'Ui' + suffix)
380+
->uiClassNames(string ...$classes): self
381+
->group(name, allow: [], ?Closure): GroupBuilder
382+
377383
GroupBuilder
378384
->add(AbstractComponent, ?sort): self (sort defaults to insertion order × 10)
379385
->pageDataPosition(pageDataClass, propertyName, ?sort): self (creates ComponentPosition with pageDataClass and pageDataProperty set)

src/Command/GenerateFixturesCommand.php

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ private function emitLayout(Layout $layout): string
107107
{
108108
$varName = '$layout_' . $this->toVar($layout->reference ?? 'layout');
109109
$ref = var_export($layout->reference, true);
110-
$ui = var_export($layout->uiComponent, true);
110+
$ui = var_export($this->stripUiPrefix($layout->uiComponent, 'CwaLayout'), true);
111111

112112
$extra = '';
113113
if (null !== $layout->uiClassNames) {
@@ -207,7 +207,7 @@ private function emitPage(
207207
string $builderVar = '$cwa',
208208
): string {
209209
$ref = var_export($page->reference, true);
210-
$ui = var_export($page->uiComponent, true);
210+
$ui = var_export($this->stripUiPrefix($page->uiComponent, 'CwaPage'), true);
211211
$layoutRef = var_export(isset($page->layout) ? $page->layout->reference : null, true);
212212

213213
$args = "{$ref}, {$ui}, layout: {$layoutRef}";
@@ -403,6 +403,15 @@ private function exportArray(array $arr): string
403403
return '[' . $items . ']';
404404
}
405405

406+
private function stripUiPrefix(?string $value, string $prefix): ?string
407+
{
408+
if (null === $value) {
409+
return null;
410+
}
411+
412+
return str_starts_with($value, $prefix) ? substr($value, \strlen($prefix)) : $value;
413+
}
414+
406415
private function getRouteName(Route $route): ?string
407416
{
408417
$rp = (new \ReflectionClass($route))->getProperty('name');

src/Fixture/Builder/ComponentBuilder.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,21 @@ public function __construct(private readonly AbstractComponent $component)
2222
{
2323
}
2424

25+
public function uiComponent(string $suffix): self
26+
{
27+
$shortName = (new \ReflectionClass($this->component))->getShortName();
28+
$this->component->uiComponent = 'CwaComponent' . $shortName . 'Ui' . $suffix;
29+
30+
return $this;
31+
}
32+
33+
public function uiClassNames(string ...$classes): self
34+
{
35+
$this->component->uiClassNames = $classes;
36+
37+
return $this;
38+
}
39+
2540
public function group(string $name, array $allow = [], ?\Closure $configure = null, ?string $locationReference = null): GroupBuilder
2641
{
2742
if (!isset($this->groupBuilders[$name])) {

src/Fixture/Builder/LayoutBuilder.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ public function group(string $name, array $allow = [], ?\Closure $configure = nu
3434
return $this->groupBuilders[$name];
3535
}
3636

37-
public function uiClassNames(array $classes): self
37+
public function uiClassNames(string ...$classes): self
3838
{
3939
$this->layout->uiClassNames = $classes;
4040

src/Fixture/Builder/PageBuilder.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ public function metaDescription(string $metaDescription): self
4848
return $this;
4949
}
5050

51-
public function uiClassNames(array $classes): self
51+
public function uiClassNames(string ...$classes): self
5252
{
5353
$this->page->uiClassNames = $classes;
5454

src/Fixture/CwaFixtureBuilder.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ public function layout(string $ref, string $uiComponent, ?array $uiClassNames =
101101
if (!isset($this->layoutBuilders[$ref])) {
102102
$layout = new Layout();
103103
$layout->reference = $ref;
104-
$layout->uiComponent = $uiComponent;
104+
$layout->uiComponent = '' !== $uiComponent ? 'CwaLayout' . $uiComponent : null;
105105
$layout->uiClassNames = $uiClassNames;
106106
$this->layoutBuilders[$ref] = new LayoutBuilder($layout);
107107
}
@@ -122,7 +122,7 @@ public function page(
122122
if (!isset($this->pageSpecs[$ref])) {
123123
$page = new Page();
124124
$page->reference = $ref;
125-
$page->uiComponent = $uiComponent;
125+
$page->uiComponent = '' !== $uiComponent ? 'CwaPage' . $uiComponent : null;
126126
$page->uiClassNames = $uiClassNames;
127127
$page->isTemplate = $isTemplate;
128128
if ($this->parentContext instanceof AbstractPageData) {

src/Maker/MakeCwaScaffold.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public function configureCommand(Command $command, InputConfiguration $inputConf
4242
$command
4343
->addArgument('name', InputArgument::OPTIONAL, 'The class name for your scaffold (e.g. <fg=yellow>AppScaffold</>)')
4444
->addOption('layout-ref', null, InputOption::VALUE_REQUIRED, 'Layout reference key used in <comment>$cwa->layout()</comment>', 'main')
45-
->addOption('layout-component', null, InputOption::VALUE_REQUIRED, 'Layout UI component name (e.g. <comment>CwaLayoutPrimary</comment>)', 'CwaLayoutPrimary');
45+
->addOption('layout-component', null, InputOption::VALUE_REQUIRED, 'Layout UI component name (e.g. <comment>Primary</comment>)', 'Primary');
4646
}
4747

4848
public function interact(InputInterface $input, ConsoleStyle $io, Command $command): void
@@ -52,8 +52,8 @@ public function interact(InputInterface $input, ConsoleStyle $io, Command $comma
5252
$input->setOption('layout-ref', $ref);
5353
}
5454

55-
if (!$input->getOption('layout-component') || 'CwaLayoutPrimary' === $input->getOption('layout-component')) {
56-
$component = $io->ask('Layout UI component name', 'CwaLayoutPrimary');
55+
if (!$input->getOption('layout-component') || 'Primary' === $input->getOption('layout-component')) {
56+
$component = $io->ask('Layout UI component name', 'Primary');
5757
$input->setOption('layout-component', $component);
5858
}
5959
}

src/Resources/skeleton/scaffold/Scaffold.tpl.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,14 @@ public function build(CwaFixtureBuilder $cwa): void
2424
->group('top');
2525

2626
// --- Pages ------------------------------------------------------------
27-
$cwa->page('home', 'PrimaryPageTemplate', layout: '<?php echo $layout_ref; ?>', route: '/', routeName: 'home-page',
27+
$cwa->page('home', 'PrimaryPage', layout: '<?php echo $layout_ref; ?>', route: '/', routeName: 'home-page',
2828
configure: fn (PageBuilder $page) => $page
2929
->title('Home')
3030
->group('primary')
3131
);
3232

3333
// Add more pages here, e.g.:
34-
// $cwa->page('about', 'PrimaryPageTemplate', layout: '<?php echo $layout_ref; ?>', route: '/about', routeName: 'about-page',
34+
// $cwa->page('about', 'PrimaryPage', layout: '<?php echo $layout_ref; ?>', route: '/about', routeName: 'about-page',
3535
// configure: fn (PageBuilder $page) => $page->title('About')->group('primary')
3636
// );
3737

tests/Command/GenerateFixturesCommandTest.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,8 @@ public function test_layout_appears_as_cwa_layout_call(): void
183183
$content = file_get_contents($this->outputFile);
184184
$this->assertStringContainsString('->layout(', $content);
185185
$this->assertStringContainsString("'main'", $content);
186-
$this->assertStringContainsString("'CwaLayoutPrimary'", $content);
186+
$this->assertStringContainsString("'Primary'", $content);
187+
$this->assertStringNotContainsString("'CwaLayoutPrimary'", $content);
187188
}
188189

189190
public function test_page_with_route_appears_as_cwa_page_call(): void

0 commit comments

Comments
 (0)