# MJML (Rust NIFs for Elixir)
[![Hex version badge](https://img.shields.io/hexpm/v/mjml.svg)](https://hex.pm/packages/mjml)
[![License badge](https://img.shields.io/hexpm/l/mjml.svg)](https://github.com/adoptoposs/mjml_nif/blob/main/LICENSE.md)
[![Build Status](https://github.com/adoptoposs/mjml_nif/workflows/Tests/badge.svg)](https://github.com/adoptoposs/mjml_nif/workflows/Tests/badge.svg)
Native Implemented Function (NIF) bindings for the [MJML](https://mjml.io) Rust implementation ([mrml](https://github.com/jdrouet/mrml)).
## Installation
In order to use the package you need to [install Rust](https://www.rust-lang.org/tools/install).
The package can be installed by adding `mjml` to your list of dependencies in `mix.exs`:
```elixir
def deps do
[
{:mjml, "~> 1.1.1"}
]
end
```
## Usage
Transpile MJML templates to HTML with:
```elixir
mjml = "<mjml>...</mjml>"
{:ok, html} = Mjml.to_html(mjml)
# For an invalid MJML template:
mjml = "something not MJML"
{:error, message} = Mjml.to_html(mjml)
```
## Deployment
MJML requires that the Rust compiler be [installed](https://www.rust-lang.org/tools/install) wherever MJML is compiled.
### Deploying to Heroku
Most Heroku buildpacks for Elixir do not come with Rust installed; you will need to:
- Add a Rust buildpack to your app, setting it to run before Elixir; and
- Add a `RustConfig` file to your project's root directory, with `RUST_SKIP_BUILD=1` set.
For example:
```bash
heroku buildpacks:add -i 1 https://github.com/emk/heroku-buildpack-rust.git
echo "RUST_SKIP_BUILD=1" > RustConfig
```
### Deploying with Docker
Make sure Rust is installed prior to running `mix deps.compile`. You can see examples of what commands to include in your Dockerfile by looking at the official Rust Dockerfiles. For example, here are the commands for [`alpine3.11`](https://github.com/rust-lang/docker-rust/blob/009cc0a821ff773d54875350312731ed490d5cce/1.43.1/alpine3.11/Dockerfile) based images.
If your Dockerfile is separated into a build stage and a release stage Rust only needs to be installed on the build stage. **However**, your release stage will need to have `libgcc` installed.
Alpine, for example, does not include `libgcc` by default and you will need to install it.
```
RUN apk add --no-cache libgcc
```
You will also need to have the following environment variable set during the `build` stage or else `mix compile` will fail.
```
RUSTFLAGS='--codegen target-feature=-crt-static'
```
## Contributing
We encourage you to contribute to mjml_nif.
Please check our [CONTRIBUTING.md](https://github.com/adoptoposs/mjml_nif/blob/main/CONTRIBUTING.md) guides for more information.
This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to our [CODE_OF_CONDUCT.md](https://github.com/adoptoposs/mjml_nif/blob/main/CODE_OF_CONDUCT.md).
## License
Copyright (c) 2020-2021, Paul Götze
This software is licensed under the [MIT License](https://github.com/adoptoposs/mjml_nif/blob/main/LICENSE.md).