New syntax simplifications in oTree Lite

344 views
Skip to first unread message

Chris @ oTree

unread,
Mar 2, 2021, 7:18:40 PMMar 2
to oTree help & discussion
Hello all,

Here are some new syntax simplifications I have made in oTree Lite. Like most of the other recent changes in oTree Lite, they are optional enhancements, so your existing code will still run fine. And these changes can be used in both the models.py format and the no-self format.

Easier access to participant vars


You can now replace participant.vars['foo'] with simply participant.foo

Just set the setting PARTICIPANT_FIELDS=['foo']. Same with session.vars (define SESSION_FIELDS).

Templates: {% %} vs {{ }}

Currently, oTree has 2 styles of tags in templates: {% %} and {{ }}. This syntax comes from Django. In oTree Lite, however, you can forget about {% %} and just use {{ }} everywhere. For example:

{{ if x == y }}
{{ formfields }}
{{ next_button }}
{{ endif }}

This makes oTree templates look a bit more like Handlebars.js or Mustache.js.

The main reason for this change is that the {% %} style tag is a bit of an oddity. For example, almost all text editors will auto-close "{{" without any special configuration, but auto-closing "{%" requires a special plugin. oTree doesn't need {% %}; we can infer the meaning of the tag from its contents. In fact the distinction between {% %} and {{ }} was not that clear-cut anyhow. Just using {{ }} everywhere is simpler and it's one fewer thing to learn/remember. And {% %} is also un-ergonomic to type.

If you want to make this change (not required), it's a simple find-and-replace:

{% -> {{
%} -> }}

If you're using PyCharm, you should turn off Django syntax highlighting for templates. Even regardless of this change, Django syntax highlighting is no longer accurate in oTree Lite.

Templates: {% extends %} and {% load %}

In the past, every template required these 2 lines at the top:

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

You are allowed to delete those now. (Unless you customized global/Page.html, which most people do not.)


from otree.api import *

Previously, oTree import statements looked like this:

from otree.api import (
    models,
    widgets,
    BaseConstants,
    BaseSubsession,
    BaseGroup,
    BasePlayer,
    Currency as c,
    currency_range,
)

I am changing this to simply:

from otree.api import *

Because oTree projects use the oTree APIs so much (and often don't import anything else at all), I consider the second style to be an appropriate use of "import *" and more convenient. Less visual noise and everything gets imported automatically.


Currency: cu() vs c()

Looking at the above import statements, you can see there is something a bit special with Currency: we import "Currency as c". So, "c()" was never the official name for the currency type inside oTree, but rather just the way we import it into each file. Meaning if you just do "from otree.api import *", you will get Currency() instead of c().

I wanted to add the convenient abbreviation c() into the namespace automatically, but I don't want to add a 1-letter variable name to oTree's API. It's not a good practice. So, I have added cu() as an official alias for Currency(). You can think of it as standing for 'currency units', as in 'ECU'.

Having a 1-letter variable name causes all kinds of issues related to searchability/identifiability. Plus you get unintentional name clashes, for example I have seen:

class Constants(BaseConstants):
a = 42
b = 43
c = 44
...
something = c(10)  # oops! c was overwritten to mean 44

However, you can continue to use "c"; either keep your import statements as they are now, or do:

from otree.api import *
c = Currency

if you're using oTree Studio, you can use either one.

Anyway, try these out and let me know if you run into any issues!

Chris
Reply all
Reply to author
Forward
0 new messages