Templating with LiquidJS

docpenny uses the LiquidJS templating engine to inject dynamic data into your HTML templates. Liquid is a safe, flexible, and powerful language that allows you to create complex document layouts with ease.

What is the basic Liquid syntax?

Variables are enclosed in double curly braces:

<p>Hello, {{ name }}!</p>

If your data is { "name": "Alice" }, the output will be <p>Hello, Alice!</p>.

How do I use control flow in templates?

If Statements

Use if tags to show content conditionally:

{% if status == 'paid' %}
  <div class="badge badge-success">PAID</div>
{% else %}
  <div class="badge badge-warning">PENDING</div>
{% endif %}

For Loops

Iterate over arrays (e.g., line items in an invoice):

<table>
  {% for item in items %}
    <tr>
      <td>{{ item.description }}</td>
      <td>{{ item.quantity }}</td>
      <td>${{ item.price }}</td>
    </tr>
  {% endfor %}
</table>

How do I use filters to format output?

Filters are used to modify the output of variables. They are applied with a pipe character |.

  • upcase: {{ name | upcase }}
  • date: {{ created_at | date: "%b %d, %y" }}
  • default: {{ title | default: "Untitled Document" }}

How does docpenny validate template data?

docpenny validates that every variable used in your template exists in the provided data payload. If a variable is referenced in the template but missing from the data, the API returns a 422 Unprocessable Content error with details identifying which variable is missing.

How do I create pixel-perfect layouts?

Since docpenny renders your HTML exactly as provided, you have full control over the precision of your documents. We recommend using inline styles or a scoped <style> block in your template to ensure consistent rendering.

Tip: Noto Serif & DM Sans

Our default PDF rendering engine supports Noto Serif (for headers) and DM Sans (for body text). You can include them via standard CSS:

<style>
  h1 { font-family: 'Noto Serif', serif; }
  body { font-family: 'DM Sans', sans-serif; }
</style>

Official Documentation

For a complete list of tags and filters, refer to the Official LiquidJS Documentation.

en