Templates

Polaris uses Django’s template system for defining the UI content rendered to users, and these templates can be written in a way that allows others to override or extend them. Specifically, Polaris’ templates have the following inheritance structure:

  • templates/polaris/base.html
    • templates/polaris/deposit.html

    • templates/polaris/withdraw.html

    • templates/polaris/more_info.html

base.html defines the top-level HTML tags like html, body, and head, while each of the four other templates extend the file and override the content block, among others. deposit.html and withdraw.html are very similar and are used for pages that display forms. more_info.html simply displays transaction details.

Template Extensions

In order to override or extend a Polaris Template, anchors must create a file with the same path and name of the file its replacing. Once created, the anchor can override any block tag defined in the template (or it’s parent templates).

Polaris provides two block tags that are intentionally left empty for anchors to extend: extra_head and extra_body. You are also allowed to extend any of the blocks actually implemented by Polaris, such as header, content, and footer. Note that header contains extra_header.

For example, the SDF’s reference server extends base.html by creating an HTML file within the app’s templates/polaris directory. In the file, we declare the template we are extending, load any django-provided templates tools such as static, and define an extra_body block:

{% extends "polaris/base.html" %} {% load static %} {% load i18n %}

{% trans "Confirm Email" as ce %}

{% block extra_body %}

    <script src="https://www.googletagmanager.com/gtag/js?id=UA-53373928-6" async></script>
    <script src="{% static 'sep24_scripts/google_analytics.js' %}"></script>

    {% if not form is not None and title != ce %}
        <script src="{% static 'sep24_scripts/check_email_confirmation.js' %}"></script>
    {% endif %}

{% endblock %}

The extra_body block adds <script> tags for a Google Analytics and a local script within the app’s static directory that requests the email confirmation status of the user on page focus, improving UX. If you’re unfamiliar with the syntax of Django’s templates, check out the template syntax documentation and particularly the block documentation. The extra_head template block is ideal for linking anchor-defined CSS files or other resources that must load before the page is displayed.

Note that the content rendered within extra_body and extra_head is in addition to the content defined by Polaris’ templates. If you wish to replace a template completely, create a file with the same relative path from the templates directory but do not use the extend keyword. Instead, simply write a Django template that does not extend one defined by Polaris.

Template Contexts

Whenever a template is rendered and displayed to the user, its rendered using a context, which is a Python dictionary containing key-value pairs that can be used to alter the content rendered. Polaris has an integration function that allows anchors to add key-value pairs to the context used whenever a template is about to be rendered.

polaris.integrations.DepositIntegration.content_for_template(self, request: rest_framework.request.Request, template: polaris.templates.Template, form: Optional[django.forms.forms.Form] = None, transaction: Optional[polaris.models.Transaction] = None, *args: List, **kwargs: Dict) Optional[Dict]

Return a dictionary containing the Django template variables to be passed to the template rendered.

The anchor may also pass a special key, template_name, which should be a file path relative your Django app’s /templates directory. Polaris will render the template specified by this key to the user instead of the default templates defined below. Note that all of the Django template variables defined below will still be passed to the template specified.

Polaris will pass one of the following polaris.templates.Template values to indicate the default template Polaris will use.

Template.DEPOSIT

The template used for deposit flows

Template.WITHDRAW

The template used for withdraw flows

Template.MORE_INFO

The template used to show transaction details

The form parameter will always be None when template is Template.MORE_INFO since that page does not display form content.

If form is None and template_name is not Template.MORE_INFO, returning None will signal to Polaris that the anchor is done collecting information for the transaction. Returning content will signal to Polaris that the user needs to take some action before receiving the next form, such as confirming their email. In this case, make sure to return an appropriate guidance message or return a custom template_name.

Using this function, anchors pass key-value pairs to the template being rendered. Some of these key-value pairs are used by Polaris, but anchors are allowed and encouraged to extend Polaris’ templates and pass custom key-value pairs.

def content_for_template(template_name, form=None, transaction=None):
    ...
    return {
        "title": "Deposit Transaction Form",
        "guidance": "Please enter the amount you would like to deposit.",
        "show_fee_table": True,
        "symbol": "$",
        "icon_label": "Stellar Development Foundation",
        "icon_path": "images/company-icon.png",
        # custom field passed by the anchor
        "username": "John.Doe"
    }

Below are all the keys passed to the template rendered. If the dictionary returned has the same key, the default value Polaris uses will be overwritten.

For Template.DEPOSIT and Template.WITHDRAW:

form

The django.forms.Form instance returned from form_for_transaction().

post_url

The URL to make the POST request containing the form data to.

operation

Either deposit or withdraw.

asset

The polaris.models.Asset object of the Stellar asset being transacted.

use_fee_endpoint

A boolean indicating whether or not Polaris should use the GET /fee endpoint when calculating fees and rendering the amounts on the page.

org_logo_url

A URL for the default logo to render if the anchor has not specified their own via icon_path.

additive_fees_enabled

A boolean indicating whether or not to add fees to the amount entered in TransactionForm amount fields. False by default, meaning fees are subtracted from the amounts entered.

title

The browser tab’s title.

guidance

A text message displayed on the page that should help guide the user to take the appropriate action(s).

icon_label

The label for the image rendered on the page specified by "icon_path".

icon_path

The relative file path to the image you would like to use as the company icon in the UI. The file path should be relative to your Django app’s /static directory. If icon_path is not present, Polaris will use the image specified by your TOML integration function’s ORG_LOGO key. If neither are present, Polaris will use its default image. All images will be rendered in a 100 x 150px sized box as defined by the default stylesheet.

show_fee_table

A boolean for whether the fee table in the default template should be visible on the page rendered to the user. This table is hidden by default unless a TransactionForm is returned from form_for_transaction(), in which case the fee table will be displayed. If the anchor instructs Polaris to display the fee table but a TransactionForm is not present on the page, the anchor is responsible for updating the fee table with the appropriate values. This is useful when the anchor is collecting the amount of an off-chain asset, since TransactionForm assumes the amount collected is for an on-chain asset.

symbol

The character string that precedes the amounts shown on the fee table. It defaults to the Stellar Asset.symbol. Note that the symbol used in input fields must be passed separately using the field’s widget attributes.

For Template.MORE_INFO

tx_json

A JSON-serialized string matching the schema returned from GET /transaction

amount_in_asset

The string representation of the asset given to the anchor by the user, formatted using SEP-38 Asset Identification Format.

amount_out_asset

The string representation of the asset sent from the anchor to the user, formatted using SEP-38 Asset Identification Format.

amount_in

A string containing the amount to be displayed on the page as Amount Sent

amount_out

A string containing the amount to be displayed on the page as Amount Received

amount_fee

A string containing the amount to be displayed on the page as Fee

amount_in_symbol

Asset.symbol or OffChainAsset.symbol, depending on whether or not asset sent to the anchor is on or off chain. If Transaction.quote is null, the value will always match Asset.symbol.

amount_fee_symbol

Asset.symbol or OffChainAsset.symbol, depending on the value of Transaction.fee_asset. If Transaction.quote is null, the value will always be Asset.symbol.

amount_out_symbol

Asset.symbol or OffChainAsset.symbol, depending on whether or not asset sent by the anchor is on or off chain. If Transaction.quote is null, the value will always match Asset.symbol.

amount_in_significant_decimals

The number of decimals to display for amounts of Transaction.amount_in. Derived from Asset.significant_decimals or OffChainAsset.decimals. If Transaction.quote is null, the value will always match Asset.significant_decimals.

amount_fee_significant_decimals

The number of decimals to display for amounts of Transaction.amount_fee. Derived from Asset.significant_decimals or OffChainAsset.decimals, depending on the value of Transaction.fee_asset.

amount_out_significant_decimals

The number of decimals to display for amounts of Transaction.amount_out. Derived from Asset.significant_decimals or OffChainAsset.decimals. If Transaction.quote is null, the value will always match Asset.significant_decimals.

transaction

The polaris.models.Transaction object representing the transaction.

asset

The polaris.models.Asset object representing the asset.

offchain_asset

The OffChainAsset object used in the Transaction.quote, if present.

price

Transaction.quote.price, if present.

price_inversion

1 / Transaction.quote.price, if price is present. The default more_info.html template uses this number for displaying exchange rates when quotes are used.

price_inversion_significant_decimals

The number of decimals to display for exchange rates. Polaris calculates this to ensure the rate displayed is always correct.

exchange_amount

If Transaction.quote is not None, exchange_amount is the value of Transaction.amount_out expressed in units of Transaction.amount_in.

exchanged_amount

If Transaction.quote is not None, exchanged_amount is the value of Transaction.amount_in expressed in units of Transaction.amount_out.

Parameters
  • request – a rest_framework.request.Request instance

  • template – a polaris.templates.Template enum value for the template to be rendered in the response

  • form – the form to be rendered in the template

  • transaction – the transaction being processed

polaris.integrations.WithdrawalIntegration.content_for_template(self, request: rest_framework.request.Request, template: polaris.templates.Template, form: Optional[django.forms.forms.Form] = None, transaction: Optional[polaris.models.Transaction] = None, *args: List, **kwargs: Dict) Optional[Dict]

Same as DepositIntegration.content_for_template.

Parameters
  • request – a rest_framework.request.Request instance

  • template – a polaris.templates.Template enum value for the template to be rendered in the response

  • form – the form to be rendered in the template

  • transaction – the transaction being processed

Using this function in conjunction with template extensions, you can define template blocks that use context variables passed from content_for_template(). This gives anchors complete control of the interactive UX.

Warning

Any content returned from content_for_template() that originates from user input should be validiated and sanitized.

Outlined below are the default key-value pairs passed as context objects to each template. In addition to the attributes listed in each Template section, Polaris also passes the key-value pairs returned from content_for_template().

Template.DEPOSIT

  • form: The Django Form object return by form_for_transaction()

  • post_url: The URL to use when making the POST request containing form data

  • get_url: The URL to use when making the GET request for the form

  • scripts: A list of TemplateScript objects (deprecated)

  • operation: The /fee?operation= value for the transaction

  • asset: The Polaris Asset object for the transaction requested

  • use_fee_endpoint: A boolean for whether the anchor requires the custom fee endpoint

  • org_logo_url: A URL to the organization’s logo, to be used as the page center icon

Template.WITHDRAW

All attributes listed here have identical definitions to the above set of attributes:

  • form

  • post_url

  • get_url

  • scripts

  • operation

  • asset

  • use_fee_endpoint

Template.MORE_INFO

  • tx_json: A JSON-serialized object matching the response body from /transactions

  • amount_in: The amount sent to the anchor’s account

  • amount_out: The amount send to the user’s account

  • amount_fee: The amount charged by the anchor for facilitating the transaction

  • transaction: The Transaction Polaris database object

  • asset_code: The code string representing the asset