Skip to main content

Frappe Jinja API in Frappe Framework v15

What is the Frappe Jinja API in Frappe v15?

The Frappe Jinja API is a set of whitelisted helper functions and attributes that Frappe exposes to Jinja templates in a safe, sandboxed way. These helpers let you read documents, format values, access system settings, and work with the current session directly from templates such as print formats, email templates, and web pages. Frappe Documentation
Only the functions explicitly whitelisted by Frappe are available in Jinja, which keeps templates powerful but secure.

Where can you use the Jinja API in Frappe?

You can use these helpers anywhere Frappe evaluates a Jinja template, for example:

  • Print Formats (Standard & Custom)
  • Email Templates / Notifications
  • Web Templates & Portal Pages
  • Auto Email Reports / Custom HTML blocks

In all these contexts, frappe is injected into the Jinja environment and exposes the whitelisted methods listed on the official Jinja API page.

Overview: Which helpers are available in the Jinja API?

The Jinja API page in Frappe v15 documents the following helpers:

Formatting & URL

  • frappe.format(value, df, doc)
  • frappe.format_date(date_string)
  • frappe.get_url()

Document & Database Access

  • frappe.get_doc(doctype, name)
  • frappe.get_all(doctype, filters, fields, order_by, start, page_length, pluck)
  • frappe.get_list(doctype, filters, fields, order_by, start, page_length)
  • frappe.db.get_value(doctype, name, fieldname)
  • frappe.db.get_single_value(doctype, fieldname)
  • frappe.get_system_settings(fieldname)
  • frappe.get_meta(doctype)

User & Session Helpers

  • frappe.get_fullname(user_email=None)
  • frappe.session.user
  • frappe.session.csrf_token
  • frappe.lang

Templating & Translation

  • frappe.render_template(template_name_or_string, context)
  • frappe._(string) or _(string)

Request Data

  • frappe.form_dict

Each of these is safe to call from templates and is designed for read-only or formatting purposes.

How to format values with frappe.format and frappe.format_date?

How does frappe.format work in a Jinja template?

frappe.format converts a raw database value into a user-facing string, according to the field definition (df) and current system settings.

Signature

{{ frappe.format(value, df, doc) }}

  • value: Raw field value as stored in the database
  • df: Field definition dict (must at least include fieldtype)
  • doc (optional): Document dict for context (e.g. currency, options)

Example – format a Date

{{ frappe.format('2019-09-08', {'fieldtype': 'Date'}) }}

Output (depending on system format, example from docs): 09-08-2019

Use frappe.format when you:

  • Render values in custom HTML tables in print formats
  • Show numeric fields (e.g. Currency) consistent with system settings

How does frappe.format_date differ from frappe.format?

frappe.format_date is a shortcut that converts a date string into a human-readable long date such as “September 8, 2019”.

Signature

{{ frappe.format_date(date_string) }}

Example

{{ frappe.format_date(doc.posting_date) }}

Typical output: September 8, 2019

Use frappe.format_date when you only care about readable dates, not field metadata.

How to get the current site URL with frappe.get_url?

frappe.get_url() returns the absolute base URL of the current site, as configured in Frappe.

Signature

{{ frappe.get_url() }}

Example – building an absolute link

<a href="{{ frappe.get_url() }}/orders/{{ doc.name }}">
View Order Online
</a>

This is useful for:

  • Email templates that need absolute links
  • Print formats that embed QR codes or external links

How to read documents in Jinja with frappe.get_doc?

frappe.get_doc(doctype, name) loads a full document (including child tables) by its doctype and name.

Signature

{% set task = frappe.get_doc('Task', 'TASK00002') %}
{{ task.subject }} – {{ task.status }}

Usage tips

  • Best for single lookups where you need many fields or child rows.
  • Avoid calling frappe.get_doc in tight loops; pre-compute in your Python controller when possible.

Jinja templates in some contexts (e.g. specific doctypes or notifications) run in a sandbox; if you hit permission issues, ensure the current user has read access to the target DocType.

How to list records with frappe.get_all and frappe.get_list?

When should you use frappe.get_all?

frappe.get_all returns a list of records for a given DocType without applying user permission filters by default (it works at the system level).

Signature

{% set tasks = frappe.get_all(
'Task',
filters={'status': 'Open'},
fields=['title', 'due_date'],
order_by='due_date asc'
) %}

Then loop:

{% for t in tasks %}
<h4>{{ t.title }}</h4>
<p>Due: {{ frappe.format_date(t.due_date) }}</p>
{% endfor %}

Use frappe.get_all in system-level templates (e.g. admin reports) when the output is not restricted by user permissions.

When should you use frappe.get_list?

frappe.get_list has the same signature as frappe.get_all but applies permission checks depending on the current user session.

Signature

{% set my_tickets = frappe.get_list(
'Issue',
filters={'raised_by': frappe.session.user},
fields=['name', 'subject', 'status']
) %}

Use frappe.get_list when:

  • You render user-specific dashboards
  • You want results filtered by role-based permissions

How to fetch single values with frappe.db.get_value and frappe.db.get_single_value?

Why use frappe.db.get_value in templates?

frappe.db.get_value retrieves one or more field values from a specific document, without loading the entire document.

Signature

{{ frappe.db.get_value(doctype, name, fieldname) }}
{{ frappe.db.get_value(doctype, name, [field1, field2]) }}

Examples

{% set company_abbr = frappe.db.get_value('Company', 'TennisMart', 'abbr') %}
{{ company_abbr }} {# e.g. "TM" #}
{% set title, description = frappe.db.get_value(
'Task', 'TASK00002', ['title', 'description']
) %}
<h4>{{ title }}</h4>
<p>{{ description }}</p>

Use this when you only need a few fields and want better performance than a full get_doc.

When to use frappe.db.get_single_value?

frappe.db.get_single_value reads a field from a Single DocType (such as System Settings).

Signature

{{ frappe.db.get_single_value(doctype, fieldname) }}

Example

{% set timezone = frappe.db.get_single_value('System Settings', 'time_zone') %}
<p>System Time Zone: {{ timezone }}</p>

This is ideal for templates that must adapt to global configuration values.

How to access global system settings with frappe.get_system_settings?

frappe.get_system_settings(fieldname) is a convenience wrapper to fetch values from the System Settings single DocType.

Signature

{{ frappe.get_system_settings(fieldname) }}

Example conditional payment method

{% if frappe.get_system_settings('country') == 'India' %}
Pay via Razorpay
{% else %}
Pay via PayPal
{% endif %}

Use this to branch template logic based on system-wide configuration.

How to inspect DocType metadata with frappe.get_meta?

frappe.get_meta(doctype) returns the metadata object for a DocType, including field definitions, title field, and other schema information.

Signature

{% set meta = frappe.get_meta('Task') %}

You can then inspect fields:

Task has {{ meta.fields | len }} fields.
{% if meta.get_field('status') %}
Task has a Status field.
{% endif %}

Use frappe.get_meta when building dynamic templates that adapt to field configuration, e.g. generic reports or admin utilities.

How to work with user information using frappe.get_fullname and frappe.session?

What does frappe.get_fullname do?

frappe.get_fullname(user_email=None) returns the full name associated with a User record. If user_email is omitted, it uses the current session user.

Examples

The fullname of faris@erpnext.com is {{ frappe.get_fullname('faris@erpnext.com') }}
The current logged in user is {{ frappe.get_fullname() }}

Typical output: “Faris Ansari”, “John Doe”.
Use this in:

  • Welcome messages in portals
  • Email greetings in notifications

How to use frappe.session.user and frappe.session.csrf_token?

Frappe exposes parts of the current session as Jinja variables: Frappe Documentation+1

  • frappe.session.user – current logged-in user ID (e.g. test@example.com or “Guest”)
  • frappe.session.csrf_token – CSRF token for the current session

Examples

<p>Logged in as: {{ frappe.session.user }}</p>
<input type="hidden" name="csrf_token" value="{{ frappe.session.csrf_token }}">

These are useful for:

  • Security-aware forms in web templates
  • Displaying session context in dashboards

How to render nested templates with frappe.render_template?

frappe.render_template(template_name_or_string, context) lets you render another Jinja template from within the current template.

Signature

{{ frappe.render_template(path_or_template_string, context) }}

Examples

{{ frappe.render_template('templates/includes/footer/footer.html', {}) }}
{{ frappe.render_template('{{ foo }}', {'foo': 'bar'}) }}
{# Output: bar #}

Use this to:

  • Reuse includes with custom context
  • Build small template fragments dynamically

How to translate strings in Jinja with frappe._ and frappe.lang?

What is frappe._(string) / _(string)?

frappe._ (or the shorthand _) marks a string for translation using Frappe’s translation system.

{{ _('This string should get translated') }}

Depending on the active language (frappe.lang), this will render the translated version of the string.

What does frappe.lang represent?

frappe.lang contains the two-letter, lowercase language code currently in use (for example, “en” or “fr”).

Example

<p>Language: {{ frappe.lang }}</p>

You can use this to:

  • Change layout or wording for specific languages
  • Debug translation issues in templates

How to access request data with frappe.form_dict?

frappe.form_dict is a dictionary of query parameters and form fields when the template is part of a web request; otherwise it is None.

Example

{% if frappe.form_dict and frappe.form_dict.get('filter') %}
<p>Filter: {{ frappe.form_dict.get('filter') }}</p>
{% endif %}

Use this in web pages and portal templates that need to:

  • Read query parameters (e.g. ?status=Open)
  • Render content based on form submissions

Always check that frappe.form_dict is truthy before calling .get.

Best practices for using the Jinja API in Frappe v15

  • Keep templates light
    Avoid heavy database operations inside loops (e.g. get_doc inside {% for %}). Pre-compute data in Python and pass it in the context when possible.
  • Respect permissions
    Prefer frappe.get_list over frappe.get_all when output must respect user permissions.
  • Use single-value helpers for configuration
    Use frappe.db.get_single_value and frappe.get_system_settings for global defaults instead of querying standard DocTypes.
  • Centralize formatting
    Use frappe.format and frappe.format_date so your templates follow system formats for dates, currency, and numbers.
  • Design translation-ready templates
    Wrap human-facing strings with _() and avoid hard-coding user-visible labels without translation markers.
  • Avoid unsafe Python in templates
    Stick to the whitelisted helpers and Jinja features. Custom business logic should live in Python, not embedded in Jinja.

Common issues and troubleshooting

Why is frappe undefined in my template?

  • The template is not being rendered through Frappe’s Jinja environment (e.g. you are testing in a standalone Jinja renderer).
  • Ensure the template is used in a Frappe context (print format, email template, web page, or server code using frappe.render_template).

Why do I get permission or sandbox errors calling frappe.get_doc?

  • In some sandboxed contexts (e.g. certain notifications or email templates), Jinja uses a sandbox environment that may restrict some operations for security.
  • Check the current user’s permissions on the DocType and review any validation errors in the logs.

Why does date or time formatting fail?

  • If you pass an invalid date/time string to formatting utilities, they can raise exceptions (e.g. “String does not contain a date”). Ensure the value is a proper date/time field or sanitized data.

 

Cross-references for deeper learning

  • Jinja API page (official) – full list of whitelisted helpers and examples
  • Utility Functions API – additional helpers available in Python via frappe.utils
  • Document API / Database API – for detailed behavior of get_doc, get_list, and DB helpers (see framework/user/en/api/document and framework/user/en/api/database in the Frappe docs).
Click to rate this post!
[Total: 0 Average: 0]