Plantillas

Sintaxis de plantillas

Variables

Puedes mostrar una variable así:

Your payoff is {{ player.payoff }}.

Las siguientes variables están disponibles en las plantillas:

  • player: el jugador que actualmente está viendo la página

  • group: el grupo al que pertenece el jugador actual

  • subsession: la subsesión a la que pertenece el jugador actual

  • participant: el participante al que pertenece el jugador actual

  • session: la sesión actual

  • C

  • Cualquier variable que hayas pasado con vars_for_template().

Condiciones («if»)

Nota

oTree 3.x utilizaba dos tipos de etiquetas en las plantillas: {{ }} y {% %}. Sin embargo, a partir de oTree 5, puedes olvidarte de {% %} y usar solo {{ }} en cualquier lugar si lo deseas. El formato antiguo aún funciona.

{{ if player.is_winner }} you won! {{ endif }}

Con un “else”:

{{ if some_number >= 0 }}
    positive
{{ else }}
    negative
{{ endif }}

Ejemplo complejo:

{{ if a or b }}
    .....
{{ elif c and d }}
    .....
{{ else }}
    .....
{{ endif }}

Bucles («for»)

{{ for item in some_list }}
    {{ item }}
{{ endfor }}

Accediendo a elementos en un dict

Mientras que en el código de Python haces my_dict['foo'], en una plantilla harías {{ my_dict.foo }}.

Comentarios

{# this is a comment #}

{#
    this is a
    multiline comment
#}

Cosas que no puedes hacer

El lenguaje de plantillas es solo para mostrar valores. No puedes hacer matemáticas (+, *, /, -) ni modificar números, listas, cadenas, etc. Para eso, debes usar vars_for_template().

Cómo funcionan las plantillas: un ejemplo

Las plantillas de oTree son una mezcla de 2 lenguajes:

  • HTML (que utiliza corchetes angulares como <this> y </this>).

  • Etiquetas de plantilla (que utilizan llaves como {{ this }})

En este ejemplo, supongamos que tu plantilla se ve así:

<p>Your payoff this round was {{ player.payoff }}.</p>

{{ if subsession.round_number > 1 }}
    <p>
        Your payoff in the previous round was {{ last_round_payoff }}.
    </p>
{{ endif }}

{{ next_button }}

Paso 1: oTree escanea las etiquetas de plantilla, produce HTML (también conocido como «lado del servidor»)

oTree utiliza los valores actuales de las variables para convertir las etiquetas de plantilla anteriores en HTML simple, así:

<p>Your payoff this round was $10.</p>

    <p>
        Your payoff in the previous round was $5.
    </p>

<button class="otree-btn-next btn btn-primary">Next</button>

Paso 2: El navegador escanea las etiquetas HTML, produce una página web (también conocido como «lado del cliente»)

El servidor de oTree envía este HTML a la computadora del usuario, donde su navegador web puede leer el código y mostrarlo como una página web formateada:

_images/template-example.png

Tenga en cuenta que el navegador nunca ve las etiquetas de plantilla.

El punto clave

Si una de tus páginas no se ve como deseas, puedes aislar cuál de los pasos anteriores salió mal. En tu navegador, haz clic derecho y selecciona “ver fuente”. (Nota: “ver fuente” puede no funcionar en modo de pantalla dividida.)

Entonces podrás ver el HTML puro que se generó (junto con cualquier JavaScript o CSS).

  • Si el código HTML no se ve como esperabas, entonces algo salió mal en el lado del servidor. Busca errores en tu vars_for_template o en tus etiquetas de plantilla.

  • Si no hubo error al generar el código HTML, entonces probablemente sea un problema con la forma en que estás utilizando la sintaxis de HTML (o JavaScript). Intenta pegar la parte problemática del HTML de nuevo en una plantilla, sin las etiquetas de plantilla, y edítala hasta que produzca la salida correcta. Luego, vuelve a poner las etiquetas de plantilla para que sea dinámica de nuevo.

Imágenes (archivos estáticos)

La forma más sencilla de incluir imágenes, videos, bibliotecas de JS/CSS de terceros y otros archivos estáticos en tu proyecto es alojarlos en línea, por ejemplo, en Dropbox, Imgur, YouTube, etc.

Luego, coloca su URL en una etiqueta <img> o <video> en tu plantilla, por ejemplo:

<img src="https://i.imgur.com/gM5yeyS.jpg" width="500px" />

También puedes almacenar imágenes directamente en tu proyecto. (pero ten en cuenta que los tamaños de archivo grandes pueden afectar el rendimiento). oTree Studio tiene una herramienta de carga de imágenes. (Si estás utilizando un editor de texto, consulta aquí.) Una vez que hayas almacenado la imagen, puedes mostrarla así:

<img src="{{ static 'folder_name/puppy.jpg' }}"/>

Imágenes dinámicas

Si necesitas mostrar diferentes imágenes dependiendo del contexto (como mostrar una imagen diferente en cada ronda), puedes construirla en vars_for_template y pasarla a la plantilla, por ejemplo:

@staticmethod
def vars_for_template(player):
    return dict(
        image_path='my_app/{}.png'.format(player.round_number)
    )

Entonces en la plantilla:

<img src="{{ static image_path }}"/>

Plantillas incluibles

Si estás copiando y pegando el mismo contenido en muchas plantillas, es mejor crear una plantilla incluyible y reutilizarla con {{ include_sibling }}.

Por ejemplo, si tu juego tiene instrucciones que necesitan repetirse en cada página, crea una plantilla llamada instructions.html y coloca las instrucciones allí, por ejemplo:

<div class="card bg-light">
    <div class="card-body">

    <h3>
        Instructions
    </h3>
    <p>
        These are the instructions for the game....
    </p>
    </div>
</div>

Luego usa {{ include_sibling 'instructions.html' }} para insertarlo en cualquier lugar que desees.

Nota

{{ include_sibling }} es una nueva alternativa a {{ include }}. La ventaja es que puedes omitir el nombre de la aplicación: {{ include_sibling 'xyz.html' }} en lugar de {{ include 'my_app/xyz.html' }}. Sin embargo, si la plantilla incluyible está en una carpeta diferente, debes usar {{ include }}.

JavaScript y CSS

Dónde colocar el código JavaScript/CSS

Puedes colocar JavaScript y CSS en cualquier lugar simplemente utilizando los habituales <script></script> o <style></style>, en cualquier parte de tu plantilla.

Si tienes muchos scripts/estilos, puedes ponerlos en bloques separados fuera de content: scripts y styles. No es obligatorio hacerlo, pero: mantiene tu código organizado y asegura que las cosas se carguen en el orden correcto (CSS, luego el contenido de tu página, luego JavaScript).

Personalización del tema

Si deseas personalizar la apariencia de un elemento de oTree, aquí está la lista de selectores CSS:

Elemento

Selector CSS/jQuery

Cuerpo de la página

.otree-body

Título de la página

.otree-title

Página de espera (diálogo completo)

.otree-wait-page

Título del diálogo de la página de espera

.otree-wait-page__title (nota: __, no _)

Cuerpo del diálogo de la página de espera

.otree-wait-page__body

Temporizador

.otree-timer

Botón Siguiente

.otree-btn-next

Advertencia de errores en el formulario

.otree-form-errors

Por ejemplo, para cambiar el ancho de la página, coloca CSS en tu plantilla base así:

<style>
    .otree-body {
        max-width:800px
    }
</style>

Para obtener más información, en tu navegador, haz clic derecho en el elemento que deseas modificar y selecciona «Inspeccionar». Luego puedes navegar para ver los diferentes elementos y probar a modificar sus estilos:

_images/dom-inspector.png

Cuando sea posible, utiliza uno de los selectores oficiales anteriores. No utilices ningún selector que comience con _otree y no selecciones basándote en clases de Bootstrap como btn-primary o card, porque son inestables.

Pasando datos de Python a JavaScript (js_vars)

Para pasar datos al código JavaScript en tu plantilla, define una función js_vars en tu Página, por ejemplo:

@staticmethod
def js_vars(player):
    return dict(
        payoff=player.payoff,
    )

Entonces, en tu plantilla, puedes referirte a estas variables:

<script>
    let x = js_vars.payoff;
    // etc...
</script>

Bootstrap

oTree viene con Bootstrap, una biblioteca popular para personalizar la interfaz de usuario de un sitio web.

Puedes usarlo si deseas un estilo personalizado, o un componente específico como una tabla, alerta, barra de progreso, etiqueta, etc. Incluso puedes hacer que tu página sea dinámica con elementos como popovers, modals, y texto colapsable.

Para usar Bootstrap, generalmente agregas un atributo class= a tu elemento HTML.

Por ejemplo, el siguiente HTML creará una alerta de «Success»:

<div class="alert alert-success">Great job!</div>

Dispositivos móviles

Bootstrap intenta mostrar una versión «amigable para móviles» cuando se visualiza en un teléfono inteligente o tableta.

Gráficos

Puedes usar cualquier biblioteca HTML/JavaScript para agregar gráficos a tu aplicación. Una buena opción es HighCharts, para dibujar gráficos de pastel, gráficos de líneas, gráficos de barras, series temporales, etc.

Primero, incluye el JavaScript de HighCharts:

<script src="https://code.highcharts.com/highcharts.js"></script>

Ve al sitio de demostración de HighCharts y encuentra el tipo de gráfico que deseas crear. Luego haz clic en «editar en JSFiddle» para editarlo a tu gusto, utilizando datos codificados de forma rígida.

Luego, copia y pega el JS y el HTML en tu plantilla, y carga la página. Si no ves tu gráfico, puede ser porque tu HTML no tiene el <div> en el que tu código JS está intentando insertar el gráfico.

Una vez que tu gráfico se esté cargando correctamente, puedes reemplazar los datos codificados como series y categories con variables generadas dinámicamente.

Por ejemplo, cambia esto:

series: [{
    name: 'Tokyo',
    data: [7.0, 6.9, 9.5, 14.5, 18.2, 21.5, 25.2, 26.5, 23.3, 18.3, 13.9, 9.6]
}, {
    name: 'New York',
    data: [-0.2, 0.8, 5.7, 11.3, 17.0, 22.0, 24.8, 24.1, 20.1, 14.1, 8.6, 2.5]
}]

A esto:

series: js_vars.highcharts_series

…donde highcharts_series es una variable que definiste en js_vars.

Si tu gráfico no se carga, haz clic en «Ver fuente» en tu navegador y verifica si hay algo mal con los datos que generaste dinámicamente.

Number formatting

You can round numbers using the to2, to1, or to0 filters. For example:: {{ 0.1234|to2 }} outputs 0.12.

Nota

As of oTree 6.0 (pip install otree --upgrade --pre), there is also to3 and to4 filters.

As of oTree 6.0 (pip install otree --upgrade --pre), if you set THOUSAND_SEPARATOR = "," in settings.py, big numbers will be formatted like «1,234,567.00». You can set it to «.», « «, etc.