Mustache template system


Is there a way to use a templating system like Mustache to generate a column from other fields?


Hi Sao,

I am not familiar with Mustache but you can use Python functions to do this.

One example of this is in the Families table of the Class Enrollment template.

We combine the First Name and Last Name columns to make the Full Name column. An alternative method of combining these could be $First_Name + " " + $Last_Name where the first row would combine to Fin Raddon.

You can see another example of this in the SKU column of the Inventory Manager template.

Another option would be to use Python’s string format() method. An example of this can be found in the Project Name column of the Projects table of the Tracking Time + Invoicing template.

The format() method formats the specified value(s) and insert them inside the string’s placeholder {}. In this example, the first set of {} are replaced with the value from $Client.Name and the second set are replaced with the value from $Name.

1 Like

thank you :wink:
But what if I need for example to loop over a list of tags .
For example, if I need to build an email message from multiple field or from another table.
Can we define a function to make it easier to write ?


Check out the ‘All Components’ column in the All Contracts table. It loops over a list and pulls information from multiple fields (some from another table)

The formula used here is:

  "{} — {:g} {}".format(comp.Component, quantity, comp.Unit)
  for (comp, quantity) in $Components.items()

We are using the join() method, sorted() function and format() method method all in one!

''.join() joins each item in the list.

'\n' adds a new line between each item in the list.

sorted() sorts the items in the list alphabetically.

This leaves us with the following:

"{} — {:g} {}".format(comp.Component, quantity, comp.Unit)
  for (comp, quantity) in $Components.items()

We’ll work through this backwards. First, we need to take a look at the Components column which is a hidden column in the All Contracts table.

This column is a list of components and their associated quantities for the contract. In the for loop, we assign each item in the list of components two variables, comp and quantity. For Components[3]: 6.0 , comp = Components[3] and quantity = 6.0 . Components[#] specifies a Component in the Components table by Row ID. Components[3] is the component assigned 3 as it’s row id.


Now, we run each item from the list above through the equation "{} — {:g} {}".format(comp.Component, quantity, comp.Unit) .

comp.Component replaces the first set of {} . comp is the variable with our component ID so comp.Component finds the value in the Component column associated with that row ID. For Components[3] , comp.Component is Nozzle.

quantity replaces the second set of {} . Again, the quantity is the second variable in our list. For Components[3]: 6.0 , quantity is 6.0 . Our second set of {} are not empty. They include :g . This converts the value to a floating-point number.

comp.Unit replaces the last set of {} . comp is the variable with our component ID so comp.Unit finds the value in the Unit column associated with that row ID. For Components[3] , comp.Unit is None .

This formula is a bit in-depth so if you need assistance writing your own, you can share your document with and let us know what you need the formula to do and we’d be happy to help out!

1 Like

OOOMG awesome , thank you very much😍
I didn’t know actually that we could write an entire function in python ,
I thought it was only accepted " String format() Method " :sweat_smile:
so we can install for example another python library and use it in formulas in a docker ?

If you are using self-hosted Grist, you can install any Python library you would like. With our hosted version, available at, you have access to the entire standard python library (without networking support).

We had a question in the community a while back about networking - check it out at the link below. Paul has a good explanation as to why there is no networking support and suggestions for getting data.

1 Like