Skip to content

PHP Fatal error: Uncaught Twig_Error_Syntax: Unknown "asset" function

michaellenahan edited this page Jun 6, 2018 · 9 revisions

Summary

This problem relates to a Drupal 8 website using a theme theme-food, which in turn uses PatternLab.

One of PatternLab's dependencies is gulp-inject. This commit caused the compilation of our theme-food theme to fail.

The error was this:

PHP Fatal error: Uncaught Twig_Error_Syntax: Unknown "asset" function

For more context, see the Details section below.

The fix was to fix the version of gulp-inject at 4.3.1 in the theme's package.json.

Use of package-lock.json

Some have asked why we have not committed the package-lock.json file into our repository. The reason for this is that the lock is operating-system dependent - committing the lock which was generated on one operating system may break the build on another OS.

Some have suggested as a possible way forward to use yarn as an alternative to npm.

Although, here is a blog post describing how a team moved to yarn and back to npm again.

Credits

Thank you to Andre Baumeier for tracking down the root cause of this issue.

Details

During the compilation of the theme, I started getting this error, a week ago.

[20:14:34] Using gulpfile /var/www/drupalvm/src/docroot/themes/contrib/theme-food/gulpfile.js
...
[20:14:41] Starting 'inject:pl'...
[20:14:41] Starting 'inject:drupal'...
Drupal 8 support not ready yet for injecting into food.info.yml
[20:14:41] Finished 'inject:drupal' after 155 μs
[20:14:41] gulp-inject 6 files into _00-head.twig.
[20:14:41] gulp-inject 17 files into _01-foot.twig.
[20:14:41] Finished 'inject:pl' after 31 ms
[20:14:41] Starting 'pl:full'...
configuring pattern lab...
PHP Fatal error:  Uncaught Twig_Error_Syntax: Unknown "asset" function in "<!DOCTYPE html>
<html class="{{ htmlClass }}">
	<head>
		<title>{{ title }}</title>
		<meta charset="UTF-8">
		<meta name="viewport" content="width=device-width" />

		<!-- Begin Pattern Lab (Required for Pattern Lab to run properly) -->
		{{ patternLabHead | raw }}
		<!-- End Pattern Lab -->

    <!-- inject:css -->
    <link rel="stylesheet" href="{{ asset("../../../../bower_components/slick-carousel/slick/slick.css") }}">
    <link rel="stylesheet" href="{{ asset("../../../../bower_components/jquery-ui/themes/base/core.css") }}">
    <link rel="stylesheet" href="{{ asset("../../../../bower_components/jquery-ui/themes/base/theme.css") }}">
    <link rel="stylesheet" href="{{ asset("../../../../bower_components/jquery-ui/themes/base/slider.css") }}">
    <link rel="stylesheet" href="{{ asset("../../../../dest/style.css") }}">
    <link rel="stylesheet" href="{{ asset("../../../../dest/style.print.recipe.css") }}">
    <!-- endinject -->
    <link rel=" in /var/www/drupalvm/src/docroot/themes/contrib/theme-food/pattern-lab/vendor/twig/twig/lib/Twig/ExpressionParser.php on line 574

The root cause of this error was this commit to gulp-inject, which does this:

  • It transforms twig files to add the asset() function.
  • Previously it was only transforming *.html.twig files, but with this patch it started also to transform *.twig files.

We can observe this change locally by doing this:

In docroot/themes/contrib/theme-food/package.json add the line "gulp": "gulp", directly under scripts:

diff --git a/package.json b/package.json
index 1b6a316..29017ea 100644
--- a/package.json
+++ b/package.json
@@ -16,6 +16,7 @@
     "prototyping"
   ],
   "scripts": {
+    "gulp": "gulp",
     "start": "gulp clean && gulp compile && gulp",
     "compile": "gulp clean && gulp compile",
     "test": "gulp validate",

This allows you to run:

$ npm run gulp -- compile

You will see gulp-inject amending _00-head.twig and _01-foot.twig

When you run:

$ git diff

You can see the amendments that have been made to these two files:

  • css has been injected into src/docroot/themes/contrib/theme-food/source/_meta/_00-head.twig
  • js has been injected into src/docroot/themes/contrib/theme-food/source/_meta/_01-foot.twig

vagrant@dkr-2018-04-05:/var/www/drupalvm/src/docroot/themes/contrib/theme-food$ npm ls gulp-inject PatternLabStarter@8.0.0 /var/www/drupalvm/src/docroot/themes/contrib/theme-food -- p2-theme-core@8.2.1 -- gulp-inject@4.3.2

My fix is to set the version of gulp-inject to exactly 4.3.1 in theme-food/package.json

--- a/package.json
+++ b/package.json
@@ -29,6 +30,7 @@
     "breakpoint-sass": "^2.7.0",
     "gulp": "^3.9.1",
     "gulp-help": "^1.6.1",
+    "gulp-inject": "4.3.1",
     "gulp-newer": "^1.2.0",
     "js-yaml": "^3.6.0",
     "lodash.merge": "^4.3.5",

Now, when I run npm install once again, I will get the version of gulp-inject I specified in my package.json:

$ npm install

... once npm install has run, I can check the installed version of gulp-inject:

$ npm ls gulp-inject
PatternLabStarter@8.0.0 /var/www/drupalvm/src/docroot/themes/contrib/theme-food
+-- gulp-inject@4.3.1
`-- p2-theme-core@8.2.1
  `-- gulp-inject@4.3.1  deduped

Now, I can run $ npm run gulp -- compile once more.

$ npm run gulp -- compile

The theme now compiles:

vagrant@dkr-2018-04-05:/var/www/drupalvm/src/docroot/themes/contrib/theme-food$ npm run gulp -- compile

> PatternLabStarter@8.0.0 gulp /var/www/drupalvm/src/docroot/themes/contrib/theme-food
> gulp "compile"

[08:26:29] Using gulpfile /var/www/drupalvm/src/docroot/themes/contrib/theme-food/gulpfile.js
...
[08:26:36] Starting 'inject:pl'...
[08:26:36] Starting 'inject:drupal'...
Drupal 8 support not ready yet for injecting into food.info.yml
[08:26:36] Finished 'inject:drupal' after 164 μs
[08:26:36] gulp-inject 6 files into _00-head.twig.
[08:26:36] gulp-inject 17 files into _01-foot.twig.
[08:26:36] Finished 'inject:pl' after 33 ms
[08:26:36] Starting 'pl:full'...
configuring pattern lab...
your site has been generated...
site generation took 11.429003953934 seconds and used 137.55MB of memory...
may the sun shine, all day long...
[08:26:47] Finished 'pl:full' after 12 s
[08:26:47] Starting 'compile'...
[08:26:47] Finished 'compile' after 8.15 μs

... and running git diff now does not show any changes to twig files:

vagrant@dkr-2018-04-05:/var/www/drupalvm/src/docroot/themes/contrib/theme-food$ git diff
diff --git a/package.json b/package.json
index 1b6a316..6370f8a 100644
--- a/package.json
+++ b/package.json
@@ -16,6 +16,7 @@
     "prototyping"
   ],
   "scripts": {
+    "gulp": "gulp",
     "start": "gulp clean && gulp compile && gulp",
     "compile": "gulp clean && gulp compile",
     "test": "gulp validate",
@@ -29,6 +30,7 @@
     "breakpoint-sass": "^2.7.0",
     "gulp": "^3.9.1",
     "gulp-help": "^1.6.1",
+    "gulp-inject": "4.3.1",
     "gulp-newer": "^1.2.0",
     "js-yaml": "^3.6.0",
     "lodash.merge": "^4.3.5",

So, all that's left now is to remove the "gulp": "gulp", line, which I only had for debugging purposes, and to commit the package.json file with the fixed version of gulp-inject.