Hosting quizzes in ActionKit
egj actionkit
It's possible to use ActionKit survey pages to host quizzes, "what type of [X] are you" games, and even web polls that display the current winning responses.
To do this, you store the "correct answers" as JSON in a custom page field, and then compare the user's provided answers with those correct answers in custom `thanks.html` template code on your after-action page. Your custom page field would look something like this:
{ "eighth_president": "Martin van Buren", "us_capital": "Washington, DC", "war_end": "1814" }
There are a few tricks involved in setting up the template code. ActionKit's `load_json` filter is used to parse the custom page field into a data structure, and the `record` tag is used to tally the user's correct answers into an empty-array variable and calculate a score. Lastly, the `nth` filter is used to pluck a value out of a dict using a key stored in a variable.
{% if page.custom_fields.interactive_quiz_responses %} {% with page.custom_fields.interactive_quiz_responses|load_json as answers %} {% with "[]"|load_json as score %} {% for question in form.surveyquestion_set.all %} {% if answers|nth:question.field_name == action.custom_fields|nth:question.field_name %} {% record question.field_name in score %} {% endif %} {% endfor %} <h3 style="margin-top: -15px; margin-bottom: 15px">Your score: {{ score|length }} out of {{ form.surveyquestion_set.all.count }}</h3> {% endwith %} {% for question in form.surveyquestion_set.all %} <div style="margin-bottom: 25px" class="span50 input-parent {{ question.question_label|slugify }}"> <label><strong>{{ question.question_label }}</strong> </label> <div>The answer was <strong>{{ answers|nth:question.field_name }}</strong>. </div><div>You were {% if answers|nth:question.field_name == action.custom_fields|nth:question.field_name %} <span style="color: green">CORRECT!</span> {% else %} <span style="color: red">wrong.</span> {% endif %} </div><div>(<em>You said: {{ action.custom_fields|nth:question.field_name }}</em>)</div> </div> {% endfor %} {% endwith %} {% endif %}
"What type of X are you" quizzes
If you want to use the user's responses to calculate a shareable result ("You're a Hufflepuff!" / "You're a Siberian tiger!") you would need to add a few layers on top of this. First, you would need to store a different JSON-ified data structure in your custom page field, with each question answer assigned to a category, and each category assigned to some descriptive output:
{"categories": { "Hufflepuff": {"image": "badger.jpg", "description": "You belong to the most inclusive among the four houses; valuing hard work, dedication, patience, loyalty, and fair play rather than a particular aptitude in its members."}, "Siberian tiger": {"image": "tiger.jpg", "description": "Also known as the Amur tiger, you inhabit mainly the Sikhote Alin mountain region with a small population in southwest Primorye Province in the Russian Far East."}, "pot of coffee": {"image": "coffee.jpg", "description": "The way you are brewed should be based on your needs and your unique coffee preferences; there’s no single right technique for everyone."} }, "answers": { "eighth_president": { "Martin van Buren": "Hufflepuff", "Andrew Jackson": "Siberian tiger", "Abraham Lincoln": "pot of coffee" }, "us_capital": { "Washington, DC": "Siberian tiger", "Albany, NY": "pot of coffee", "Boston, MA": "Hufflepuff" }, "war_end": { "1811": "Siberian tiger", "1812": "Hufflepuff", "1813": "pot of coffee", "1814": "Hufflepuff", "1815": "pot of coffee" } } }
Then, in your `thanks.html` template, you would loop over the user's responses to tally up the categories, and display different content depending on which category had the most responses.
Polls with aggregated responses
Running a web poll that displays the leading responses, or a quiz that tells you what percent of respondents got each question right, is trickier because you don't normally have access to other past responses in your templates, and especially not in a form that's convenient for this sort of reporting.
A safe and pretty maintainable approach would be to set up a cronjob that runs some SQL to tally results on the page(s) you're interested in, and then pushes that tally as JSON into a custom field on the appropriate page. Graphing those results in `thanks.html` would then be very straightforward.
You'd end up with non-real-time totals (how out of date they'd be would depend on how often you run the cronjob) but without any scaling problems, and with a lot of flexibility in what you're reporting (e.g. only top N per question, filtering out inappropriate free-form answers, etc)