Skip to content

Commit 6824ca6

Browse files
committed
Making the Twig "source" functions automatically disable tracking
1 parent 9f254e9 commit 6824ca6

File tree

8 files changed

+84
-23
lines changed

8 files changed

+84
-23
lines changed

README.md

Lines changed: 34 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -112,12 +112,41 @@ not to repeat the same JavaScript or CSS file within the same request.
112112
This prevents you from having duplicate `<link>` or `<script>` tags
113113
if you render multiple entries that rely on the same file.
114114

115-
In some cases, however, you may want to render the script & link
116-
tags for the same entry multiple times in a request - for example
117-
when rendering Twig templates for a PDF or for an email.
115+
But if you're purposely rendering multiple templates in the same
116+
request - e.g. rendering a template for a PDF or to send an email -
117+
then this can cause problems: the later templates won't include any
118+
`<link>` or `<script>` tags that were rendered in an earlier template.
118119

119-
The easiest solution is to *disable* the "file tracking" on those
120-
templates:
120+
The easiest solution is to render the raw CSS and JavaScript using
121+
a special function that *always* returns the full source, even for files
122+
that were already rendered.
123+
124+
This works especially well in emails thanks to the
125+
[inline_css](https://github.com/twigphp/cssinliner-extra) filter:
126+
127+
```twig
128+
{% apply inline_css(encore_entry_css_source('my_entry')) %}
129+
<div>
130+
Hi! The CSS from my_entry will be converted into
131+
inline styles on any HTML elements inside.
132+
</div>
133+
{% endapply %}
134+
```
135+
136+
Or you can just render the source directly.
137+
138+
```twig
139+
<style>
140+
{{ encore_entry_css_source('my_entry')|raw }}
141+
</style>
142+
143+
<script>
144+
{{ encore_entry_js_source('my_entry')|raw }}
145+
</script>
146+
```
147+
148+
If you can't use these `encore_entry_*_source` functions, you can instead
149+
manually disable and enable "file tracking":
121150

122151
```twig
123152
{# some template that renders a PDF or an email #}
@@ -131,21 +160,6 @@ templates:
131160
With this, *all* JS and CSS files for `entry1` will be rendered and
132161
this won't affect any other Twig templates rendered in the request.
133162

134-
You can also use this along with `inline_css` and `encore_entry_css_source()`
135-
to automatically convert the CSS to inline styles so that your emails
136-
or PDF doesn't require any external CSS files:
137-
138-
```twig
139-
{% do encore_disable_file_tracking() %}
140-
{% apply inline_css(encore_entry_css_source('my_entry')) %}
141-
<div>
142-
Hi! The CSS from my_entry will be converted into
143-
inline styles on any HTML elements inside.
144-
</div>
145-
{% endapply %}
146-
{% do encore_enable_file_tracking() %}
147-
```
148-
149163
## Resetting the Entrypoint
150164

151165
If using `encore_disable_file_tracking()` won't work for you for some

src/Asset/BuildFileLocator.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ public function findFile(string $path, string $buildName = '_default'): string
3737
$targetPath = $this->combinePaths($buildPath, $path);
3838

3939
if ($this->ensureFileExists && !file_exists($targetPath)) {
40-
throw new \LogicException(sprintf('Cannot determine how to locate the "%s" file by combining with the output_path "%s"', $path, $buildPath));
40+
throw new \LogicException(sprintf('Cannot determine how to locate the "%s" file by combining with the output_path "%s". Looked in "%s".', $path, $buildPath, $targetPath));
4141
}
4242

4343
return $targetPath;

src/Asset/EntrypointLookup.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,11 @@ public function enableReturnedFileTracking(bool $shouldTrackReturnedFiles)
8484
$this->trackReturnedFiles = $shouldTrackReturnedFiles;
8585
}
8686

87+
public function isReturnedFileTrackingEnabled(): bool
88+
{
89+
return $this->trackReturnedFiles;
90+
}
91+
8792
private function getEntryFiles(string $entryName, string $key): array
8893
{
8994
$this->validateEntryName($entryName);

src/Twig/EntryFilesTwigExtension.php

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,18 +54,30 @@ public function getWebpackCssFiles(string $entryName, string $entrypointName = '
5454

5555
public function getWebpackJsSource(string $entryName, string $entrypointName = '_default'): string
5656
{
57+
$originalTrackingValue = $this->isReturnedFileTrackingEnabled($entrypointName);
58+
$this->changeReturnedFileTracking(false, $entrypointName);
59+
5760
$files = $this->getEntrypointLookup($entrypointName)
5861
->getJavaScriptFiles($entryName);
5962

60-
return $this->concatenateFileSources($files);
63+
$source = $this->concatenateFileSources($files);
64+
$this->changeReturnedFileTracking($originalTrackingValue, $entrypointName);
65+
66+
return $source;
6167
}
6268

6369
public function getWebpackCssSource(string $entryName, string $entrypointName = '_default'): string
6470
{
71+
$originalTrackingValue = $this->isReturnedFileTrackingEnabled($entrypointName);
72+
$this->changeReturnedFileTracking(false, $entrypointName);
73+
6574
$files = $this->getEntrypointLookup($entrypointName)
6675
->getCssFiles($entryName);
6776

68-
return $this->concatenateFileSources($files);
77+
$source = $this->concatenateFileSources($files);
78+
$this->changeReturnedFileTracking($originalTrackingValue, $entrypointName);
79+
80+
return $source;
6981
}
7082

7183
public function renderWebpackScriptTags(string $entryName, string $packageName = null, string $entrypointName = '_default'): string
@@ -101,6 +113,17 @@ private function changeReturnedFileTracking(bool $isEnabled, string $entrypointN
101113
$lookup->enableReturnedFileTracking($isEnabled);
102114
}
103115

116+
private function isReturnedFileTrackingEnabled(string $entrypointName): bool
117+
{
118+
$lookup = $this->getEntrypointLookup($entrypointName);
119+
120+
if (!$lookup instanceof EntrypointLookup) {
121+
throw new \LogicException('In order to use encore_entry_js_source/encore_entry_css_source, the EntrypointLookupInterface must be an instance of EntrypointLookup.');
122+
}
123+
124+
return $lookup->isReturnedFileTrackingEnabled();
125+
}
126+
104127
private function concatenateFileSources(array $files): string
105128
{
106129
$locator = $this->getBuildFileLocator();

tests/IntegrationTest.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,15 @@ public function testTwigIntegrationWithSourceFiles()
102102
'<h2 style="color: purple;">World!</h2>',
103103
$html
104104
);
105+
106+
$this->assertStringContainsString(
107+
"alert('Hello file1 JavaScript!')",
108+
$html
109+
);
110+
$this->assertStringContainsString(
111+
"alert('Hello file2 JavaScript!')",
112+
$html
113+
);
105114
}
106115

107116
public function testEntriesAreNotRepeatedWhenAlreadyOutputIntegration()

tests/fixtures/build/file1.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
alert('Hello file1 JavaScript!');

tests/fixtures/build/file2.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
alert('Hello file2 JavaScript!');
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,12 @@
1+
{# should not affect encore_entry_css_source() below #}
2+
{{ encore_entry_link_tags('my_entry') }}
3+
{{ encore_entry_script_tags('my_entry') }}
4+
15
{% apply inline_css(encore_entry_css_source('my_entry')) %}
26
<h1>Hello</h1>
37
<h2>World!</h2>
48
{% endapply %}
9+
10+
<script>
11+
{{ encore_entry_js_source('my_entry')|raw }}
12+
</script>

0 commit comments

Comments
 (0)