I have an umbrella app. Most of the apps are regular OTP apps. I also have an Api app that is a phoenix app (has an endpoint/router/etc.) This is the main app for incoming requests. I am adding an Admin app to my umbrella which will also have an endpoint/router/etc, but I want it totally separated from the Api. Currently my Api forwards /admin calls to the admin endpoint like this:
scope “/admin” do
forward("/", AdminWeb.Endpoint)
end
This all works great, and it renders the page, except the Routes.static_path generates /images/something.png instead of /admin/images/something.png. Since all paths generated in the Admin app, will be routed through the Api app, is there a way to append “/admin” to all path helpers in the Admin app?
Does changing the config for AdminWeb.Endpoint to include url: [path: "/admin"] work? The docs mention using it when hosting behind rewrite rules, which this use of forward kinda is.
Author: Ryan Kelker <... no spam ...>
Date: Thu Apr 11 13:39:50 2019 -0400
Add the `:prefix` option to the resources builder
diff --git a/lib/phoenix/router/resource.ex b/lib/phoenix/router/resource.ex
index 043d2ddf..5bf35476 100644
--- a/lib/phoenix/router/resource.ex
+++ b/lib/phoenix/router/resource.ex
@@ -28,7 +28,8 @@ defmodule Phoenix.Router.Resource do
Builds a resource struct.
"""
def build(path, controller, options) when is_atom(controller) and is_list(options) do
- path = Phoenix.Router.Scope.validate_path(path)
+ prefix = Keyword.get(options, :prefix, "")
+ path = Phoenix.Router.Scope.validate_path(prefix <> path)
alias = Keyword.get(options, :alias)
param = Keyword.get(options, :param, @default_param_key)
name = Keyword.get(options, :name, Phoenix.Naming.resource_name(controller, "Controller"))
You can now do the following if you wish.
scope "/", DevAppWeb do
pipe_through :browser
# This route can be found at /example/abc
# Routes.page_path(@conn, :index) => /example/abc
resources "/abc", PageController, only: [:index], prefix: "example"
end
Edit: I’m clearly tired because this code has nothing to do with the helpers. Let me think about this again. LOL!
Try writing a plug like this and possibly adding it to an existing pipeline.
defmodule DevAppWeb.ExamplePlug do
import Phoenix.Controller, only: [redirect: 2]
def init(default), do: default
@prefix "/admin"
def call(conn, _default) do
with %{request_path: path} = conn do
cond do
String.starts_with?(path, @prefix) -> conn
true -> redirect conn, to: @prefix <> path
end
end
end
end
I think the simplest solution at the moment would be to write a wrapper for the helper and make it accessible to the view via your_app_web.ex.
in your_app_web.ex, you might do something like this.
def view do
quote do
use Phoenix.View,
root: "lib/dev_app_web/templates",
namespace: DevAppWeb
# ... snip ... #
alias YourAppWeb.MyHelpers, as: AdminHelper
end
end
That is ‘essentially’ what I’m doing, the problem is remembering to do that every time I add a new forward. ^.^
I have my application broken up into dependencies, each of which just gets forwarded to among other automated setups based on what is detected automatically at compile time, but names are still made and changed manually on occasion.