README.md

[![build status](https://gitlab.com/mucky-pup/mecto/badges/main/pipeline.svg)](https://gitlab.com/mucky-pup/mecto/-/commits/main)
[![coverage report](https://gitlab.com/mucky-pup/mecto/badges/main/coverage.svg)](https://mucky-pup.gitlab.io/mecto/coverage/excoveralls.html)
[![documentation coverage](https://ik.imagekit.io/muckypup/mecto/doc-coverage.svg)](https://hexdocs.pm/mecto)
[![License: CC BY-SA 4.0](https://img.shields.io/badge/License-CC%20BY--SA%204.0-lightgrey.svg)](https://creativecommons.org/licenses/by-sa/4.0/)

# Mecto

"Mail merging" with Ecto structs.

A parser to interpolate MediaWiki-like `[[foo.bar]]` markup using data from Ecto schemas.

## Installation

If [available in Hex](https://hex.pm/docs/publish), the package can be installed
by adding `mecto` to your list of dependencies in `mix.exs`:

```elixir
def deps do
  [
    {:mecto, "~> 0.7.0"}
  ]
end
```

## Usage

Mecto was originally built to provide dynamic "mail-merging" (think HEEx, but not compiled) from Elixir structs - specifically ones that `use Ecto.Schema`.

Take this struct:

```elixir
defmodule MyApp.BlogPost do
  use Ecto.Schema

  schema "blog_posts" do
    field(:title, :string)
    field(:content, :string)
  end
end
```

You could then have some text like:

```elixir
text = "The latest blog post is [[blog_post.title]]"
```

If you wanted to validate the text has correct markup, you could call:

```elixir
Mecto.validate(text, MyApp.BlogPost)

> %{blog_post: %{title: :string}}
```

And Mecto would ensure that the fields used in the text actually exist on `MyApp.BlogPost`. You can also take it a step further,
calling `Mecto.interpolate` to then use the values in a specific struct:

```elixir
Mecto.interpolate(text, %MyApp.BlogPost{title: "some title"})

> {:ok, "The latest blog post is some title"}
```

Mecto also handles relationships and custom Ecto types (i.e. defined with `Ecto.Type`).

By default there is [an implementation](https://gitlab.com/mucky-pup/mecto/-/blob/main/lib/custom_schema.ex) for `Ecto.Enum`, but you can use [protocol_ex](https://github.com/OvermindDL1/protocol_ex) for your own types.

See the tests for more examples.

Documentation can be found at <https://hexdocs.pm/mecto>.

## Support my work

If you want to support my work, you can donate on Liberapay:

[![Liberapay donation link](https://liberapay.com/assets/widgets/donate.svg)](https://liberapay.com/mucky-pup-creations/donate)