sixFingers / phamello

A Phoenix + Amazon S3 + Trello integration example

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Dynamic Plug.Static configuration at run time

nguyenvinhlinh opened this issue · comments

Dear,
I have read your configuration file at link and your chat discussion at link. Honestly, I am obsessed to 12-factors. and I am now facing the same problem as yours in the chat log. I did try to make a plug myself but It does not work well.

Here is my plug:

defmodule ImageSharing.Plug.StaticUploadAsset do
  import Plug.Conn

  def init(args) do
    args
  end

  def call(conn, _) do
    Plug.Static.call(conn,
      at: "/uploads",
      from: Application.get_env(:image_sharing, :file_store_path))
  end
end

Also here is how my route.ex look like.

defmodule ImageSharing.Router do
  use ImageSharing.Web, :router
  
  pipeline :browser do
    plug ImageSharing.Plug.StaticUploadAsset
    plug :accepts, ["html"]
    plug :fetch_session
    plug :fetch_flash
    plug :protect_from_forgery
    plug :put_secure_browser_headers    
  end
  
  scope "/", ImageSharing do
    pipe_through :browser
    get "/", PageController, :index
    get "/images/random", ImageController, :random_image
    resources "/images", ImageController, except: [:edit, :update, :delete]    
  end
end

I am stucking at this issue and I cannot fix it. In addition, I did look at your repo with a hope to resolve this issue but not. If you are still interesting at this issue please ping back. I am lost to the Plug workflow.

Hello,

I'm not aware of this project but I stumbled on this when I was searching for a solution for the same problem you are.

Your code helped me out achieving what I think it's what you want too!

Here's what I've had to do...

Plug

defmodule MyApp.Plug.Assets do
  alias Plug.Static

  def init(opts), do: opts

  def call(conn, _opts) do
    plug_opts = Static.init(at: "/my-assets", from: "priv/static", gzip: false,
                                               only: ~w(css fonts images js favicon.ico robots.txt))
    
    Static.call(conn, plug_opts)
  end
end

Router

defmodule MyApp.Router do
  ...

  pipeline :browser do
    ...
    plug MyApp.Plug.Assets
    ...
  end

  scope "/" do
    get "/*path", FallbackController, :not_found # this is important
  end
  ...
end

I believe your plugin wasn't working for two reasons:

  1. As you can see here on section "Module plugs":

The result returned by init/1 is passed as second argument to call/2

  1. The catch-all route defined above is what allows as to match "/my-assets/css/x/y", otherwise our plug would never be called since no route matched (for what I understand here plugs in pipelines are only called when a route matches, which actually makes sense).

Hope this help you out! Good luck! (and thank you for helping me too 👍)