Skip to content

Commit bd6612c

Browse files
committed
[Twig] Add reprise_entry_exists()
1 parent e8e0b6f commit bd6612c

7 files changed

Lines changed: 55 additions & 1 deletion

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
## 0.6.0
44

55
- Add a per-call `attributes` argument to the `reprise_entry_script_tags()` and `reprise_entry_link_tags()` Twig functions
6+
- Add the `reprise_entry_exists()` Twig function
67

78
## 0.5.0
89

doc/index.rst

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ This is where Reprise pays off: once ``entrypoints.json`` exists, ``RepriseBundl
9696
``<script>`` and ``<link>`` tags for an entry directly in Twig, the same experience `WebpackEncoreBundle`_ gives you
9797
with ``encore_entry_script_tags`` and ``encore_entry_link_tags``.
9898

99-
Four Twig functions come with it:
99+
Five Twig functions come with it:
100100

101101
.. code-block:: twig
102102
@@ -124,6 +124,16 @@ Four Twig functions come with it:
124124
``reprise_entry_js_files('app')`` and ``reprise_entry_css_files('app')`` are the same lookup, minus the HTML: they
125125
return the raw URL lists, for the rare case where you need the paths rather than the tags.
126126

127+
``reprise_entry_exists('checkout')`` returns ``true`` when the named entry is present in ``entrypoints.json`` and
128+
``false`` otherwise. Use it to guard a page-specific or optional entry so rendering its tags doesn't error in strict
129+
mode:
130+
131+
.. code-block:: twig
132+
133+
{% if reprise_entry_exists('checkout') %}
134+
{{ reprise_entry_script_tags('checkout') }}
135+
{% endif %}
136+
127137
If you're migrating from Webpack Encore, it's a tag-for-tag swap (Reprise is Encore's heritage, so the template
128138
shape hasn't changed):
129139

@@ -145,6 +155,9 @@ shape hasn't changed):
145155
* - ``encore_entry_js_files('app')``
146156
- ``reprise_entry_js_files('app')``
147157
- JS URL list
158+
* - ``encore_entry_exists('app')``
159+
- ``reprise_entry_exists('app')``
160+
- ``true``/``false``
148161

149162
``reprise_entry_script_tags`` and ``reprise_entry_link_tags`` take a fourth ``attributes`` argument, merged over the
150163
global ``script_attributes``/``link_attributes`` (per-call wins, ``false`` drops the attribute). It mirrors Encore's

src/Asset/TagRenderer.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,11 @@ public function getCssFiles(string $entryName, ?string $packageName = null): arr
119119
return array_map(fn (string $r) => $this->url($r, $packageName), $this->lookup->getCssFiles($entryName));
120120
}
121121

122+
public function entryExists(string $entryName): bool
123+
{
124+
return $this->lookup->entryExists($entryName);
125+
}
126+
122127
public function reset(): void
123128
{
124129
$this->clientInjected = false;

src/Twig/AssetExtension.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ public function getFunctions(): array
3131
new TwigFunction('reprise_entry_link_tags', [AssetRuntime::class, 'renderLinkTags'], ['is_safe' => ['html']]),
3232
new TwigFunction('reprise_entry_js_files', [AssetRuntime::class, 'getJsFiles']),
3333
new TwigFunction('reprise_entry_css_files', [AssetRuntime::class, 'getCssFiles']),
34+
new TwigFunction('reprise_entry_exists', [AssetRuntime::class, 'entryExists']),
3435
];
3536
}
3637
}

src/Twig/AssetRuntime.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,4 +63,9 @@ public function getCssFiles(string $entryName, ?string $packageName = null): arr
6363
{
6464
return $this->tagRenderer->getCssFiles($entryName, $packageName);
6565
}
66+
67+
public function entryExists(string $entryName): bool
68+
{
69+
return $this->tagRenderer->entryExists($entryName);
70+
}
6671
}

tests/Asset/TagRendererTest.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
use Symfony\Component\HttpFoundation\RequestStack;
2121
use Symfony\Component\WebLink\GenericLinkProvider;
2222
use Symfony\Reprise\Asset\DevServer;
23+
use Symfony\Reprise\Asset\EntrypointsLookup;
2324
use Symfony\Reprise\Asset\EntrypointsLookupInterface;
2425
use Symfony\Reprise\Asset\TagRenderer;
2526

@@ -392,6 +393,17 @@ public function testRendersEveryStylesheetInFileOrder()
392393
);
393394
}
394395

396+
public function testEntryExistsDelegatesToTheLookup()
397+
{
398+
$renderer = new TagRenderer(
399+
new EntrypointsLookup(__DIR__.'/../fixtures/build/entrypoints.json'),
400+
new Packages(new PathPackage('/', new EmptyVersionStrategy())),
401+
);
402+
403+
$this->assertTrue($renderer->entryExists('app'));
404+
$this->assertFalse($renderer->entryExists('does-not-exist'));
405+
}
406+
395407
public function testModulepreloadHasNoIntegrityWhenTheChunkIsNotHashed()
396408
{
397409
// A preload chunk without an SRI entry (e.g. in dev) gets a bare modulepreload link.

tests/Twig/AssetExtensionTest.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use Symfony\Component\Asset\PathPackage;
1717
use Symfony\Component\Asset\VersionStrategy\EmptyVersionStrategy;
1818
use Symfony\Reprise\Asset\DevServer;
19+
use Symfony\Reprise\Asset\EntrypointsLookup;
1920
use Symfony\Reprise\Asset\EntrypointsLookupInterface;
2021
use Symfony\Reprise\Asset\TagRenderer;
2122
use Symfony\Reprise\Twig\AssetExtension;
@@ -89,6 +90,22 @@ public function testScriptTagsAcceptPerCallAttributesViaNamedArgument()
8990
);
9091
}
9192

93+
public function testEntryExistsFunctionReflectsTheLookup()
94+
{
95+
$twig = new Environment(new ArrayLoader([
96+
'page' => "{{ reprise_entry_exists('app') ? 'yes' : 'no' }}|{{ reprise_entry_exists('missing') ? 'yes' : 'no' }}",
97+
]));
98+
$twig->addExtension(new AssetExtension());
99+
$twig->addRuntimeLoader(new FactoryRuntimeLoader([
100+
AssetRuntime::class => static fn (): AssetRuntime => new AssetRuntime(new TagRenderer(
101+
new EntrypointsLookup(__DIR__.'/../fixtures/build/entrypoints.json'),
102+
new Packages(new PathPackage('/', new EmptyVersionStrategy())),
103+
)),
104+
]));
105+
106+
$this->assertSame('yes|no', $twig->render('page'));
107+
}
108+
92109
/**
93110
* @param list<string> $js
94111
* @param list<string> $css

0 commit comments

Comments
 (0)