Skip to content

Commit

Permalink
Add doc
Browse files Browse the repository at this point in the history
  • Loading branch information
lcharette committed Jan 5, 2022
1 parent bbffb35 commit f399fe8
Showing 1 changed file with 133 additions and 2 deletions.
135 changes: 133 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,148 @@

Webpack Encore Standalone Twig Functions. Allows usage of Webpack Encore in Twig Templates without Symfony. Optimized for PHP-DI style containers.

This allows you to use the `splitEntryChunks()` and `enableVersioning()` features from Webpack Encore by reading the `entrypoints.json` and `manifest.json` files.

## Installation
```
composer require lcharette/webpack-encore-twig
```

## Documentation & Usage

(TODO)
Whenever you run [Encore](https://symfony.com/doc/current/frontend.html), two configuration files are generated in your output folder (default location: `public/build/`): `entrypoints.json` and `manifest.json`. Each file is similar, and contains a map to the final, versioned filenames.

The first file – `entrypoints.json` – is generated when the [`splitEntryChunks()`](https://symfony.com/doc/current/frontend/encore/split-chunks.html) option is defined in your `webpack.config.js` and will be read by the `encore_entry_script_tags()` and `encore_entry_link_tags()` Twig helpers this package provides. If you're using these, then your CSS and JavaScript files will render with the new, versioned filename.

The second file - `manifest.json` - is generated when [Asset Versioning](https://symfony.com/doc/current/frontend/encore/versioning.html#load-manifest-files) option (`enableVersioning()`) is defined in your `webpack.config.js` and will be read to get the versioned filename of _other_ files, like font files or image files (though it also contains information about the CSS and JavaScript files).

Both features (`splitEntryChunks()` and `enableVersioning()`) are defined as two separate Twig Extensions (`EntrypointsTwigExtension` and `VersionedAssetsTwigExtension` respectively) in case you need/want to enable only one of the two.

### `splitEntryChunks` and `entrypoints.json`

Encore writes an `entrypoints.json` file that contains all of the files needed for each "entry". To reference entries in Twig, you need to add the `EntrypointsTwigExtension` extension to the Twig Environment. This accept `EntrypointLookup`, which itself accept the path to the `entrypoints.json`, and the `TagRenderer` (which itself accept `EntrypointLookup`).

```php
use Lcharette\WebpackEncoreTwig\EntrypointsTwigExtension;
use Lcharette\WebpackEncoreTwig\TagRenderer;
use Symfony\WebpackEncoreBundle\Asset\EntrypointLookup;
use Twig\Environment;
use Twig\Loader\FilesystemLoader;

$entryPoints = new EntrypointLookup('./path/to/entrypoints.json');
$tagRenderer = new TagRenderer($entryPoints);
$extension = new EntrypointsTwigExtension($entryPoints, $tagRenderer);

// Create Twig Environment and add extension
$loader = new FilesystemLoader('./path/to/templates');
$twig = new Environment($loader);
$twig->addExtension($extension);
```

> When using a PSR Dependency Injection Container with autowiring, like [PHP-DI](https://php-di.org), you can define `EntrypointLookup` in your [definition factory](https://php-di.org/doc/php-definitions.html#factories) and simply inject `EntrypointsTwigExtension` into your class.
Now, to render all of the `script` and `link` tags for a specific "entry" (e.g. `entry1`), you can:

```twig
{# any template or base layout where you need to include a JavaScript entry #}
{% block javascripts %}
{{ parent() }}
{{ encore_entry_script_tags('entry1') }}
{# or render a custom attribute #}
{#
{{ encore_entry_script_tags('entry1', attributes={
defer: true
}) }}
#}
{% endblock %}
{% block stylesheets %}
{{ parent() }}
{{ encore_entry_link_tags('entry1') }}
{% endblock %}
```

If you want more control, you can use the `encore_entry_js_files()` and `encore_entry_css_files()` methods to get the list of files needed, then loop and create the `script` and `link` tags manually.

#### Custom Attributes on script and link Tags

Custom attributes can be added to rendered `script` or `link` in 3 different ways:

1. Via global config, using the `defaultAttributes` argument on the TagRenderer constructor, or using the setter method:
```
$tagRenderer->setDefaultAttributes(['crossorigin' => 'anonymous']);
```

## Other Documents
1. Via specific _script_ or _link_ argument on the TagRenderer constructor, or using the setter method:
```
$tagRenderer->setDefaultScriptAttributes(['defer' => null]);
$tagRenderer->setDefaultLinkAttributes(['hreflang' => 'en']);
```

1. When rendering in Twig - see the `attributes` option in the docs above.


### `enableVersioning` and `manifest.json`

To read the manifest file to be able to link (e.g. via an `img` tag) to certain assets, you need to add the `VersionedAssetsTwigExtension` extension to the Twig Environment. This accept `JsonManifest`, which itself accept the path to the `manifest.json`.

```php
use Lcharette\WebpackEncoreTwig\JsonManifest;
use Lcharette\WebpackEncoreTwig\VersionedAssetsTwigExtension;
use Twig\Environment;
use Twig\Loader\FilesystemLoader;

$manifest = new JsonManifest('./path/to/manifest.json');
$extension = new VersionedAssetsTwigExtension($manifest);

// Create dumb Twig and test adding extension
$loader = new FilesystemLoader();
$twig = new Environment($loader);
$twig->addExtension($extension);
```

In your Twig template, just wrap each path in the Twig `asset()` function like normal:

```twig
<img src="{{ asset('build/images/logo.png') }}" alt="ACME logo">
```

### Using Without Twig

Both script and link tags can be generated in vanilla PHP and without Twig using the underlying public methods on the `TagRenderer` class:

**Getting script and link tag from `entrypoints.json`:**
```php
$entryPoints = new EntrypointLookup('./path/to/entrypoints.json');
$tagRenderer = new TagRenderer($entryPoints);

// Returns the tags as string
$scriptsString = $tagRenderer->renderWebpackScriptTags('entry1');
$linksString = $tagRenderer->renderWebpackLinkTags('entry1');

// Returns the list of files as an array of strings
$jsFiles = $tagRenderer->getJavaScriptFiles('entry1');
$cssFiles = $tagRenderer->getCssFiles('entry1');
```

Same goes for the versioned assets, using the underlying public methods on the `JsonManifest` class:

**Getting versioned from `manifest.json`:**
```php
$manifest = new JsonManifest('./path/to/manifest.json');
$path = $manifest->applyVersion('build/images/logo.png');
```

## See Also
- [Changelog](CHANGELOG.md)
- [License](LICENSE)
- [Style Guide](.github/STYLE-GUIDE.md)
- [Testing](.github/RUNNING_TESTS.md)

## References
- https://symfony.com/doc/current/frontend.html
- https://github.com/symfony/webpack-encore-bundle

0 comments on commit f399fe8

Please sign in to comment.