Current section
Files
Jump to
Current section
Files
src/inertia.erl
-module(inertia).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/inertia.gleam").
-export([init/2, from_context/1, add_context/2, shared_add/2, shared_get/1, root_view/1, handle_request/2, add_prop/3, add_error/3, add_once/3, add_defer/4, add_merge/3, add_flash/3, add_flashes/2, new_page_object/2, render/2, redirect/2]).
-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.
-file("src/inertia.gleam", 42).
-spec manifest_entries() -> list(internal@manifest:entry()).
manifest_entries() ->
Manifest_file = gleam@result:unwrap(
internal@template:has_manifest(),
<<""/utf8>>
),
case internal@context:get_orelse(<<"manifest_entries"/utf8>>, []) of
[] when Manifest_file =/= <<""/utf8>> ->
case internal@template:read_file_lines(Manifest_file) of
<<""/utf8>> ->
[];
Lines ->
Entries = internal@manifest:parse(Lines),
internal@context:add_entry(
<<"manifest_entries"/utf8>>,
Entries
),
Entries
end;
[] when Manifest_file =:= <<""/utf8>> ->
[];
Entries@1 ->
Entries@1
end.
-file("src/inertia.gleam", 61).
?DOC(" Initializes the inertia context\n").
-spec init(binary(), binary()) -> nil.
init(App, Version) ->
internal@context:add_entry(<<"app"/utf8>>, App),
internal@context:add_entry(<<"version"/utf8>>, Version).
-file("src/inertia.gleam", 68).
?DOC(" Gets an entry from the inertia context, if it not exists returns an empty String\n").
-spec from_context(binary()) -> binary().
from_context(Name) ->
internal@context:get_orelse(Name, <<""/utf8>>).
-file("src/inertia.gleam", 74).
?DOC(" Adds an entry to the Inertia context\n").
-spec add_context(binary(), binary()) -> nil.
add_context(Name, Value) ->
internal@context:add_entry(Name, Value).
-file("src/inertia.gleam", 80).
?DOC(" Adds a shared value to the Inertia context\n").
-spec shared_add(binary(), binary()) -> nil.
shared_add(Name, Value) ->
internal@context:shared_add_entry(Name, Value).
-file("src/inertia.gleam", 86).
?DOC(" Gets a shared value from the Inertia context\n").
-spec shared_get(binary()) -> binary().
shared_get(Name) ->
internal@context:shared_get_orelse(Name, <<""/utf8>>).
-file("src/inertia.gleam", 93).
?DOC(
" Creates the root view based on index.html file when the request is a full page load.\n"
" If the index.html file is not found, it will render a default error message\n"
).
-spec root_view(binary()) -> binary().
root_view(State) ->
App_name = internal@context:get_orelse(<<"app"/utf8>>, <<""/utf8>>),
Pdir = gleam@result:unwrap(
fun gleam_erlang_ffi:priv_directory/1(App_name),
<<""/utf8>>
),
Entries = manifest_entries(),
case internal@template:read_template(Pdir) of
{ok, Content} ->
internal@template:parse_template(Content, State, Entries);
_ ->
<<"
<html lang='en'>
<head>
<title>Inertia Error</title>
</head>
<body>
<h1 style='color:red;padding:4px;font-size:24px'>Error: No root template</h1>
</body>
</html>
"/utf8>>
end.
-file("src/inertia.gleam", 106).
?DOC(" Handle request middleware that manages all Inertia requests\n").
-spec handle_request(
gleam@http@request:request(wisp@internal:connection()),
fun((gleam@http@request:request(wisp@internal:connection())) -> gleam@http@response:response(wisp:body()))
) -> gleam@http@response:response(wisp:body()).
handle_request(Req, Next) ->
_pipe = Next(Req),
_pipe@1 = fun gleam@http@response:set_header/3(
_pipe,
<<"X-Inertia"/utf8>>,
<<"true"/utf8>>
),
_pipe@2 = fun gleam@http@response:set_header/3(
_pipe@1,
<<"Vary"/utf8>>,
<<"X-Inertia"/utf8>>
),
fun gleam@http@response:set_header/3(
_pipe@2,
<<"X-Inertia-Version"/utf8>>,
internal@context:get_orelse(<<"version"/utf8>>, <<"v1"/utf8>>)
).
-file("src/inertia.gleam", 115).
?DOC(" Adds a basic property to be injected on the client. The value must be a `json.Json` value\n").
-spec add_prop(internal@props:page_object(), binary(), gleam@json:json()) -> internal@props:page_object().
add_prop(Self, Name, Value) ->
New_props = lists:append(
erlang:element(4, Self),
[{base_prop, Name, Value}]
),
{page_object,
erlang:element(2, Self),
erlang:element(3, Self),
New_props,
erlang:element(5, Self),
erlang:element(6, Self),
erlang:element(7, Self),
erlang:element(8, Self),
erlang:element(9, Self)}.
-file("src/inertia.gleam", 126).
?DOC(" Adds an error property. The value must be a `json.Json` value\n").
-spec add_error(internal@props:page_object(), binary(), gleam@json:json()) -> internal@props:page_object().
add_error(Self, Name, Value) ->
New_errors = lists:append(
erlang:element(5, Self),
[{error_prop, Name, Value}]
),
{page_object,
erlang:element(2, Self),
erlang:element(3, Self),
erlang:element(4, Self),
New_errors,
erlang:element(6, Self),
erlang:element(7, Self),
erlang:element(8, Self),
erlang:element(9, Self)}.
-file("src/inertia.gleam", 137).
?DOC(" Adds an once property. The property value must be a function that returns a `json.Json` value.\n").
-spec add_once(
internal@props:page_object(),
binary(),
fun(() -> gleam@json:json())
) -> internal@props:page_object().
add_once(Self, Name, Value) ->
New_props = lists:append(
erlang:element(4, Self),
[{once_prop, Name, Value}]
),
{page_object,
erlang:element(2, Self),
erlang:element(3, Self),
New_props,
erlang:element(5, Self),
erlang:element(6, Self),
erlang:element(7, Self),
erlang:element(8, Self),
erlang:element(9, Self)}.
-file("src/inertia.gleam", 149).
?DOC(
" Adds a deferred property. Usually, a deferred property is a time-consuming function that will take time\n"
" to generate its outcome. The property value is a function that returns `Result(json.Json, Nil)`\n"
).
-spec add_defer(
internal@props:page_object(),
binary(),
fun(() -> {ok, gleam@json:json()} | {error, nil}),
gleam@option:option(binary())
) -> internal@props:page_object().
add_defer(Self, Name, Value, Group) ->
New_props = lists:append(
erlang:element(6, Self),
[{defer_prop, Name, Value, Group}]
),
{page_object,
erlang:element(2, Self),
erlang:element(3, Self),
erlang:element(4, Self),
erlang:element(5, Self),
New_props,
erlang:element(7, Self),
erlang:element(8, Self),
erlang:element(9, Self)}.
-file("src/inertia.gleam", 162).
?DOC(" Adds a Merge property\n").
-spec add_merge(
internal@props:page_object(),
binary(),
fun(() -> gleam@json:json())
) -> internal@props:page_object().
add_merge(Self, Name, Value) ->
New_props = lists:append(
erlang:element(4, Self),
[{merge_prop, Name, Value}]
),
{page_object,
erlang:element(2, Self),
erlang:element(3, Self),
New_props,
erlang:element(5, Self),
erlang:element(6, Self),
erlang:element(7, Self),
erlang:element(8, Self),
erlang:element(9, Self)}.
-file("src/inertia.gleam", 173).
?DOC(" Adds a flash message on the request. The flash message value IS NOT persisted between requests.\n").
-spec add_flash(
gleam@http@request:request(wisp@internal:connection()),
binary(),
binary()
) -> gleam@http@request:request(wisp@internal:connection()).
add_flash(Req, Name, Value) ->
internal@flash:set_flash_message(Req, Name, Value).
-file("src/inertia.gleam", 183).
?DOC(" Adds multiple flash messages on the request. The flash message value IS NOT persisted between requests.\n").
-spec add_flashes(
gleam@http@request:request(wisp@internal:connection()),
list(internal@flash:flash_prop())
) -> gleam@http@request:request(wisp@internal:connection()).
add_flashes(Req, Messages) ->
internal@flash:set_flash_messages(Req, Messages).
-file("src/inertia.gleam", 192).
?DOC(" Creates a page object that will manage all properties for the current page component.\n").
-spec new_page_object(
gleam@http@request:request(wisp@internal:connection()),
binary()
) -> internal@props:page_object().
new_page_object(Req, Component) ->
{page_object,
Component,
erlang:element(8, Req),
gleam@list:new(),
gleam@list:new(),
gleam@list:new(),
internal@props:dict_to_prop(internal@context:shared_get_all()),
internal@context:get_orelse(<<"version"/utf8>>, <<"v1"/utf8>>),
none}.
-file("src/inertia.gleam", 208).
-spec new_render_context(gleam@http@request:request(wisp@internal:connection())) -> internal@props:render_context().
new_render_context(Req) ->
Component = begin
_pipe = gleam@http@request:get_header(
Req,
<<"X-Inertia-Partial-Component"/utf8>>
),
gleam@result:unwrap(_pipe, <<""/utf8>>)
end,
Excepts = case gleam@http@request:get_header(
Req,
<<"X-Inertia-Except-Once-Props"/utf8>>
) of
{ok, Str} ->
gleam@string:split(Str, <<","/utf8>>);
{error, _} ->
[]
end,
Partials = case gleam@http@request:get_header(
Req,
<<"X-Inertia-Partial-Data"/utf8>>
) of
{ok, Str@1} ->
gleam@string:split(Str@1, <<","/utf8>>);
{error, _} ->
[]
end,
Resets = case gleam@http@request:get_header(Req, <<"X-Inertia-Reset"/utf8>>) of
{ok, Str@2} ->
gleam@string:split(Str@2, <<","/utf8>>);
{error, _} ->
[]
end,
First_load = case {Component, Partials} of
{<<""/utf8>>, []} ->
true;
{_, _} ->
false
end,
Version = internal@context:get_orelse(<<"version"/utf8>>, <<"v1"/utf8>>),
{render_context,
Req,
Component,
Version,
First_load,
Resets,
Partials,
Excepts}.
-file("src/inertia.gleam", 251).
?DOC(
" Renders a Inertia component based on the PageObject.\n"
"\n"
" #Example:\n"
" ```gleam\n"
" inertia.new_page_object(req, \"index)\n"
" |> inertia.render(req)\n"
" ```\n"
).
-spec render(
internal@props:page_object(),
gleam@http@request:request(wisp@internal:connection())
) -> gleam@http@response:response(wisp:body()).
render(Page_object, Req) ->
Po = begin
_pipe = Page_object,
_pipe@1 = internal@props:page_object_to_json(
_pipe,
new_render_context(Req)
),
gleam@json:to_string(_pipe@1)
end,
case gleam@http@request:get_header(Req, <<"X-Inertia"/utf8>>) of
{ok, _} ->
wisp:json_body(wisp:ok(), Po);
_ ->
wisp:html_body(wisp:ok(), root_view(Po))
end.
-file("src/inertia.gleam", 274).
?DOC(
" Creates a reponse with status code 303 for Post, Patch, Put or Delete request,\n"
" otherwise the status code is 302\n"
"\n"
" #Example\n"
" ```gleam\n"
" inertia.redirect(req, \"/\")\n"
" ```\n"
).
-spec redirect(gleam@http@request:request(wisp@internal:connection()), binary()) -> gleam@http@response:response(wisp:body()).
redirect(Req, Path) ->
case erlang:element(2, Req) of
post ->
Cookies = begin
_pipe = erlang:element(3, Req),
gleam@list:filter(
_pipe,
fun(Pair) ->
erlang:element(1, Pair) =:= <<"inertia_flash"/utf8>>
end
)
end,
case Cookies of
[Ic] ->
_pipe@1 = wisp:redirect(Path),
wisp:set_cookie(
_pipe@1,
Req,
erlang:element(1, Ic),
erlang:element(2, Ic),
plain_text,
10
);
_ ->
wisp:redirect(Path)
end;
put ->
Cookies = begin
_pipe = erlang:element(3, Req),
gleam@list:filter(
_pipe,
fun(Pair) ->
erlang:element(1, Pair) =:= <<"inertia_flash"/utf8>>
end
)
end,
case Cookies of
[Ic] ->
_pipe@1 = wisp:redirect(Path),
wisp:set_cookie(
_pipe@1,
Req,
erlang:element(1, Ic),
erlang:element(2, Ic),
plain_text,
10
);
_ ->
wisp:redirect(Path)
end;
patch ->
Cookies = begin
_pipe = erlang:element(3, Req),
gleam@list:filter(
_pipe,
fun(Pair) ->
erlang:element(1, Pair) =:= <<"inertia_flash"/utf8>>
end
)
end,
case Cookies of
[Ic] ->
_pipe@1 = wisp:redirect(Path),
wisp:set_cookie(
_pipe@1,
Req,
erlang:element(1, Ic),
erlang:element(2, Ic),
plain_text,
10
);
_ ->
wisp:redirect(Path)
end;
delete ->
Cookies = begin
_pipe = erlang:element(3, Req),
gleam@list:filter(
_pipe,
fun(Pair) ->
erlang:element(1, Pair) =:= <<"inertia_flash"/utf8>>
end
)
end,
case Cookies of
[Ic] ->
_pipe@1 = wisp:redirect(Path),
wisp:set_cookie(
_pipe@1,
Req,
erlang:element(1, Ic),
erlang:element(2, Ic),
plain_text,
10
);
_ ->
wisp:redirect(Path)
end;
_ ->
{response, 302, [{<<"location"/utf8>>, Path}], {text, <<""/utf8>>}}
end.