Repository: twigphp/Twig (php)

Issue:
 'ignore missing' does not ignore missing templates
This appears like it might well be a Twig bug, on my local, using the version on my branch (v1.38.4 ) adding a made up template to the homepage:

{% set x = 'bad' %}
{% embed x ~ 'ger.twig' ignore missing %}
{% endembed %}

Does not error, removing 'ignore missing' causes it to error…

Upgrading twig/twig (v1.38.4 => v1.42.1)

At which point the ignore missing directive appears to no longer work and the above test fails 

Twig\Error\LoaderError thrown with message "Unable to find template



Pull request:
Fix 'ignore missing' when used on an 'embed' tag
Closes #3085

Patch:
diff --git a/CHANGELOG b/CHANGELOG
index 70838965..4d0616ce 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,5 +1,6 @@
 # 3.15.0 (2024-XX-XX)
 
+ * Fix "ignore missing" when used on an "embed" tag
  * Fix the possibility to override an aliased block (via use)
  * Add template cache hot reload
  * Allow Twig callable argument names to be free-form (snake-case or camelCase) independently of the PHP callable signature
diff --git a/src/Node/EmbedNode.php b/src/Node/EmbedNode.php
index 4cd3b38f..597f95e4 100644
--- a/src/Node/EmbedNode.php
+++ b/src/Node/EmbedNode.php
@@ -33,10 +33,10 @@ class EmbedNode extends IncludeNode
         $this->setAttribute('index', $index);
     }
 
-    protected function addGetTemplate(Compiler $compiler): void
+    protected function addGetTemplate(Compiler $compiler, string $template = ''): void
     {
         $compiler
-            ->write('$this->loadTemplate(')
+            ->raw('$this->loadTemplate(')
             ->string($this->getAttribute('name'))
             ->raw(', ')
             ->repr($this->getTemplateName())
@@ -46,5 +46,11 @@ class EmbedNode extends IncludeNode
             ->string($this->getAttribute('index'))
             ->raw(')')
         ;
+        if ($this->getAttribute('ignore_missing')) {
+            $compiler
+                ->raw(";\n")
+                ->write(\sprintf("\$%s->getParent(\$context);\n", $template))
+            ;
+        }
     }
 }
diff --git a/src/Node/IncludeNode.php b/src/Node/IncludeNode.php
index 1c18292c..33267170 100644
--- a/src/Node/IncludeNode.php
+++ b/src/Node/IncludeNode.php
@@ -48,7 +48,7 @@ class IncludeNode extends Node implements NodeOutputInterface
                 ->write(\sprintf('$%s = ', $template))
             ;
 
-            $this->addGetTemplate($compiler);
+            $this->addGetTemplate($compiler, $template);
 
             $compiler
                 ->raw(";\n")
@@ -56,6 +56,7 @@ class IncludeNode extends Node implements NodeOutputInterface
                 ->write("} catch (LoaderError \$e) {\n")
                 ->indent()
                 ->write("// ignore missing template\n")
+                ->write(\sprintf("\$$template = null;\n", $template))
                 ->outdent()
                 ->write("}\n")
                 ->write(\sprintf("if ($%s) {\n", $template))
@@ -78,10 +79,10 @@ class IncludeNode extends Node implements NodeOutputInterface
         }
     }
 
-    protected function addGetTemplate(Compiler $compiler)
+    protected function addGetTemplate(Compiler $compiler/* , string $template = '' */)
     {
         $compiler
-            ->write('$this->loadTemplate(')
+            ->raw('$this->loadTemplate(')
             ->subcompile($this->getNode('expr'))
             ->raw(', ')
             ->repr($this->getTemplateName())


Test patch:
diff --git a/tests/Fixtures/tags/embed/embed_ignore_missing.test b/tests/Fixtures/tags/embed/embed_ignore_missing.test
new file mode 100644
index 00000000..f6f27a10
--- /dev/null
+++ b/tests/Fixtures/tags/embed/embed_ignore_missing.test
@@ -0,0 +1,10 @@
+--TEST--
+"embed" tag
+--TEMPLATE--
+{% set x = 'bad' %}
+{% embed x ~ 'ger.twig' ignore missing %}{% endembed %}
+HERE
+--DATA--
+return []
+--EXPECT--
+HERE
diff --git a/tests/Node/IncludeTest.php b/tests/Node/IncludeTest.php
index b4851005..e0c23cd6 100644
--- a/tests/Node/IncludeTest.php
+++ b/tests/Node/IncludeTest.php
@@ -80,9 +80,10 @@ EOF
 // line 1
 \$__internal_%s = null;
 try {
-    \$__internal_%s =     \$this->loadTemplate("foo.twig", null, 1);
+    \$__internal_%s = \$this->loadTemplate("foo.twig", null, 1);
 } catch (LoaderError \$e) {
     // ignore missing template
+    \$__internal_%s = null;
 }
 if (\$__internal_%s) {
     yield from \$__internal_%s->unwrap()->yield(CoreExtension::toArray(["foo" => true]));