# `Tayori.Entry`
[🔗](https://github.com/hattoriai/tayori/blob/v0.1.0/lib/tayori/entry.ex#L1)

An entry of the news: one thing the app has to say, in one or more
languages (`Tayori.Translation`).

  * `:slug` - its address on the public page, from the title of its
    first language unless the admin gives one.
  * `:categories` - the keys of its categories (`Tayori.Category`).
  * `:cover` - an optional image at the top of the entry and on its
    card, and its picture when a link to it is shared:
    `%{"url" => ..., "key" => ..., "width" => ..., "height" => ..., "alt" => ...}`.
  * `:segments` - the readers it is for: an entry with no segments is
    for everyone, and is the only kind on the public page; an entry with
    segments is for the readers in at least one of them (see
    `Tayori.Reader`).
  * `:published_at` - nil while it is a draft; a time in the future
    while it is scheduled.
  * `:pinned_at` - when it was pinned: pinned entries come first.
  * `:announce` - `"popup"`, `"toast"` or `"banner"`: the entry is shown
    in the app as one, until `:announce_until` (the `:announcements`
    feature).
  * `:email` - whether it is sent to the subscribers when it is
    published (the `:subscriptions` feature); `:emailed_at` once it is.
  * `:author` - who wrote it, as the admin's resolver gave them
    (`%{"id" => ..., "name" => ...}`).

`:translation` is not stored: the functions that read entries for a
reader set it to the translation in the reader's language, or in the
first language when the entry has none in theirs.

# `status`

```elixir
@type status() :: :draft | :scheduled | :published
```

# `t`

```elixir
@type t() :: %Tayori.Entry{
  __meta__: term(),
  announce: String.t() | nil,
  announce_until: DateTime.t() | nil,
  announced_at: DateTime.t() | nil,
  author: map() | nil,
  categories: [String.t()],
  cover: map() | nil,
  email: boolean(),
  emailed_at: DateTime.t() | nil,
  id: Ecto.UUID.t() | nil,
  inserted_at: term(),
  pinned_at: DateTime.t() | nil,
  published_at: DateTime.t() | nil,
  segments: [String.t()],
  slug: String.t() | nil,
  translation: Tayori.Translation.t() | nil,
  translations: [Tayori.Translation.t()] | Ecto.Association.NotLoaded.t(),
  updated_at: term()
}
```

# `announce_kinds`

```elixir
@spec announce_kinds() :: [String.t()]
```

The ways an entry can be announced in the app.

# `announcing?`

```elixir
@spec announcing?(t(), DateTime.t()) :: boolean()
```

Whether the entry is announced in the app at a time: announced as a
popup, toast or banner, and its announcement not over.

# `slugify`

```elixir
@spec slugify(String.t()) :: String.t()
```

A slug from a title: lowercase ASCII letters and digits, joined by
dashes, with the accents taken off.

## Examples

    iex> Tayori.Entry.slugify("Ação rápida: exports in 2 clicks!")
    "acao-rapida-exports-in-2-clicks"

# `status`

```elixir
@spec status(t(), DateTime.t()) :: status()
```

The status of an entry at a time (now by default).

## Examples

    iex> Tayori.Entry.status(%Tayori.Entry{published_at: nil})
    :draft

    iex> Tayori.Entry.status(%Tayori.Entry{published_at: ~U[2000-01-01 00:00:00Z]})
    :published

# `translation`

```elixir
@spec translation(t(), String.t() | nil, [String.t()]) :: Tayori.Translation.t() | nil
```

The translation of an entry in a language, else in the first of
`locales`, else the first it has. Needs the translations preloaded.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
