Skip to content

Commit 675a3e0

Browse files
committed
refactor: return ?string from script()/css() instead of echo
Change script() and css() methods to return the tag string when block => false, instead of echoing directly. This is more consistent with CakePHP's HtmlHelper conventions and makes the code easier to test.
1 parent b1dee7e commit 675a3e0

2 files changed

Lines changed: 54 additions & 39 deletions

File tree

src/View/Helper/ViteHelper.php

Lines changed: 36 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -77,13 +77,14 @@ public function isDev(array|ViteConfig|null $config = null): bool
7777
*
7878
* Backwards compatible with ViteScriptsHelper::script()
7979
*
80-
* When `block` option is `false`, outputs tags directly (inline).
81-
* Otherwise appends to the specified view block.
80+
* When `block` option is `false`, returns the tags as a string for inline output.
81+
* Otherwise appends to the specified view block and returns null.
8282
*
8383
* @param array<string, mixed>|string $options Options or file shorthand
8484
* @param \CakeVite\ValueObject\ViteConfig|array<string, mixed>|null $config Configuration
85+
* @return string|null Returns tag string when block is false, null otherwise
8586
*/
86-
public function script(array|string $options = [], array|ViteConfig|null $config = null): void
87+
public function script(array|string $options = [], array|ViteConfig|null $config = null): ?string
8788
{
8889
$options = $this->normalizeOptions($options);
8990
$config = $this->extractConfigFromOptions($options, $config);
@@ -102,14 +103,16 @@ public function script(array|string $options = [], array|ViteConfig|null $config
102103

103104
$tags = $this->getAssetService()->generateScriptTags($config, $options);
104105

106+
$output = '';
107+
105108
// Render tags (preload tags as link elements, script tags as script elements)
106109
foreach ($tags as $tag) {
107110
if ($tag->isPreload) {
108111
// Render preload tags as <link rel="modulepreload" href="...">
109112
$preloadType = $tag->preloadType ?? 'modulepreload';
110113
$linkTag = $this->buildPreloadLinkTag($preloadType, $tag->url, $tag->attributes);
111114
if ($inline) {
112-
echo $linkTag;
115+
$output .= $linkTag;
113116
} else {
114117
$this->getView()->append($block, $linkTag);
115118
}
@@ -118,29 +121,32 @@ public function script(array|string $options = [], array|ViteConfig|null $config
118121
// When block is false, Html::script() returns the tag string
119122
$scriptTag = $this->Html->script($tag->url, array_merge(['block' => $block], $tag->attributes));
120123
if ($inline && $scriptTag !== null) {
121-
echo $scriptTag;
124+
$output .= $scriptTag;
122125
}
123126
}
124127
}
125128

126129
// Add dependent CSS if in production
127130
if (!$this->isDev($config)) {
128-
$this->addDependentCss($config, $options, $cssBlock, $inline);
131+
$output .= $this->addDependentCss($config, $options, $cssBlock, $inline);
129132
}
133+
134+
return $inline ? $output : null;
130135
}
131136

132137
/**
133138
* Render CSS tags
134139
*
135140
* Backwards compatible with ViteScriptsHelper::css()
136141
*
137-
* When `block` option is `false`, outputs tags directly (inline).
138-
* Otherwise appends to the specified view block.
142+
* When `block` option is `false`, returns the tags as a string for inline output.
143+
* Otherwise appends to the specified view block and returns null.
139144
*
140145
* @param array<string, mixed>|string $options Options or file shorthand
141146
* @param \CakeVite\ValueObject\ViteConfig|array<string, mixed>|null $config Configuration
147+
* @return string|null Returns tag string when block is false, null otherwise
142148
*/
143-
public function css(array|string $options = [], array|ViteConfig|null $config = null): void
149+
public function css(array|string $options = [], array|ViteConfig|null $config = null): ?string
144150
{
145151
$options = $this->normalizeOptions($options);
146152
$config = $this->extractConfigFromOptions($options, $config);
@@ -152,13 +158,17 @@ public function css(array|string $options = [], array|ViteConfig|null $config =
152158

153159
$tags = $this->getAssetService()->generateStyleTags($config, $options);
154160

161+
$output = '';
162+
155163
foreach ($tags as $tag) {
156164
// When block is false, Html::css() returns the tag string
157165
$cssTag = $this->Html->css($tag->url, array_merge(['block' => $block], $tag->attributes));
158166
if ($inline && $cssTag !== null) {
159-
echo $cssTag;
167+
$output .= $cssTag;
160168
}
161169
}
170+
171+
return $inline ? $output : null;
162172
}
163173

164174
/**
@@ -293,10 +303,15 @@ private function extractConfigFromOptions(
293303
* @param \CakeVite\ValueObject\ViteConfig $config Configuration
294304
* @param array<string, mixed> $options Options
295305
* @param string|false $cssBlock CSS block name or false for inline output
296-
* @param bool $inline Whether to output inline (when block is false)
306+
* @param bool $inline Whether to return inline (when block is false)
307+
* @return string Returns CSS tags when inline is true, empty string otherwise
297308
*/
298-
private function addDependentCss(ViteConfig $config, array $options, string|false $cssBlock, bool $inline = false): void
299-
{
309+
private function addDependentCss(
310+
ViteConfig $config,
311+
array $options,
312+
string|false $cssBlock,
313+
bool $inline = false,
314+
): string {
300315
$manifestService = new ManifestService();
301316
$manifest = $manifestService->load($config);
302317

@@ -308,14 +323,20 @@ private function addDependentCss(ViteConfig $config, array $options, string|fals
308323
$entries = $manifest->filterEntries();
309324
$pluginPrefix = $config->pluginName ? $config->pluginName . '.' : '';
310325

326+
$output = '';
327+
311328
foreach ($entries as $entry) {
312329
foreach ($entry->getDependentCssUrls() as $cssUrl) {
313-
$cssTag = $this->Html->css($pluginPrefix . $cssUrl, ['block' => $cssBlock]);
330+
// When inline, pass block => false to get the tag string; otherwise use the block name
331+
$blockOption = $inline ? false : $cssBlock;
332+
$cssTag = $this->Html->css($pluginPrefix . $cssUrl, ['block' => $blockOption]);
314333
if ($inline && $cssTag !== null) {
315-
echo $cssTag;
334+
$output .= $cssTag;
316335
}
317336
}
318337
}
338+
339+
return $output;
319340
}
320341

321342
/**

tests/TestCase/View/Helper/ViteHelperTest.php

Lines changed: 18 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -741,11 +741,10 @@ public function testScriptWithBlockFalseOutputsInline(): void
741741
],
742742
];
743743

744-
ob_start();
745-
$this->Vite->script(['files' => ['src/app.ts'], 'block' => false], $config);
746-
$output = ob_get_clean();
744+
$output = $this->Vite->script(['files' => ['src/app.ts'], 'block' => false], $config);
747745

748-
// Should output directly instead of buffering to view block
746+
// Should return tags directly instead of buffering to view block
747+
$this->assertNotNull($output);
749748
$this->assertStringContainsString('http://localhost:3000/@vite/client', $output);
750749
$this->assertStringContainsString('http://localhost:3000/src/app.ts', $output);
751750
$this->assertStringContainsString('type="module"', $output);
@@ -766,11 +765,10 @@ public function testScriptWithBlockFalseInProductionMode(): void
766765
],
767766
];
768767

769-
ob_start();
770-
$this->Vite->script(['files' => ['src/app.ts'], 'block' => false], $config);
771-
$output = ob_get_clean();
768+
$output = $this->Vite->script(['files' => ['src/app.ts'], 'block' => false], $config);
772769

773-
// Should output directly
770+
// Should return tags directly
771+
$this->assertNotNull($output);
774772
$this->assertStringContainsString('assets/app-abc123.js', $output);
775773
$this->assertStringNotContainsString('localhost', $output);
776774

@@ -791,11 +789,10 @@ public function testCssWithBlockFalseOutputsInline(): void
791789
],
792790
];
793791

794-
ob_start();
795-
$this->Vite->css(['files' => ['src/style.css'], 'block' => false], $config);
796-
$output = ob_get_clean();
792+
$output = $this->Vite->css(['files' => ['src/style.css'], 'block' => false], $config);
797793

798-
// Should output directly
794+
// Should return tags directly
795+
$this->assertNotNull($output);
799796
$this->assertStringContainsString('http://localhost:3000/src/style.css', $output);
800797

801798
// View block should be empty
@@ -814,11 +811,10 @@ public function testCssWithBlockFalseInProductionMode(): void
814811
],
815812
];
816813

817-
ob_start();
818-
$this->Vite->css(['files' => ['src/style.css'], 'block' => false], $config);
819-
$output = ob_get_clean();
814+
$output = $this->Vite->css(['files' => ['src/style.css'], 'block' => false], $config);
820815

821-
// Should output directly
816+
// Should return tags directly
817+
$this->assertNotNull($output);
822818
$this->assertStringContainsString('assets/style-jkl012.css', $output);
823819

824820
// View block should be empty
@@ -836,11 +832,10 @@ public function testScriptWithBlockFalseOutputsPreloadTagsInline(): void
836832
'forceProductionMode' => true,
837833
];
838834

839-
ob_start();
840-
$this->Vite->script(['files' => ['src/app.ts'], 'block' => false], $config);
841-
$output = ob_get_clean();
835+
$output = $this->Vite->script(['files' => ['src/app.ts'], 'block' => false], $config);
842836

843-
// Preload tags should be output directly
837+
// Preload tags should be returned directly
838+
$this->assertNotNull($output);
844839
$this->assertStringContainsString('modulepreload', $output);
845840
$this->assertStringContainsString('<link rel="modulepreload"', $output);
846841

@@ -860,11 +855,10 @@ public function testScriptWithBlockFalseOutputsDependentCssInline(): void
860855
],
861856
];
862857

863-
ob_start();
864-
$this->Vite->script(['files' => ['src/app.ts'], 'block' => false], $config);
865-
$output = ob_get_clean();
858+
$output = $this->Vite->script(['files' => ['src/app.ts'], 'block' => false], $config);
866859

867-
// Dependent CSS should be output directly
860+
// Dependent CSS should be returned directly
861+
$this->assertNotNull($output);
868862
$this->assertStringContainsString('assets/app-xyz789.css', $output);
869863

870864
// CSS view block should be empty

0 commit comments

Comments
 (0)