# `MishkaCmsMigration.Targets.Helpers.SeoTags`
[🔗](https://github.com/mishka-group/mishka_cms_migration/blob/v0.0.1/lib/mishka_cms_migration/targets/__helpers/seo_tags.ex#L5)

An item's `"seo"` (`MishkaCmsMigration.Sources.WordPress` reads it from Yoast SEO and Rank Math)
as the `seo_tags` a CMS page or a Blog post stores, for the targets that write them
(`MishkaCmsMigration.Targets.CmsPage`, `MishkaCmsMigration.Targets.BlogPost`). Each tag is
written as the core's head reads a stored tag (`MishkaCmsCore.Runtime.Seo.stored_tag/3`), and
replaces the default the head would draw for it:

  * `"title"` — the `title`; a `{{page.title}}` or `{{site.name}}` in it is the core's own
    variable;
  * `"description"` — the `description` meta;
  * `"robots"` — the `robots` meta, such as `noindex, nofollow`;
  * `"image"` — the `og:image` meta: the Media address of the file the same run, or an earlier
    one, wrote for its `"image_id"` (`MishkaCmsMigration.Targets.CmsMedia.addresses/2`). An image
    on another site than the source keeps its address; one on the source that was not imported
    is left out, and so is the target's `featured` file: a page with no stored `og:image` gets the
    core's share card (`MishkaCmsCore.Runtime.ShareCard`), which draws a Blog post's featured
    image, and a stored one would replace that card;
  * `"canonical"` — the `canonical` link. The source keeps only a canonical on another site;
  * `"og_title"` and `"og_description"` — the `og:title` and `og:description` metas, the social
    title and description when they say something else than the title and the description;
  * `"twitter_title"` and `"twitter_description"` — the `twitter:title` and
    `twitter:description` metas;
  * `"twitter_image"` — the `twitter:image` meta, kept and left out by the same rules as `"image"`
    (its `"twitter_image_id"`), and left out too when it is the `og:image` the page stores,
    which the head already repeats for Twitter;
  * `"twitter_card"` — the `twitter:card` meta, only `summary`: the head draws
    `summary_large_image` for a page with an image by itself.

The core's head stacks these over the layout's and a plugin's, a tag by its name and attributes,
so each one replaces the default for that tag, and none is drawn twice.

A title and a description are stored as the item carries them, plain text, which the head
escapes once: the source has already read the HTML entities its CMS answers
(`MishkaCmsMigration.Sources.WordPress`).

An item without `"seo"` has no tags.

# `call`

```elixir
@spec call(
  MishkaCmsMigration.Source.Item.t(),
  MishkaCmsMigration.Target.context(),
  term()
) :: [map()]
```

The `seo_tags` of `item`, leaving out an image that is the source's `featured` file (`nil` for
none).

---

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