Jinja templates

Things I have tried

I searched google, the community plugins, and the forums

What I’m trying to do

Firstly, I’m new to this, so it’s totally possible that I’m using templater wrong and I’m missing the right way to do what I’m trying to.

I’m a developer, and have worked with jinja2 templates for a long time. They’re very powerful, easily extendable, they mostly look good, and it’s better suited to rendering text than javascript as templater uses.

I’m extremely surprised to see there’s not one plugin that allows one to use jinja templates.

The things that bother me from templater might sound silly, but… hey, I think we’re all a bit obsessive, otherwise we wouldn’t be using Obsidian, would we?

Here’s an example:
To generate a contact’s metadata I’ve got the following (abridged, the rest doesn’t matter):

  let name = await tp.system.prompt("name");
  names = name.split(" ")
  let firstName = names[0]
  let lastName = names[1]
  let team = await tp.system.prompt("Team");
-%>
---
aliases:
- <% firstName + " " + lastName %>
- <% lastName + " " + firstName %>
- <% firstName + "." + lastName %>
created: "{{date}} {{time}}"
tags:
- person
<% team ? "team: " + team : "" %>
---

There’s several things that bother me from that.

  • Firstly, the ternary operator (that team?"team":"" thing) is ugly and hard to read
  • secondly having to concatenate values like that with + is also ugly and hard to read
  • thirdly, if there’s no team, an empty line will be added to the file, and the only way around it I could find would be to change that line to: <%- team ? "\nteam: " + team : "" %> or similar.

For comparison, an equivalent template in jinja (leaving aside the fact that it doesn’t have capabilities to call on system.prompt and that kind of stuff, which I think is great) would look like:

---
....
tags:
- person
{%- if team %}
team: {{team}}
{%- endif %}
---

So, is there any way of conditionally adding lines like that on templater, or any plugins to use jinja, or anything else I’m missing?

Thanks for the help
Tomas

1 Like

One option could be to do something like this:

<%*
let team = await tp.system.prompt("Team")

if ( team != "" )
  team = `team: ${ team }\n`
_%>

before
<% team -%>
after

If I call this template twice, once without adding a team, and once with adding a team, I get the following output:

before
after
before
team: Obsidian
after

That is not adding the line due to the ending -%>, and I’m using a slightly different syntax to build the line using javascript template literals.

You’re aware of the fact that this’ll break with people with double first names, or double last names? So “John Patrick McEnroe” or “Ludwig van Beethoven”, would render slightly errorneous as aliases…

@holroy I figured out what I was looking for in these 20 minutes, but I’ll answer your questions for posterity :wink:

One option could be to do something like this:

...
 team = `team: ${ team }\n`
_%>

One of my biggest points here was that I don’t want to use explicit \n for basic templating. The idea of building a string and then outputting it is even worse, that’s precisely the problem a templating language should solve.

You’re aware of the fact that this’ll break with people with double first names, or double last names?

Yes, this is a simplified script, just to have an example, no worries :slight_smile:

As for my solution, what I just found out is that you can use execution commands to partially render JS a la PHP, so the solution to my woes is:

aliases:
 - ....
<% if (team) { -%>
team: <% team %>
<% } -%>
---
2 Likes

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.