<div align="center">

# Fields

A collection of commonly used fields implemented as custom Ecto types 
with the validation, sanitising and encryption/hashing. <br />
TODO: update intro copy once we ship better docs!
Ship your Phoenix App _much_ faster by using well-documented fields
with built-in validation, testing, sanitising and encryption.
See below for examples!

[![Build Status](](
[![contributions welcome](](
<!-- uncomment when service is working ... [![Inline docs](]( 

  <a href=""
  alt="Try the Demo on Heroku!">
    <img src=""
    alt="Van Gogh Fields of Wheat!">


## Installation

Add the `fields` package to your list of dependencies in `mix.exs`:

def deps do
    {:fields, "~> 1.0.0"}

Documentation can be generated with [ExDoc](
and published on [HexDocs]( 
Once published, the docs can
be found at [](

## Usage

Each field can be used in place of an Ecto type when defining your schema.

schema "users" do
  field(:email, Fields.EmailEncrypted)
  field(:address, Fields.Address)
  field(:postcode, Fields.Postcode)
  field(:password, Fields.Password)


Each field is defined as an 
[Ecto type](, 
with the relevant callbacks. 
So when you call `Ecto.Changeset.cast/4` 
in your schema's changeset function, 
the field will be correctly validated. 
For example, calling cast on the `:email` field 
will ensure it is a valid format for an email address.

When you load one of the fields into your database, 
the corresponding `dump/1` callback will be called, 
ensuring it is inserted into the database in the correct format. 
In the case of `Fields.EmailEncrypted`, 
it will encrypt the email address 
using a given encryption key 
(set in your config file) before inserting it.

Likewise, when you load a field from the database, 
the `load/1` callback will be called, 
giving you the data in the format you need. 
`Fields.EmailEncrypted` will be decrypted back to plaintext.

Each Field optionally defines an `input_type/0` function. 
This will return an atom 
representing the `Phoenix.HTML.Form` input type to use for the Field. 
For example: `Fields.DescriptionPlaintextUnlimited.input_type` returns `:textarea`.

The fields `DescriptionPlaintextUnlimited` 
and `HtmlBody` uses 
to remove scripts and help keep your project safe. 
`HtmlBody` is able to display basic html elements 
whilst `DescriptionPlaintextUnlimited` displays text. 
Remember to use `raw` when rendering
the content of your `DescriptionPlaintextUnlimited` 
and `HtmlBody` fields 
so that symbols such as & (ampersand) and Html are rendered correctly. 
`<p><%= raw @product.description %></p>` 

The currently existing fields are:

- [Address](lib/address.ex)
- [AddressEncrypted](lib/address_encrypted.ex)
- [DescriptionPlaintextUnlimited](lib/description_plaintext_unlimited.ex)
- [Encrypted](lib/encrypted.ex)
- [EmailPlaintext](lib/email_plaintext.ex)
- [EmailHash](lib/email_hash.ex)
- [EmailEncrypted](lib/email_encrypted.ex)
- [Hash](lib/hash.ex)
- [HtmlBody](lib/html-body.ex)
- [Password](lib/password.ex)
- [PhoneNumber](lib/phone_number.ex)
- [PhoneNumberEncrypted](lib/phone_number_encrypted.ex)
- [Postcode](lib/postcode.ex)
- [PostcodeEncrypted](lib/postcode_encrypted.ex)
- [Url](lib/url.ex)

## Config

If you use any of the `Encrypted` fields, 
you will need to set a list of 
one or more encryption keys in your config:

``` elixir
config :fields, Fields.AES,
    # remove single-quotes around key list in .env
    |> String.replace("'", "")
    # split the CSV list of keys
    |> String.split(",")
    # decode the key.
    |> key -> :base64.decode(key) end)

If you use any of the `Hash` fields, you will need to set a secret key base:

``` elixir
config :fields, Fields,
  secret_key_base: "rVOUu+QTva+VlRJJI3wSYONRoffFQH167DfiZcegvYY/PEasjPLKIDz7wPTvTPIP"

## Background / Further Reading

### How to Create a Re-useable Elixir Package and Publish to ``

### How to _Use_ the Package Locally _Before_ Publishing it to ``