Reusable code snippets in ActionKit templates
egj actionkit
(5/12/2016) UPDATE: We Also Walk Dogs just released a built-in "Make Your Own Templates" feature which makes this a lot cleaner. Instead of overriding `wrapper.html` with a giant switch-case, you can now just create a new template for each custom snippet and include that template directly.
It's still worth setting up a dedicated "snippets" templateset for this, though -- that will keep your code more organized and easier to reuse across templatesets, and can also be used as the basis for cleanly overriding snippets in particular templatesets or even running A/B tests on them.
It turns out there's a pretty straightforward built-in way to do this. The trick is that you can use a template from one templateset in another set. Between this and Django's built-in include-with syntax, we have everything we need to define and use custom snippets or partials.
To set this up, first create a new templateset. I'll call it "snippets" but this can be anything you want. This templateset won't ever be used directly by pages. Instead we'll use its wrapper template as our "snippet library" and will include that template when we want to invoke a partial.
So, open up the new wrapper.html template in your snippets templateset and delete everything. In place of the built-in code, just set up an `{% if %}` block that looks at the value of a "snippet" variable in the template context, with one `{% elif %}` for each new snippet you want to create -- basically a big switch statement:
<pre> {% if snippet == "custom_heading" %} <div><h3>Take action!</h3></div> {% elif snippet == "embedded_video" %} {% if page.custom_fields.embedded_video_url %} <iframe src="{{ page.custom_fields.embedded_video_url"></iframe> {% endif %} {% endif %} </pre>
Then in your "real" templatesets, you can just include these to use a snippet:
<pre> {% include "snippets/wrapper.html" with snippet="custom_heading" %} </pre>
Note that your snippets will have access to the same template context as the templates that include them, so they can make use of `page`, `args`, `user`, and so on in the same way you normally would.
You can also include snippets with extra custom variables in their context. This can help with reuse when you have multiple code blocks that are similar, but not quite the same, for example identical markup but different text depending on whether you're using a signup or a petition page:
<pre> # in snippets/wrapper.html {% elif snippet == "fancy_submit_button" %} <div class="fancy-submit-button"><input type="submit" value="{{ submit_button_text }}"></div> # in My Template Set/signup.html {% include "snippets/wrapper.html" with snippet="fancy_submit_button" submit_button_text="Join us" %} # in My Template Set/petition.html {% include "snippets/wrapper.html" with snippet="fancy_submit_button" submit_button_text="Add your name" %} </pre>