Advanced features

These are advanced features that are mostly unsupported in oTree Studio.



If the template needs to have a different name from your page class (e.g. you are sharing the same template for multiple pages), set template_name. Example:

class Page1(Page):
    template_name = 'app_name/MyPage.html'

CSS/JS and base templates

To include the same JS/CSS in all pages of an app, make a base template for the app.

For example, if your app’s name is public_goods, create public_goods/templates/public_goods/Page.html:

{% extends "global/Page.html" %}
{% load otree %}

{% block app_styles %}
{% endblock %}

{% block app_scripts %}
{% endblock %}

Then make each template inherit from this template:

{% extends "public_goods/Page.html" %}
{% load otree %}

To include the same JS/CSS in all apps of a project, modify _templates/global/Page.html. In that file, you will find the blocks global_scripts and global_styles.

Wait pages

Custom wait page template

You can make a custom wait page template. For example, save this to your_app_name/templates/your_app_name/MyWaitPage.html:

{% extends 'otree/WaitPage.html' %}
{% load otree %}
{% block title %}{{ title_text }}{% endblock %}
{% block content %}
    {{ body_text }}
        My custom content here.
{% endblock %}

Then tell your wait page to use this template:

class MyWaitPage(WaitPage):
    template_name = 'your_app_name/MyWaitPage.html'

Then you can use vars_for_template in the usual way. Actually, the body_text and title_text attributes are just shorthand for setting vars_for_template; the following 2 code snippets are equivalent:

class MyWaitPage(WaitPage):
    body_text = "foo"
class MyWaitPage(WaitPage):
    def vars_for_template(self):
        return dict(body_text="foo")

If you want to apply your custom wait page template globally, save it to _templates/global/WaitPage.html. oTree will then automatically use it everywhere instead of the built-in wait page.

CSS and JavaScript in Wait Pages

Wait pages have the same block structure as regular pages (global_scripts, app_scripts, scripts, etc…), so you can follow the same instructions described in CSS/JS and base templates and Customizing the theme.

For example, to apply CSS to your custom wait page at _templates/global/WaitPage.html, put a block global_scripts in the template.

You can even make other custom wait pages inherit from _templates/global/WaitPage.html, just the way regular pages inherit from _templates/global/Page.html, and they can define the blocks app_scripts and scripts, etc.

Modifying an existing database

This section is more advanced and is for people who are comfortable with troubleshooting.

If your database already contains data and you want to update the structure without running resetdb (which will delete existing data), you can use Django’s migrations feature. Below is a quick summary; for full info see the Django docs here.

First, add an empty file otree_core_migrations/ in your project top-level folder.

Then, add the following line to

MIGRATION_MODULES = {'otree': 'otree_core_migrations'}

Then run:

python makemigrations otree

Then run python makemigrations my_app_name (substituting your app’s name), for each app you are working on. This will create a migrations folder in your app, which you should add to your git repo, commit, and push to your server.

Instead of using otree resetdb on the server, run python migrate (or otree migrate). If using Heroku, you would do heroku run otree migrate. This will update your database tables.

If you make further modifications to your apps or upgrade otree, you can run python makemigrations. You don’t need to specify the app names in this command; migrations will be updated for every app that has a migrations folder. Then commit, push, and run python migrate again as described above.

More info here