Repository: wagtail/wagtail

Issue:
`include_block block with context` does not include variables defined in templates
Wagtails `include_block` tag is meant to match as closely as possible Jinja2's `include` tag 
- so one would expect that when you include the context the local template variables are also includes. However the following code does not make `foo` available to the template that `block` renders:

```
{% with foo="bar" %}
        {% include_block block with context %}
{% endwith %}
```

Looks like this is because `jinja2.nodes.ContextReference()` does not currently include template defined variables (which we use in [wagtail/core/jinja2tags.py](wagtail/core/jinja2tags.py#L39) to get the context). There is an issue relating [to this on Jinja2's repo](https://github.com/pallets/jinja/issues/860).

We could provide our own Jinja2 environment with a patched `CodeGenerator` fairly easily to include template variables (the method described in the issue above does work and django is nice enough to expose a way to load custom environments).

I'd be keen to submit a PR for this - but I'm unsure if we want to ship a patched `CodeGenerator` class? If we were to do so we'd probably want to pin the Jinja2 version in Wagtail a little more tightly to avoid breakages.


Discussion:
Looks like [there is a PR open](https://github.com/pallets/jinja/pull/861) to add this functionality into the Jinja2 API... hasn't been looked at in a while though.
Just ran into this myself. Looks like [that Jinja2 PR](https://github.com/pallets/jinja/pull/861) was merged and released in Jinja 2.11.0. @jonnyscholes, if you're still up for contributing here, a PR to update Wagtail's Jinja2 `include_block` tag to support this would be most welcome!

Resolving patch:
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -44,7 +44,7 @@
     'python-dateutil>=2.2',
     'pytz>=2014.7',
     'elasticsearch>=5.0,<6.0',
-    'Jinja2>=2.8,<3.0',
+    'Jinja2>=2.11,<3.0',
     'boto3>=1.16,<1.17',
     'freezegun>=0.3.8',
     'openpyxl>=2.6.4',
diff --git a/wagtail/core/jinja2tags.py b/wagtail/core/jinja2tags.py
--- a/wagtail/core/jinja2tags.py
+++ b/wagtail/core/jinja2tags.py
@@ -37,7 +37,11 @@ def parse_include_block(self, parser):
             parser.stream.skip()
 
         if with_context:
-            args.append(jinja2.nodes.ContextReference())
+            if hasattr(jinja2.nodes, 'DerivedContextReference'):
+                # DerivedContextReference includes local variables. Introduced in Jinja 2.11
+                args.append(jinja2.nodes.DerivedContextReference())
+            else:
+                args.append(jinja2.nodes.ContextReference())
         else:
             # Actually we can just skip else branch because context arg default to None
             args.append(jinja2.nodes.Const(None))


Test patch:
diff --git a/wagtail/core/tests/test_jinja2.py b/wagtail/core/tests/test_jinja2.py
--- a/wagtail/core/tests/test_jinja2.py
+++ b/wagtail/core/tests/test_jinja2.py
@@ -182,3 +182,16 @@ def test_include_block_tag_with_filtered_value(self):
             'language': 'fr',
         })
         self.assertIn('<body>999</body>', result)
+
+    def test_include_block_tag_with_additional_variable(self):
+        """
+        The include_block tag should be able to pass local variables from parent context to the
+        child context
+        """
+        block = blocks.CharBlock(template='tests/blocks/heading_block.html')
+        bound_block = block.bind('bonjour')
+
+        result = render_to_string('tests/jinja2/include_block_tag_with_additional_variable.html', {
+            'test_block': bound_block
+        })
+        self.assertIn('<body><h1 class="important">bonjour</h1></body>', result)
diff --git a/wagtail/tests/testapp/jinja2_templates/tests/jinja2/include_block_only_test.html b/wagtail/tests/testapp/jinja2_templates/tests/jinja2/include_block_only_test.html
deleted file mode 100644
--- a/wagtail/tests/testapp/jinja2_templates/tests/jinja2/include_block_only_test.html
+++ /dev/null
@@ -1,5 +0,0 @@
-{% with classname = 'asdf' %}
-    {{ classname }}
-    {{ language }}
-    <body>{% include_block test_block with context %}</body>
-{% endwith %}
diff --git a/wagtail/tests/testapp/jinja2_templates/tests/jinja2/include_block_tag_with_additional_variable.html b/wagtail/tests/testapp/jinja2_templates/tests/jinja2/include_block_tag_with_additional_variable.html
new file mode 100644
--- /dev/null
+++ b/wagtail/tests/testapp/jinja2_templates/tests/jinja2/include_block_tag_with_additional_variable.html
@@ -0,0 +1 @@
+<body>{% with classname="important" %}{% include_block test_block with context %}{% endwith %}</body>