Coelho.Schema.Default (coelho v0.14.0)

Copy Markdown View Source

The schema Coelho ships with.

It covers what an application typically needs out of the box — paragraphs, headings, lists, quotes, code blocks, images and the usual inline marks — and is meant to be copied and adapted rather than extended in place.

An href and a title, and nothing else. In particular no target and no rel: a document is not necessarily rendered into a page where opening a new tab makes sense, and a target="_blank" without rel="noopener" hands the opened page a handle on the opener. Rather than guess, the shipped renderer emits neither.

An application that wants them says so per render, and must set both:

Coelho.to_html(document,
  marks: %{
    link: fn mark, inner ->
      Coelho.Render.tag(
        "a",
        [
          {"href", Coelho.Render.safe_url(Coelho.Render.attr(mark, "href"))},
          {"target", "_blank"},
          {"rel", "noopener noreferrer"}
        ],
        inner
      )
    end
  }
)

The href still goes through Coelho.Render.safe_url/1 there, because a stored document is not re-validated on the way out.

Alignment

paragraph, heading and list_item carry an align attribute, one of left, center, right or justify, rendered as a text-align style and read back from either a style or an align attribute on import. It is absent from the document when unset, and re-checked against the closed list at render time.

How it renders is part of the attribute's declaration — :render_as, see Coelho.Schema.Attr — rather than a render function, so the browser applies the same answer and an application can change it without writing any JavaScript. An inline style is what ships because it needs no stylesheet: the HTML works in an email, a feed, an export. It is also what a page's own CSS cannot override, so an application that would rather own alignment in its stylesheet asks for a class map instead — once, for the three blocks that carry the attribute:

Coelho.Schema.Default.build(
  align: {:class, %{"center" => "text-center", "right" => "text-right"}}
)

The schema is built once and kept in :persistent_term, since it is immutable and read on every render.

Summary

Functions

Builds the default schema without consulting the cache.

Returns the default schema, building it on first use.

Functions

build(opts \\ [])

@spec build(keyword()) :: Coelho.Schema.t()

Builds the default schema without consulting the cache.

Options

  • :align — how the align attribute reaches the DOM, in the form Coelho.Schema.Attr takes for :render_as. Defaults to {:style, "text-align"}.

An inline style is unanswerable by a stylesheet, so an application that would rather own alignment in CSS says so once, here, rather than redeclaring the three blocks that carry the attribute:

Coelho.Schema.Default.build(
  align: {:class, %{"center" => "text-center", "right" => "text-right"}}
)

The result is not cached — schema/0 caches the default one. Build yours once at compile time, as an application with any custom schema already does.

schema()

@spec schema() :: Coelho.Schema.t()

Returns the default schema, building it on first use.