diff --git a/app/config/sculpin_kernel.yml b/app/config/sculpin_kernel.yml
index 0e95223e..0925d958 100644
--- a/app/config/sculpin_kernel.yml
+++ b/app/config/sculpin_kernel.yml
@@ -11,7 +11,17 @@ sculpin_content_types:
permalink: talks/:basename/
taxonomies: [tags]
+parameters:
+ asset.manifest_dir: '%sculpin.source_dir%'
+
services:
+ App\Asset\TwigExtension\EncoreExtension:
+ autowire: true
+ arguments:
+ $manifestDir: '%asset.manifest_dir%'
+ tags:
+ - { name: twig.extension }
+
App\Talk\TwigExtension\TalksExtension:
tags:
- { name: twig.extension }
diff --git a/app/src/Asset/TwigExtension/EncoreExtension.php b/app/src/Asset/TwigExtension/EncoreExtension.php
new file mode 100644
index 00000000..c5d6808b
--- /dev/null
+++ b/app/src/Asset/TwigExtension/EncoreExtension.php
@@ -0,0 +1,63 @@
+manifestDir = $manifestDir;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getName()
+ {
+ return 'app.encore';
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getFunctions()
+ {
+ return [
+ new TwigFunction('asset', [$this, 'generateAssetPaths']),
+ ];
+ }
+
+ public function generateAssetPaths(string $assetName): string
+ {
+ if (!$manifest = file_get_contents($this->manifestPath($assetName))) {
+ return $this->defaultPath($assetName);
+ }
+
+ return (new Collection(json_decode($manifest, true)))
+ ->get($assetName, $assetName);
+ }
+
+ private function manifestPath(string $assetName): string
+ {
+ return preg_replace('/(?<=\/)[\w.]+$/', 'manifest.json', $this->defaultPath($assetName)) ?? $this->defaultPath($assetName);
+ }
+
+ private function defaultPath(string $assetName): string
+ {
+ return "{$this->manifestDir}/{$assetName}";
+ }
+}
diff --git a/source/_layouts/app.html.twig b/source/_layouts/app.html.twig
index 57c09018..80725745 100644
--- a/source/_layouts/app.html.twig
+++ b/source/_layouts/app.html.twig
@@ -9,7 +9,7 @@
{% endblock %}
-
+
{% block stylesheets %}{% endblock %}
{% for size in site.apple_touch_icon_sizes %}
@@ -29,7 +29,7 @@
{% endif %}
-
+
{% block scripts %}{% endblock %}