An issue with a lib? Create yours!
Tags: node, koa, hacktoberfest
Published: 2020-10-06 19:39:48

---
title: An issue with a lib? Create yours!
published: true
description: When your project use an external lib, you're dependent of it. If a bug is blocking you, replace this lib with your own code !
tags: #node, #koa, #hacktoberfest
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/cdbjgnw0fx26sz0gfemp.png
canonical_url: https://maximeblanc.fr/blog/an-issue-with-a-lib-create-yours
---

I'm working on a Node.js project that is using [Koa](https://github.com/koajs/koa). I wanted to use [Twig](https://www.npmjs.com/package/twig) as template engine in order to render views. I encountered some issues, and I want to relate how I dealt with.

## Many libs and one problem

The usual way to render HTML with Koa is by using [koa-views](https://www.npmjs.com/package/koa-views), which is using [consolidate](https://www.npmjs.com/package/consolidate) under the hood. `consolidate` require to add and configure manually the template engine we want to use.
There are many libs that are dependent (`koa-views` &rarr; `consolidate` &rarr; `twig`). This is not bad, but this requires each lib to communicate correctly with others.

I encountered a problem when I wanted to include or extend other twig files. Let's take the following code as example.

```twig
{# template.twig #}

<!DOCTYPE html>
<html lang="en">
  <head>...</head>
  <body>
    <main>{% block main %}{% endblock %}</main>
  </body>
</html>
```

```twig
{# home.twig #}

{% extends "template.html" %}

{% block main %}
<div>Home</div>
{% endblock %}
```

This code leads to the following error. Even if add some specific configuration as explained in [this issue](https://github.com/queckezz/koa-views/issues/99).

```bash
Error parsing twig template undefined: 
TwigException: Cannot extend an inline template.
```

By reading issues, it looked like there was some interferences between these libs, so I decided to reduce their numbers and make the link between Koa and Twig by myself.

## The koa-twig lib

The goal of [koa-twig](https://github.com/jean-smaug/koa-twig) is to enhance the **Koa Context** with a `render` function. It's heavily inspired of `koa-views`.

I'll present to you the first version of the code. I improved it, and I'm still improving it in order to offer the same feature as the others template engines bindings for Koa ([koa-ejs](https://github.com/koajs/ejs), [koa-hbs](https://github.com/koajs/koa-hbs)...).

```js
const twig = require("twig");
const util = require("util");

// Use Promise instead of callback syntax.
const renderFile = util.promisify(twig.renderFile);

/**
 * Give the ability to use Twig template engine in Koa
 * @param {object} config
 * @param {string} config.views - the views folder path
 * @param {object} config.data - the data to pass to each view
 * @param {object} config.extension - the data to pass to each view
 */
const twigMiddleware = (config) => async (ctx, next) => {
  function render(file, data) {
    return renderFile(`${config.views}/${file}.${config.extension || "twig"}`, {
      ...config.data,
      ...data,
    });
  }

  /* `render` function will be accessible
  on ctx and on ctx.response */
  ctx.response.render = render;
  ctx.render = render;

  await next();
};

module.exports = twigMiddleware;
```

Here a basic use case.

```js
const Koa = require("koa");
const koaTwig = require("koa-twig");

const app = new Koa();

// Configuration of the middleware
app.use(
  koaTwig({
    views: `${__dirname}/views`
  })
);

app.use(async (ctx) => {
  // Calling `render` will render `./views/home.twig`
  ctx.body = await ctx.render("home");
});

app.listen(8080);
```

So it wasn't that hard to reach a quick win. I can now develop with less intermediate. This is also something that made me remember that you don't need a lib for all of your problems!

## Bonus

All the PRs I made for this little lib counted for the Hacktoberfest 🎉

![hacktoberfest](https://dev-to-uploads.s3.amazonaws.com/i/lkcz2ot95rjt2o978haj.png)

Another reason to create and share what you're doing !

## Conclusion

If there is an obstacle on the road and you can't go to right, try the left. If it's closed, try to go up. If it's blocked, dig under! Don't wait for someone to clean the road for you.

I still have some work to do in order to have the same features as the others Koa template engines bindings, but it's a first step I'm satisfied of!

The short version : **DIY** and **KISS**.

Thanks for reading.

## Links

- [Banner image](https://www.artisan-ebeniste.com/quil-faut-savoir-atelier-debeniste/)