Repository: Keats/tera (rust)

Issue:
Add a magical variable that dumps the context
Something like `__tera_context`.
Useful when you are not entirely what the context is, like when I'm writing templates with Hugo and I have no clue what is available.

It will need to be able to pretty print the JSON context

Pull request description:
Add magical variable that dumps current context
Closes #74 

Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3ebc403..397b2d9 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -15,6 +15,7 @@ A few breaking changes in this one
 - Added `compile_templates!` macro  to try to compile all templates and, in case of errors,
 print them and exit the process
 - Much improved error messages
+- Add a magical variable `__tera_context` that will pretty print the current context
 
 ## 0.4.1 (2016/12/07)
 
diff --git a/src/render.rs b/src/render.rs
index 4c5808a..add21c4 100644
--- a/src/render.rs
+++ b/src/render.rs
@@ -1,5 +1,6 @@
 use std::collections::{LinkedList, HashMap};
 
+use serde_json::to_string_pretty;
 use serde_json::value::{Value, to_value};
 
 use context::{ValueRender, ValueNumber, ValueTruthy, get_json_pointer};
@@ -90,6 +91,13 @@ impl<'a> Renderer<'a> {
             None => &self.context
         };
 
+        // Magical variable that just dumps the context
+        if key == "__tera_context" {
+            return Ok(to_value(
+                to_string_pretty(context).expect("Couldn't serialize context for `__tera_context`")
+            ));
+        }
+
         // small helper fn to reduce duplication code in the 3 spots in `lookup_variable` where we
         // need to actually do the variable lookup
         fn find_variable(context: &Value, key: &str, tpl_name: &str) -> Result<Value> {
@@ -391,7 +399,9 @@ impl<'a> Renderer<'a> {
             let active_namespace = match namespace.as_ref() {
                 "self" => {
                     // TODO: handle error if we don't have a namespace
-                    // This can only happen when calling {{ self:: }} outside of a macro afaik
+                    // This can (maybe) happen when calling {{ self:: }} outside of a macro
+                    // This happens when calling a macro defined in the file itself without imports
+                    // that means macros need to be put in another file to work, which seems ok
                     self.macro_namespaces
                         .last()
                         .expect("Open an issue with a template sample please (mention `self namespace macro`)!")


Test patch:
diff --git a/tests/expected/magical_variable.html b/tests/expected/magical_variable.html
new file mode 100644
index 0000000..2b4ea0a
--- /dev/null
+++ b/tests/expected/magical_variable.html
@@ -0,0 +1,55 @@
+
+
+{
+  "a_tuple": [
+    1,
+    2,
+    3
+  ],
+  "an_array_of_tuple": [
+    [
+      1,
+      2,
+      3
+    ],
+    [
+      1,
+      2,
+      3
+    ]
+  ],
+  "empty": [],
+  "friend_reviewed": true,
+  "number_reviews": 2,
+  "product": {
+    "manufacturer": "Motorala",
+    "name": "Moto G",
+    "price": 100,
+    "summary": "A phone"
+  },
+  "reviews": [
+    {
+      "paragraphs": [
+        "A",
+        "B",
+        "C"
+      ],
+      "title": "My review"
+    },
+    {
+      "paragraphs": [
+        "A",
+        "B",
+        "C"
+      ],
+      "title": "My review"
+    }
+  ],
+  "show_more": true,
+  "username": "bob"
+}
+
+
+{
+  "name": "bob"
+}
diff --git a/tests/render_ok.rs b/tests/render_ok.rs
index c3b118a..dbe33b5 100644
--- a/tests/render_ok.rs
+++ b/tests/render_ok.rs
@@ -138,3 +138,9 @@ fn test_ok_macros() {
         vec!["tests/templates/macros.html", "tests/templates/macro_included.html"]
     );
 }
+
+
+#[test]
+fn test_magical_variable_dumps_context() {
+    assert_template_ok("tests/templates/magical_variable.html", vec!["tests/templates/macros.html"]);
+}
diff --git a/tests/templates/macros.html b/tests/templates/macros.html
index bdd24f3..cd4e407 100644
--- a/tests/templates/macros.html
+++ b/tests/templates/macros.html
@@ -16,3 +16,7 @@
 {% macro include(greeting) %}
     {% include "macro_included.html" %}
 {% endmacro include %}
+
+{% macro dump(name) %}
+    {{ __tera_context }}
+{% endmacro dump %}
diff --git a/tests/templates/magical_variable.html b/tests/templates/magical_variable.html
new file mode 100644
index 0000000..bd8d41b
--- /dev/null
+++ b/tests/templates/magical_variable.html
@@ -0,0 +1,6 @@
+{% import "macros.html" as macros %}
+
+{{ __tera_context }}
+
+
+{{ macros::dump(name="bob") }}