Skip to content

Commit

Permalink
Making the Twig "source" functions automatically disable tracking
Browse files Browse the repository at this point in the history
  • Loading branch information
weaverryan committed May 8, 2020
1 parent 9f254e9 commit 6824ca6
Show file tree
Hide file tree
Showing 8 changed files with 84 additions and 23 deletions.
54 changes: 34 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,12 +112,41 @@ not to repeat the same JavaScript or CSS file within the same request.
This prevents you from having duplicate `<link>` or `<script>` tags
if you render multiple entries that rely on the same file.

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

The easiest solution is to *disable* the "file tracking" on those
templates:
The easiest solution is to render the raw CSS and JavaScript using
a special function that *always* returns the full source, even for files
that were already rendered.

This works especially well in emails thanks to the
[inline_css](https://github.com/twigphp/cssinliner-extra) filter:

```twig
{% apply inline_css(encore_entry_css_source('my_entry')) %}
<div>
Hi! The CSS from my_entry will be converted into
inline styles on any HTML elements inside.
</div>
{% endapply %}
```

Or you can just render the source directly.

```twig
<style>
{{ encore_entry_css_source('my_entry')|raw }}
</style>
<script>
{{ encore_entry_js_source('my_entry')|raw }}
</script>
```

If you can't use these `encore_entry_*_source` functions, you can instead
manually disable and enable "file tracking":

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

You can also use this along with `inline_css` and `encore_entry_css_source()`
to automatically convert the CSS to inline styles so that your emails
or PDF doesn't require any external CSS files:

```twig
{% do encore_disable_file_tracking() %}
{% apply inline_css(encore_entry_css_source('my_entry')) %}
<div>
Hi! The CSS from my_entry will be converted into
inline styles on any HTML elements inside.
</div>
{% endapply %}
{% do encore_enable_file_tracking() %}
```

## Resetting the Entrypoint

If using `encore_disable_file_tracking()` won't work for you for some
Expand Down
2 changes: 1 addition & 1 deletion src/Asset/BuildFileLocator.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public function findFile(string $path, string $buildName = '_default'): string
$targetPath = $this->combinePaths($buildPath, $path);

if ($this->ensureFileExists && !file_exists($targetPath)) {
throw new \LogicException(sprintf('Cannot determine how to locate the "%s" file by combining with the output_path "%s"', $path, $buildPath));
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));
}

return $targetPath;
Expand Down
5 changes: 5 additions & 0 deletions src/Asset/EntrypointLookup.php
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,11 @@ public function enableReturnedFileTracking(bool $shouldTrackReturnedFiles)
$this->trackReturnedFiles = $shouldTrackReturnedFiles;
}

public function isReturnedFileTrackingEnabled(): bool
{
return $this->trackReturnedFiles;
}

private function getEntryFiles(string $entryName, string $key): array
{
$this->validateEntryName($entryName);
Expand Down
27 changes: 25 additions & 2 deletions src/Twig/EntryFilesTwigExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,18 +54,30 @@ public function getWebpackCssFiles(string $entryName, string $entrypointName = '

public function getWebpackJsSource(string $entryName, string $entrypointName = '_default'): string
{
$originalTrackingValue = $this->isReturnedFileTrackingEnabled($entrypointName);
$this->changeReturnedFileTracking(false, $entrypointName);

$files = $this->getEntrypointLookup($entrypointName)
->getJavaScriptFiles($entryName);

return $this->concatenateFileSources($files);
$source = $this->concatenateFileSources($files);
$this->changeReturnedFileTracking($originalTrackingValue, $entrypointName);

return $source;
}

public function getWebpackCssSource(string $entryName, string $entrypointName = '_default'): string
{
$originalTrackingValue = $this->isReturnedFileTrackingEnabled($entrypointName);
$this->changeReturnedFileTracking(false, $entrypointName);

$files = $this->getEntrypointLookup($entrypointName)
->getCssFiles($entryName);

return $this->concatenateFileSources($files);
$source = $this->concatenateFileSources($files);
$this->changeReturnedFileTracking($originalTrackingValue, $entrypointName);

return $source;
}

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

private function isReturnedFileTrackingEnabled(string $entrypointName): bool
{
$lookup = $this->getEntrypointLookup($entrypointName);

if (!$lookup instanceof EntrypointLookup) {
throw new \LogicException('In order to use encore_entry_js_source/encore_entry_css_source, the EntrypointLookupInterface must be an instance of EntrypointLookup.');
}

return $lookup->isReturnedFileTrackingEnabled();
}

private function concatenateFileSources(array $files): string
{
$locator = $this->getBuildFileLocator();
Expand Down
9 changes: 9 additions & 0 deletions tests/IntegrationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,15 @@ public function testTwigIntegrationWithSourceFiles()
'<h2 style="color: purple;">World!</h2>',
$html
);

$this->assertStringContainsString(
"alert('Hello file1 JavaScript!')",
$html
);
$this->assertStringContainsString(
"alert('Hello file2 JavaScript!')",
$html
);
}

public function testEntriesAreNotRepeatedWhenAlreadyOutputIntegration()
Expand Down
1 change: 1 addition & 0 deletions tests/fixtures/build/file1.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
alert('Hello file1 JavaScript!');
1 change: 1 addition & 0 deletions tests/fixtures/build/file2.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
alert('Hello file2 JavaScript!');
8 changes: 8 additions & 0 deletions tests/fixtures/inline_css_template.twig
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
{# should not affect encore_entry_css_source() below #}
{{ encore_entry_link_tags('my_entry') }}
{{ encore_entry_script_tags('my_entry') }}

{% apply inline_css(encore_entry_css_source('my_entry')) %}
<h1>Hello</h1>
<h2>World!</h2>
{% endapply %}

<script>
{{ encore_entry_js_source('my_entry')|raw }}
</script>

0 comments on commit 6824ca6

Please sign in to comment.