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

Writes the news: what the admin does, for a script or a seed too.

    {:ok, entry} =
      Tayori.Entries.create(%{
        "categories" => ["New"],
        "translations" => [
          %{"locale" => "en", "title" => "Exports", "body" => Kotoba.Content.from_markdown("...")}
        ]
      })

    {:ok, entry} = Tayori.Entries.publish(entry)

Every change is told on the PubSub (see `Tayori`), and the entry is
announced once, when it is published (`Tayori.Notifier`).

# `change`

```elixir
@spec change(Tayori.Entry.t(), map()) :: Ecto.Changeset.t()
```

A changeset of an entry, for a form.

# `counts`

```elixir
@spec counts() :: %{
  all: integer(),
  draft: integer(),
  scheduled: integer(),
  published: integer()
}
```

The number of entries of each status, for the admin's tabs.

# `create`

```elixir
@spec create(map(), keyword()) ::
  {:ok, Tayori.Entry.t()} | {:error, Ecto.Changeset.t()}
```

Creates an entry. Options: `:author` - who writes it, a map such as
`%{"id" => ..., "name" => ...}`.

A slug made from the title that another entry has takes a number:
`exports-2`. A slug given is the entry's, or an error.

# `delete`

```elixir
@spec delete(Tayori.Entry.t()) ::
  {:ok, Tayori.Entry.t()} | {:error, Ecto.Changeset.t()}
```

Deletes an entry and its translations.

# `get`

```elixir
@spec get(Ecto.UUID.t()) :: Tayori.Entry.t() | nil
```

An entry by its id, with its translations, or nil.

# `get!`

```elixir
@spec get!(Ecto.UUID.t()) :: Tayori.Entry.t()
```

An entry by its id, with its translations. Raises if there is none.

# `list`

```elixir
@spec list(keyword()) :: [Tayori.Entry.t()]
```

All the entries, for the admin: drafts and scheduled first, then the
published, the newest first, with their translations.

Options: `:search` - words of a title or a slug; `:status` - `:draft`,
`:scheduled` or `:published`.

# `new`

```elixir
@spec new() :: Tayori.Entry.t()
```

A new entry, with an empty translation in the first language.

# `pin`

```elixir
@spec pin(Tayori.Entry.t()) :: {:ok, Tayori.Entry.t()} | {:error, Ecto.Changeset.t()}
```

Pins an entry: pinned entries come first, the last pinned first.

# `publish`

```elixir
@spec publish(Tayori.Entry.t(), DateTime.t()) ::
  {:ok, Tayori.Entry.t()} | {:error, Ecto.Changeset.t()}
```

Publishes an entry, now or at a time: a time in the future schedules
it.

# `put_cover`

```elixir
@spec put_cover(Tayori.Entry.t(), Kotoba.Nodes.Attachment.t(), String.t() | nil) ::
  {:ok, Tayori.Entry.t()} | {:error, Ecto.Changeset.t() | :not_an_image}
```

Puts a cover on an entry, from a stored image: a
`Kotoba.Nodes.Attachment` (as `Kotoba.Attachments.store/2` or an upload
of the admin makes it), with its alternative text. Only an image can be
a cover.

# `put_cover_alt`

```elixir
@spec put_cover_alt(Tayori.Entry.t(), String.t()) ::
  {:ok, Tayori.Entry.t()} | {:error, Ecto.Changeset.t()}
```

Changes the alternative text of an entry's cover.

# `remove_cover`

```elixir
@spec remove_cover(Tayori.Entry.t()) ::
  {:ok, Tayori.Entry.t()} | {:error, Ecto.Changeset.t()}
```

Takes the cover off an entry. The image stays in the storage: delete it
with the storage adapter (`Kotoba.Storage`) if nothing else uses it.

# `unpin`

```elixir
@spec unpin(Tayori.Entry.t()) ::
  {:ok, Tayori.Entry.t()} | {:error, Ecto.Changeset.t()}
```

Unpins an entry.

# `unpublish`

```elixir
@spec unpublish(Tayori.Entry.t()) ::
  {:ok, Tayori.Entry.t()} | {:error, Ecto.Changeset.t()}
```

Makes an entry a draft again. It will be announced again when it is published.

# `update`

```elixir
@spec update(Tayori.Entry.t(), map()) ::
  {:ok, Tayori.Entry.t()} | {:error, Ecto.Changeset.t()}
```

Updates an entry: its fields, translations and publication time.

---

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