I’ve been playing with Macro’s after reading Metaprogramming Elixir by @chrismccord.
As a result :phx_alt_routes was born, albeit in a private repository. First I want to validate the concept. It already works with dead views and live views. Simply by
- creating one config module (adapter)
- replacing alias
MyWebApp.Router.Helperswithuse MyWebApp.AltRoutes.Router.Helpers, MyWebApp.Router.Helpersin my_web_app.ex - adding
Phx.AltRoutes.MountHelperto the :live_view set. - adding
Phx.AltRoutes.Plugto the connection plug set
Phx.AltRoutes.Router
Provides a set of macros for generating alternative Phoenix routes with configurable assignments.
When a Gettext module is defined in the configuration, the alt_scope/2 macro uses it to build the alternative routes using the Gettext module. This allows routes to be translated along with other Gettext messages.
To summarize the process.
- The
alt_scope/2macro splits the path of every nested route. - The segments are extracted into
routes.pofiles usingmix gettext.extract. - The individual segments are translated
- The translations are used to create additional alternative routes with path
{prefix}/{translated_segment1}/{translated_segment2}/and helper{prefix}_{original_helper} - For every alternative route the configured bindings are added to
assignsandsession. - A few helper assignments are also added, which can be used by
Phx.AltRoutes.Router.Helpers
Example
Given this configuration:
defmodule MyAppWeb.Phx.AltRoutes do
use Phx.AltRoutes,
routes: %{
"dutch" => %{
path_prefix: "nl",
bindings: %{locale: "nl_NL"},
},
"english" => %{
path_prefix: "en",
bindings: %{ocale: "en_GB"},
},
},
gettext_module: MyAppWeb.Gettext
To generate alternative routes for routes, those routes are nested in a alt_scope.
defmodule MyAppWeb.Router do
use Phoenix.Router
alt_scope MyAppWeb.Phx.AltRoutes do
get "/users/:id/edit", UserController, :edit
get "/users/show/:id", UserController, :show
end
end
This will generate routes.po files including the entries for users, edit and show. You can translate the segments. The macro expand the routes during compile time with alternative variants. The example above is equal to:
defmodule MyAppWeb.Router do
use Phoenix.Router
scope "/" do
get "/users/:id/edit", UserController, :edit
get "/users/show/:id", UserController, :show
scope "/en" do
get "/users/:id/edit", UserController, :edit, assigns: %{locale: "en_GB", helper_prefix: "en"}, session: %{"locale": "en_GB", helper_prefix: "en"}, as: :en_user_edit_path
get "/users/show/:id", UserController, :show, assigns: %{locale: "en_GB", helper_prefix: "en"}, session: %{"locale": "en_GB", helper_prefix: "en"} , as: :en_user_show_path
end
scope "/nl" do
get "/gebruikers/:id/bewerken", UserController, :edit, assigns: %{locale: "nl_NL", helper_prefix: "nl"}, session: %{"locale": "nl_NL", helper_prefix: "nl"}, as: :nl_user_edit_path
get "/gebruikers/tonen/:id", UserController, :show, :edit, assigns: %{locale: "nl_NL", helper_prefix: "nl"}, session: %{"locale": "nl_NL", helper_prefix: "nl"}, as: :nl_user_show_path
end
end
The routes can be nested, which makes it easy to create /region/sub-region/ routes.
Phx.AltRoutes.Router.Helpers
Provides a macro that wraps Phoenix.Router.Helpers functions in order to generates the correct alternative route. It uses the helper_prefix assignment added to the session by Phx.AltRoutes.Router.
Thinking of it…the assignments can probably be fetched using only the helper_prefix key…






















