Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions .github/labeler.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
labels:
code-change:
- changed-files:
- any-glob-to-any-file:
- "src/**"
- "include/**"
- "priv/**"
- "**/*.erl"
- "**/*.hrl"
- "**/*.app.src"
- "**/*.app"
documentation:
- changed-files:
- '*.md'
2 changes: 1 addition & 1 deletion guides/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ These parameters can be specified in your *main* application (Eg the one you've
|-----|-------------|-------|
| `json_lib` | JSON lib to use. Read more in the subsection *Configure json lib* | `atom()` |
| `watchers` | Watchers are external programs that will run together with Nova. Watchers are defined as list of tuples where the tuples is in format `{Command, ArgumentList}` (Like `[{my_app, "npm", ["run", "watch"], #{workdir => "priv/assets/js/my-app"}}]`) | `[{string(), string()}] | [{atom(), string(), map()}] | [{atom(), string(), list(), map()}]` |

| `router_module` | Module that contains the `routes/1` callback | `atom()` |


### Configure json_lib
Expand Down
11 changes: 11 additions & 0 deletions guides/multi-app.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,14 @@ There's currently two different options available and they works in the same way
]}
...
```

## Pragmatically starting other nova applications

### Starting an application

You can also start other nova applications pragmatically by calling `nova_sup:add_application/2` to add another nova application to your supervision tree. The routes will automatically be added to the routing-module.


## Stopping an application

To stop a nova application you can call `nova_sup:remove_application/1` with the name of the application you want to stop. Use this with caution since calling this method all routes for all other applications will be removed and re-added in order to filter out the one removed.
2 changes: 1 addition & 1 deletion include/nova_router.hrl
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
callback :: function() | undefined,
plugins = [] :: list(),
secure = false :: false | {Mod :: atom(), Fun :: atom()},
extra_state :: any()
extra :: any()
}).

-record(cowboy_handler_value, {
Expand Down
1 change: 0 additions & 1 deletion rebar.config
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
{cowboy, "2.13.0"},
{erlydtl, "0.14.0"},
{jhn_stdlib, "5.4.0"},
{routing_tree, "1.0.11"},
{thoas, "1.2.1"}
]}.

Expand Down
1 change: 1 addition & 0 deletions src/nova.erl
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ use_stacktrace(_) ->
%% the module, function, arity, file, and line number of the
%% function call.
%% @end
%%--------------------------------------------------------------------
-spec format_stacktrace(Stacktrace :: [{M :: atom(), F :: atom(), A :: integer(), Info :: list()}])
-> [map()].
format_stacktrace(Stacktrace) ->
Expand Down
18 changes: 1 addition & 17 deletions src/nova_basic_handler.erl
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,7 @@ handle_ws(ok, State) ->
%%%===================================================================

handle_view(View, Variables, Options, Req) ->
{ok, HTML} = render_dtl(View, Variables, []),
{ok, HTML} = View:render(Variables, []),
Headers =
case maps:get(headers, Options, undefined) of
undefined ->
Expand All @@ -303,22 +303,6 @@ handle_view(View, Variables, Options, Req) ->
Req2 = Req1#{resp_status_code => StatusCode},
{ok, Req2}.

render_dtl(View, Variables, Options) ->
case code:is_loaded(View) of
false ->
case code:load_file(View) of
{error, Reason} ->
%% Cast a warning since the module could not be found
?LOG_ERROR(#{msg => <<"Nova could not render template">>, template => View, reason => Reason}),
throw({404, {template_not_found, View}});
_ ->
View:render(Variables, Options)
end;
_ ->
View:render(Variables, Options)
end.


get_view_name({Mod, _Opts}) -> get_view_name(Mod);
get_view_name(Mod) when is_atom(Mod) ->
StrName = get_view_name(erlang:atom_to_list(Mod)),
Expand Down
143 changes: 143 additions & 0 deletions src/nova_request.erl
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
%%%-------------------------------------------------------------------
%%% @author Niclas Axelsson <burbas@MBPsomtrNiclas3.kgh.local>
%%% @copyright (C) 2024, Niclas Axelsson
%%% @doc
%%%
%%% @end
%%% Created : 22 Dec 2024 by Niclas Axelsson <burbas@MBPsomtrNiclas3.kgh.local>
%%%-------------------------------------------------------------------
-module(nova_request).

-behaviour(gen_server).

%% API
-export([
start_link/0
]).

%% gen_server callbacks
-export([
init/1,
handle_call/3,
handle_cast/2,
handle_info/2,
terminate/2,
code_change/3
]).

-define(SERVER, ?MODULE).

-record(state, {}).

%%%===================================================================
%%% API
%%%===================================================================

%%--------------------------------------------------------------------
%% @doc
%% Starts the server
%% @end
%%--------------------------------------------------------------------
-spec start_link() -> {ok, Pid :: pid()} |
{error, Error :: {already_started, pid()}} |
{error, Error :: term()} |
ignore.
start_link() ->
gen_server:start_link({local, ?SERVER}, ?MODULE, [], []).

%%%===================================================================
%%% gen_server callbacks
%%%===================================================================

%%--------------------------------------------------------------------
%% @private
%% @doc
%% Initializes the server
%% @end
%%--------------------------------------------------------------------
-spec init(Args :: term()) -> {ok, State :: term()} |
{ok, State :: term(), Timeout :: timeout()} |
{ok, State :: term(), hibernate} |
{stop, Reason :: term()} |
ignore.
init([]) ->
process_flag(trap_exit, true),
{ok, #state{}}.

%%--------------------------------------------------------------------
%% @private
%% @doc
%% Handling call messages
%% @end
%%--------------------------------------------------------------------
-spec handle_call(Request :: term(), From :: {pid(), term()}, State :: term()) ->
{reply, Reply :: term(), NewState :: term()} |
{reply, Reply :: term(), NewState :: term(), Timeout :: timeout()} |
{reply, Reply :: term(), NewState :: term(), hibernate} |
{noreply, NewState :: term()} |
{noreply, NewState :: term(), Timeout :: timeout()} |
{noreply, NewState :: term(), hibernate} |
{stop, Reason :: term(), Reply :: term(), NewState :: term()} |
{stop, Reason :: term(), NewState :: term()}.
handle_call(_Request, _From, State) ->
Reply = ok,
{reply, Reply, State}.

%%--------------------------------------------------------------------
%% @private
%% @doc
%% Handling cast messages
%% @end
%%--------------------------------------------------------------------
-spec handle_cast(Request :: term(), State :: term()) ->
{noreply, NewState :: term()} |
{noreply, NewState :: term(), Timeout :: timeout()} |
{noreply, NewState :: term(), hibernate} |
{stop, Reason :: term(), NewState :: term()}.
handle_cast(_Request, State) ->
{noreply, State}.

%%--------------------------------------------------------------------
%% @private
%% @doc
%% Handling all non call/cast messages
%% @end
%%--------------------------------------------------------------------
-spec handle_info(Info :: timeout() | term(), State :: term()) ->
{noreply, NewState :: term()} |
{noreply, NewState :: term(), Timeout :: timeout()} |
{noreply, NewState :: term(), hibernate} |
{stop, Reason :: normal | term(), NewState :: term()}.
handle_info(_Info, State) ->
{noreply, State}.

%%--------------------------------------------------------------------
%% @private
%% @doc
%% This function is called by a gen_server when it is about to
%% terminate. It should be the opposite of Module:init/1 and do any
%% necessary cleaning up. When it returns, the gen_server terminates
%% with Reason. The return value is ignored.
%% @end
%%--------------------------------------------------------------------
-spec terminate(Reason :: normal | shutdown | {shutdown, term()} | term(),
State :: term()) -> any().
terminate(_Reason, _State) ->
ok.

%%--------------------------------------------------------------------
%% @private
%% @doc
%% Convert process state when code is changed
%% @end
%%--------------------------------------------------------------------
-spec code_change(OldVsn :: term() | {down, term()},
State :: term(),
Extra :: term()) -> {ok, NewState :: term()} |
{error, Reason :: term()}.
code_change(_OldVsn, State, _Extra) ->
{ok, State}.

%%%===================================================================
%%% Internal functions
%%%===================================================================
Loading
Loading