Customise your Phoenix HTML Generator
Tags: elixir, phoenix
Published: 2019-06-02 22:28:26

---
title: Customise your Phoenix HTML Generator
published: true
tags: elixir,phoenix
canonical_url: https://medium.com/@mutablestate/customise-your-phoenix-html-generator-d45fecd48683
---

![](https://cdn-images-1.medium.com/max/1024/1*FBJdKJt9CTNCpV4dMzPJaw.jpeg)<figcaption>Generator Hostel Dublin by <a href="https://www.flickr.com/photos/yukino/">Rosa G</a></figcaption>

**NOTE: 2019 update in progress... Phoenix 1.4 and Tailwindcss ftw**

**What’s it all about?**

Scaffolding with Phoenix generators, especially with `mix phx.gen.html`, is a great way start out a project. Not only do you get a resource all wired up for CRUD it also provides unit tests and demonstrates best practices.

All this sounds great so why did I stop using such a powerful ally after that initial burst of enthusiasm? I think the main reason was the desire to take off the proverbial training wheels provided by the generator and get writing some sweet Elixir code. My confidence was up and going it alone was aided by a helpful feedback loop of error messages and stack traces.

The fundamental point i’d completely missed of using a generator with templates is achieving consistency through automation. Consistency is one of the keys to a maintainable codebase and also happens to be the basis of a great UX. By customising the Phoenix HTML generator maybe I can achieve both of these goals.

**The scenario**

Being an opinionated software engineer I’ve decided my new CRUD project will use [Milligram](https://milligram.github.io/), a minimalist css framework, instead of the standard bootstrap css used by Phoenix and most of the web. Making that one simple decision renders the standard Phoenix HTML generator pretty useless.

**One of many solutions**

Replace the standard `mix phx.gen.html` with a project specific generator and templates. The templates can then be updated and re-used to generate each new resource I add with the latest styles and layout.

**Let’s do it!**

1. Create a new Phoenix 1.3 project

```
mix phx.new boiler && cd boiler
```

2. Replace assets/css/phoenix.css with milligram.css

3. Make the templates and mix task project directories

```
mkdir -p priv/templates/boiler.gen.html && mkdir -p lib/boiler/mix/tasks
```

4. Copy all current HTML generator templates to the new project templates directory

```
cp -a deps/phoenix/priv/templates/phx.gen.html/. priv/templates/boiler.gen.html
```

5. Copy the current generator task to the new project tasks directory

```
cp deps/phoenix/lib/mix/tasks/phx.gen.html.ex lib/boiler/mix/tasks/boiler.gen.html.ex
```

6. Open `lib/boiler/mix/tasks/boiler.gen.html.ex` in your favourite editor and update the module name to `Mix.Tasks.Boiler.Gen.Html`

7. In the same file search / replace all instances of lowercase `phx` with `boiler`

8. Check that your code compiles and you have a boiler project mix task

```
mix compile && mix help | grep boiler
```

If all went well you should see our new mix task listed as `mix boiler.gen.html`

9. Its time to edit the `eex` templates in `priv/templates/boiler.gen.html` using Milligram classes and any markup changes before using our new generator command.

Milligram uses a different grid system to bootstrap so we also need to update `lib/boiler/web/templates/layout/app.html.eex`

**Its generate time!**

Use our new mix task as you would with the Phoenix generator.

```
mix boiler.gen.html Accounts User users name:string email:string phone:string
```

Follow the instructions to add the resource to the router and run the migrations.

Start the server with `mix phx.server` and visit [http://localhost:4000/users](http://localhost:4000/users) to see your custom generated HTML templates in action.

**Don’t stop now**

This is a small example of generating custom markup for a CRUD app but its only a taster of what’s possible.

Are you using Phoenix custom generators in creative ways?

Thanks for reading!

The repo can be found at [https://github.com/mutablestate/boiler](https://github.com/mutablestate/boiler)