View Source Inertia.Controller (Inertia v1.0.0-beta.2)

Controller functions for rendering Inertia.js responses.

Summary

Functions

Assigns errors to the Inertia page data. This helper accepts an Ecto.Changeset (and automatically serializes its errors into a shape compatible with Inertia), or a bare map of errors.

Assigns a prop value to the Inertia page data.

Enable (or disable) automatic conversion of prop keys from snake case (e.g. inserted_at), which is conventional in Elixir, to camel case (e.g. insertedAt), which is conventional in JavaScript.

Instuct the client-side to clear the history.

Instuct the client-side to encrypt history for this page.

Marks a prop value as "always included", which means it will be included in the props on initial page load and subsequent partial loads (even when it's not explicitly requested).

Marks that a prop should fetched immediately after the page is loaded on the client-side.

Marks that a prop should be merged with existing data on the client-side.

Marks a prop value as optional, which means it will only get evaluated if explicitly requested in a partial reload.

Renders an Inertia response.

Types

@type always() :: {:keep, any()}
@type defer() :: {:defer, {(... -> any()), String.t()}}
@type merge() :: {:merge, any()}
@type optional() :: {:optional, (... -> any())}
@type render_opt() :: {:ssr, boolean()}
@type render_opts() :: [render_opt()]

Functions

Link to this function

assign_errors(conn, map_or_changeset)

View Source
@spec assign_errors(Plug.Conn.t(), data :: Ecto.Changeset.t() | map()) ::
  Plug.Conn.t()

Assigns errors to the Inertia page data. This helper accepts an Ecto.Changeset (and automatically serializes its errors into a shape compatible with Inertia), or a bare map of errors.

If you are serializing your own errors, they should take the following shape:

%{
  "name" => "Name is required",
  "password" => "Password must be at least 5 characters",
  "team.name" => "Team name is required",
}

When assigning a changeset, you may optionally pass a message-generating function to use when traversing errors. See Ecto.Changeset.traverse_errors/2 for more information about the message function.

defp default_msg_func({msg, opts}) do
  Enum.reduce(opts, msg, fn {key, value}, acc ->
    String.replace(acc, "%{#{key}}", fn _ -> to_string(value) end)
  end)
end

This default implementation performs a simple string replacement for error message containing variables, like count. For example, given the following error:

{"should be at least %{count} characters", [count: 3, validation: :length, min: 3]}

The generated description would be "should be at least 3 characters". If you would prefer to use the Gettext module for pluralizing and localizing error messages, you can override the message function:

conn
|> assign_errors(changeset, fn {msg, opts} ->
  if count = opts[:count] do
    Gettext.dngettext(MyAppWeb.Gettext, "errors", msg, msg, count, opts)
  else
    Gettext.dgettext(MyAppWeb.Gettext, "errors", msg, opts)
  end
end)
Link to this function

assign_errors(conn, changeset, msg_func)

View Source
@spec assign_errors(Plug.Conn.t(), data :: Ecto.Changeset.t(), msg_func :: function()) ::
  Plug.Conn.t()
Link to this function

assign_prop(conn, key, value)

View Source
@spec assign_prop(Plug.Conn.t(), atom(), any()) :: Plug.Conn.t()

Assigns a prop value to the Inertia page data.

Link to this function

camelize_props(conn)

View Source (since 1.0.0)
@spec camelize_props(Plug.Conn.t()) :: Plug.Conn.t()

Enable (or disable) automatic conversion of prop keys from snake case (e.g. inserted_at), which is conventional in Elixir, to camel case (e.g. insertedAt), which is conventional in JavaScript.

Examples

Using camelize_props here will convert first_name to firstName in the response props.

conn
|> assign_prop(:first_name, "Bob")
|> camelize_props()
|> render_inertia("Home")

You may also pass a boolean to the camelize_props function (to override any previously-set or globally-configured value):

conn
|> assign_prop(:first_name, "Bob")
|> camelize_props(false)
|> render_inertia("Home")
Link to this function

camelize_props(conn, true_or_false)

View Source
@spec camelize_props(Plug.Conn.t(), boolean()) :: Plug.Conn.t()
Link to this function

clear_history(conn)

View Source (since 1.0.0)
@spec clear_history(Plug.Conn.t()) :: Plug.Conn.t()

Instuct the client-side to clear the history.

Link to this function

clear_history(conn, true_or_false)

View Source
@spec clear_history(Plug.Conn.t(), boolean()) :: Plug.Conn.t()
Link to this function

encrypt_history(conn)

View Source (since 1.0.0)
@spec encrypt_history(Plug.Conn.t()) :: Plug.Conn.t()

Instuct the client-side to encrypt history for this page.

Link to this function

encrypt_history(conn, true_or_false)

View Source
@spec encrypt_history(Plug.Conn.t(), boolean()) :: Plug.Conn.t()
@spec inertia_always(value :: any()) :: always()

Marks a prop value as "always included", which means it will be included in the props on initial page load and subsequent partial loads (even when it's not explicitly requested).

Link to this function

inertia_defer(fun)

View Source (since 1.0.0)
@spec inertia_defer(fun :: (... -> any())) :: defer()

Marks that a prop should fetched immediately after the page is loaded on the client-side.

Link to this function

inertia_defer(fun, group)

View Source
@spec inertia_defer(fun :: (... -> any()), group :: String.t()) :: defer()
Link to this function

inertia_merge(value)

View Source (since 1.0.0)
@spec inertia_merge(value :: any()) :: merge()

Marks that a prop should be merged with existing data on the client-side.

Link to this function

inertia_optional(fun)

View Source (since 1.0.0)
@spec inertia_optional(fun :: (... -> any())) :: optional()

Marks a prop value as optional, which means it will only get evaluated if explicitly requested in a partial reload.

Optional props will only be included the when explicitly requested in a partial reload. If you want to include the prop on first visit, you'll want to use a bare anonymous function or named function reference instead.

conn
# ALWAYS included on first visit...
# OPTIONALLY included on partial reloads...
# ALWAYS evaluated...
|> assign_prop(:cheap_thing, cheap_thing())

# ALWAYS included on first visit...
# OPTIONALLY included on partial reloads...
# ONLY evaluated when needed...
|> assign_prop(:expensive_thing, fn -> calculate_thing() end)
|> assign_prop(:another_expensive_thing, &calculate_another_thing/0)

# NEVER included on first visit...
# OPTIONALLY included on partial reloads...
# ONLY evaluated when needed...
|> assign_prop(:super_expensive_thing, inertia_optional(fn -> calculate_thing() end))
Link to this function

render_inertia(conn, component)

View Source
@spec render_inertia(Plug.Conn.t(), component :: String.t()) :: Plug.Conn.t()

Renders an Inertia response.

Options

  • ssr: whether to server-side render the response (see the docs on "Server-side rendering" in the README for more information on setting this up). Defaults to the globally-configured value, or false if no global config is specified.

Examples

conn
|> assign_prop(:user_id, 1)
|> render_inertia("SettingsPage")

You may pass additional props as map for the third argument:

conn
|> assign_prop(:user_id, 1)
|> render_inertia("SettingsPage", %{name: "Bob"})

You may also pass options for the last positional argument:

conn
|> assign_prop(:user_id, 1)
|> render_inertia("SettingsPage", ssr: true)

conn
|> assign_prop(:user_id, 1)
|> render_inertia("SettingsPage", %{name: "Bob"}, ssr: true)
Link to this function

render_inertia(conn, component, inline_props)

View Source
@spec render_inertia(
  Plug.Conn.t(),
  component :: String.t(),
  inline_props_or_opts :: map() | render_opts()
) :: Plug.Conn.t()
Link to this function

render_inertia(conn, component, inline_props, opts)

View Source
@spec render_inertia(
  Plug.Conn.t(),
  component :: String.t(),
  props :: map(),
  opts :: render_opts()
) :: Plug.Conn.t()