Bringing Go Templates everywhere
Tags: go, opensource, programming, coding
Published: 2023-08-05 06:20:42

As developers, we often copy and paste code, configurations, and templates between projects. This duplication leads to tech debt and missed optimization opportunities. That's why I created [`tpl`](https://github.com/ivanvc/tpl) - a simple, flexible templating tool to help developers standardize and reuse elements across their stack.

There are many instances in which I could use a _gotemplate_ to avoid a repetitive task. I searched for a simple tool (ideally a binary) that would help to achieve running _gotemplates_ in an arbitrary file (i.e., I love Helm _templating_, but it's limited to YAML files), however, after doing a [GitHub search](https://github.com/topics/gotemplate). I couldn't find what I wanted.

So, as I was working on a project that needed what I wanted. I paused that other project and decided to run a simple _gotemplate_ wrapper.

Ideally, I wanted it to be not opinionated, so it supports reading input files from _stdin_, a file, or receiving it as an argument. However, a simple _gotemplate_ with an environment would be helpful. So, it supports JSON, TOML, and YAML inputs for the environment. It tries to guess the format for the given environment, but it's also possible to force the format (in case it's wrongly parsed using another format). You can specify the environment inline as an argument, or using a file (if the first character is `@`, similar to curl).

Here are a some samples on how to use `tpl`.

### JSON environment from GitHub's API using _stdin_

There are many instances in which I want to run a template using an external resource (i.e., an HTTP API). I could do this using bash and jq. But doing it with a _gotemplate_ is way easier. Note that, in this case, the response is a JSON array. Like other tools I tried, it doesn't break, which would, as they expected to, be a JSON object. You need to handle `.` in the template as an array.

![JSON example](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9271nhw8a5fbdlx57jfi.gif)

### TOML environment building an index page using an input file

In my recent project (see my post on [Publishing Alpine Linux Packages using GitHub Actions](https://dev.to/ivanvc/publishing-alpine-linux-packages-using-github-actions-78p)), I wanted to build index page(s). So, a TOML input is an easy way to pass a list of files.

![TOML example](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/60ag0h5bt4lq2bz5gwbr.gif)

### YAML environment input defining a Terraform module

I wrote [`mleh`](https://github.com/ivanvc/mleh) years ago when I was trying to generate a Helm template with a Terraform output. Of course, Helm didn't like the format, which didn't work. While `mleh` is helpful for complex templates (i.e., it follows Helm's practices ignoring files that start with an underscore, and you can specify a `values.yaml` file as environment), there are some instances in which I need something more straightforward.

![YAML example](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f48b4htvl4jhn59ypf0s.gif)

So, if you want to give `tpl` a try, you can:

1. Install it by downloading the latest binary from its [GitHub releases page](https://github.com/ivanvc/tpl/releases)
2. Install it using Go:

    ```bash
    $ go install github.com/ivanvc/tpl@latest
    ```
3. Use it with Docker:

    ```bash
    $ docker run --rm ivan/tpl:latest --help
    ```

    Or, you could use it in your `Dockerfile`

    ```Dockerfile
    COPY --from=ivan/tpl:latest /bin/tpl /bin
    ```

[![GitHub Repo](https://opengraph.githubassets.com/bdbcb8d1aae43dbf9d83e917a53a1ee933092df99d6efeab41ba5df3a02c82d8/ivanvc/tpl)](https://github.com/ivanvc/tpl)