View Source Mecto (mecto v0.7.2)

"Mail merging" with Ecto structs.

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

Summary

Functions

Extracts nodes from some markup, returning a map where the end values are the count of how many times that node was in the markup.

Interpolates markup with the values in the given Ecto structs.

Builds a map from an Ecto schema, including following associations.

Validates markup fields exist on the supplied schema.

Functions

@spec extract_nodes(String.t()) :: map() | {:error, String.t()}

Extracts nodes from some markup, returning a map where the end values are the count of how many times that node was in the markup.

Note: this doesn't validate the nodes, just extracts them or errors if the markup is invalid.

Examples

iex> Mecto.extract_nodes("some text [[blog_post.title]] and [[blog_post.comments[0].content]]")
%{blog_post: %{title: 1, comments: %{0 => %{content: 1}}}}

iex> Mecto.extract_nodes("some text that [[is|invalid]]")
{:error, "invalid markup"}
@spec interpolate(String.t(), map()) :: {:ok, String.t()} | {:error, String.t()}

Interpolates markup with the values in the given Ecto structs.

Note: this does not validate the markup (beyond checking it can be parsed) - it is expected that any text passed to this has already been validated with Mecto.validate/2

Examples

iex> Mecto.interpolate("Title for post [[blog_post.title]]", %Mecto.BlogPost{title: "some title"})
{:ok, "Title for post some title"}

iex> Mecto.interpolate("Some [[[invalid markup]]", %Mecto.BlogPost{})
{:error, "invalid markup"}

iex> Mecto.interpolate("Some [[blog_post.invalid_field]]", %Mecto.BlogPost{})
{:ok, "Some "}
@spec parse_schema(module()) :: map() | {:error, atom()}

Builds a map from an Ecto schema, including following associations.

Note: this will not recurse if a struct is repeated deeper in the tree.

Examples

iex> Mecto.parse_schema(Mecto.User)
%{id: :id, username: :string}

iex> Mecto.parse_schema(Mecto.Foo)
{:error, :missing_schema}
@spec validate(String.t(), module()) :: map() | {:error, [String.t()]}

Validates markup fields exist on the supplied schema.

Examples

iex> Mecto.validate("Title for post #[[blog_post.id]]", Mecto.BlogPost)
%{blog_post: %{id: :id}}

iex> Mecto.validate("[[blog_post.invalid_field]]", Mecto.BlogPost)
{:error, ["blog_post.invalid_field does not exist"]}