Skip to content

Instantly share code, notes, and snippets.

@mazz
Created February 20, 2019 22:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mazz/4a61a0033b445b4928f36b91d3a01fb2 to your computer and use it in GitHub Desktop.
Save mazz/4a61a0033b445b4928f36b91d3a01fb2 to your computer and use it in GitHub Desktop.
Phoenix.Template.UndefinedError
Phoenix.Template.UndefinedError at GET /
Could not render "app.html" for WordApi.LayoutView, please define a matching clause for render/2 or define a template at "lib/faithful_word_api/templates/layout". No templates were compiled for this module. Assigns:
%{__phx_template_not_found__: WordApi.LayoutView, conn: %Plug.Conn{adapter: {Plug.Cowboy.Conn, :...}, assigns: %{layout: {WordApi.LayoutView, "app.html"}}, before_send: [#Function<0.116269836/1 in Plug.CSRFProtection.call/2>, #Function<2.65282597/1 in Phoenix.Controller.fetch_flash/2>, #Function<0.58261320/1 in Plug.Session.before_send/2>, #Function<1.112466771/1 in Plug.Logger.call/2>, #Function<0.66982185/1 in Phoenix.LiveReloader.before_send_inject_reloader/2>], body_params: %{}, cookies: %{"cookieconsent_status" => "dismiss"}, halted: false, host: "localhost", method: "GET", owner: #PID<0.736.0>, params: %{}, path_info: [], path_params: %{}, port: 4000, private: %{WordApi.Router => {[], %{}}, :phoenix_action => :index, :phoenix_controller => WordApi.PageController, :phoenix_endpoint => WordApi.Endpoint, :phoenix_flash => %{}, :phoenix_format => "html", :phoenix_layout => {WordApi.LayoutView, :app}, :phoenix_pipelines => [:browser], :phoenix_router => WordApi.Router, :phoenix_template => "index.html", :phoenix_view => WordApi.PageView, :plug_session => %{}, :plug_session_fetch => :done}, query_params: %{}, query_string: "", remote_ip: {127, 0, 0, 1}, req_cookies: %{"cookieconsent_status" => "dismiss"}, req_headers: [{"accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"}, {"accept-encoding", "gzip, deflate"}, {"accept-language", "en-US,en;q=0.5"}, {"cache-control", "max-age=0"}, {"connection", "keep-alive"}, {"cookie", "cookieconsent_status=dismiss"}, {"host", "localhost:4000"}, {"upgrade-insecure-requests", "1"}, {"user-agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.13; rv:65.0) Gecko/20100101 Firefox/65.0"}], request_path: "/", resp_body: nil, resp_cookies: %{}, resp_headers: [{"cache-control", "max-age=0, private, must-revalidate"}, {"x-request-id", "2m2j0nl502o92uhe0k000io1"}, {"x-frame-options", "SAMEORIGIN"}, {"x-xss-protection", "1; mode=block"}, {"x-content-type-options", "nosniff"}, {"strict-transport-security", "max-age=31536000; includeSubDomains"}, {"x-download-options", "noopen"}, {"x-permitted-cross-domain-policies", "none"}, {"cross-origin-window-policy", "deny"}], scheme: :http, script_name: [], secret_key_base: :..., state: :unset, status: nil}, view_module: WordApi.PageView, view_template: "index.html"}
Assigned keys: [:__phx_template_not_found__, :conn, :view_module, :view_template]
@mazz
Copy link
Author

mazz commented Feb 20, 2019

layout_view.ex:

defmodule WordApi.LayoutView do
  use WordApi, :view
end

@mazz
Copy link
Author

mazz commented Feb 20, 2019

page_controller.ex:

defmodule WordApi.PageController do
  use WordApi, :controller
  alias WordApi.Guardian

  def index(conn, _params) do
    conn
    # |> assign(:users, Accounts.list_users())
    # |> assign(:current_user, Guardian.Plug.current_resource(conn))
    # |> render("index.html")
    render(conn, "index.html")

  #   |> send_resp(200, """  <== this renders 'index' OK
  #   index
  # """)
  end

  def about(conn, _params) do
    render(conn, "about.html")
  end

end

@mazz
Copy link
Author

mazz commented Feb 20, 2019

screen shot 2019-02-20 at 5 25 55 pm

@mazz
Copy link
Author

mazz commented Feb 20, 2019

defmodule WordApi.Router do
  use WordApi, :router
  alias Word.Authenticator.GuardianImpl


  # ---- Pipelines ----

  pipeline :api do
    plug(:accepts, ["json"])
  end

  pipeline :api_auth do
    plug(GuardianImpl.Pipeline)
    plug(Guardian.Plug.VerifyHeader, realm: "Bearer")
    plug(Guardian.Plug.LoadResource, allow_blank: true)
  end

  # -------- Routes --------
  scope "/", WordApi do
    pipe_through([:api])

    # return "/music/\(uuid)/media"
    # case .music(_):
    #     return "/music"

    scope "/v1.2" do
      scope "/books" do
        get "/", BookController, :indexv12
        get "/:bid/media", MediaChapterController, :indexv12
      end
      scope "/gospels" do
        get "/", GospelController, :indexv12
        get "/:gid/media", MediaGospelController, :indexv12
      end
      scope "/music" do
        get "/", MusicController, :indexv12
        get "/:mid/media", MediaMusicController, :indexv12
      end
      scope "/languages" do
        get "/supported", LanguageIdentifierController, :indexv12
      end
      scope "/app" do
        get "/versions", AppVersionController, :indexv12
      end
      scope "/device" do
        post "/pushtoken/update", ClientDeviceController, :indexv12
      end
    end

    scope "/v1.3" do
      scope "/books" do
        get "/", BookController, :index
        get "/:uuid/media", MediaChapterController, :index
      end
      scope "/gospels" do
        get "/", GospelController, :index
        get "/:uuid/media", MediaGospelController, :index
      end
      scope "/music" do
        get "/", MusicController, :index
        get "/:uuid/media", MediaMusicController, :index
      end
      scope "/languages" do
        get "/supported", LanguageIdentifierController, :index
      end
      scope "/app" do
        get "/versions", AppVersionController, :index
      end
      scope "/device" do
        post "/pushtoken/update", ClientDeviceController, :index
      end
    end
  end

  # scope "/v1.3", WordApi do
  #   pipe_through(:api)

  #   get "/books", BookController, :index
  #   # post("/sessions", SessionController, :create)
  #   # post("/users", UserController, :create)

  #   # post("/sessions", SessionController, :create)
  #   # post("/users", UserController, :create)
  # end

  scope "/", WordApi do
    pipe_through([:api])

    # ---- Public endpoints ----
    # get("/", ApiInfoController, :get)
    # get("/videos", VideoController, :index)
    # get("/speakers/:slug_or_id", SpeakerController, :show)
    # post("/search/video", VideoController, :search)
    # get("/videos/:video_id/statements", StatementController, :get)
    # get("/newsletter/unsubscribe/:token", UserController, :newsletter_unsubscribe)

    # ---- Authenticathed endpoints ----
    scope "/" do
      pipe_through([:api_auth])

      # Authentication
      scope "/auth" do
        delete("/", AuthController, :logout)
        delete("/:provider/link", AuthController, :unlink_provider)
        post("/:provider/callback", AuthController, :callback)
      end

      # Users
      scope "/users" do
        post("/", UserController, :create)
        post("/request_invitation", UserController, :request_invitation)
        get("/username/:username", UserController, :show)

        scope "/reset_password" do
          post("/request", UserController, :reset_password_request)
          get("/verify/:token", UserController, :reset_password_verify)
          post("/confirm", UserController, :reset_password_confirm)
        end

        scope "/me" do
          get("/", UserController, :show_me)
          put("/", UserController, :update)
          delete("/", UserController, :delete)
          get("/available_flags", UserController, :available_flags)
          put("/confirm_email/:token", UserController, :confirm_email)
          put("/achievements/:achievement", UserController, :unlock_achievement)
          post("/onboarding/complete_step", UserController, :complete_onboarding_step)
          post("/onboarding/complete_steps", UserController, :complete_onboarding_steps)
          delete("/onboarding", UserController, :delete_onboarding)
        end
      end

      # Videos
      post("/videos", VideoController, :get_or_create)

      # Moderation
      get("/moderation/random", ModerationController, :random)
      post("/moderation/feedback", ModerationController, :post_feedback)
    end



  pipeline :browser do
    plug :accepts, ["html"]
    plug :fetch_session
    plug :fetch_flash
    plug :protect_from_forgery
    plug :put_secure_browser_headers
    plug(GuardianImpl.Pipeline)

    # plug WordApi.Plugs.GuardianPipeline
  end

  scope "/", WordApi do
    pipe_through :browser # Use the default browser stack

    get "/", PageController, :index
    get "/about", PageController, :about
    get "/login", LoginController, :new
    post "/login", LoginController, :create
    get "/signup", SignupController, :new
    post "/signup", SignupController, :create
    # get "/login/:magic_token", LoginController, :callback
  end


  end


  defp handle_errors(conn, %{kind: kind, reason: reason, stack: stacktrace}) do
    conn =
      conn
      |> Plug.Conn.fetch_cookies()
      |> Plug.Conn.fetch_query_params()

    params =
      case conn.params do
        %Plug.Conn.Unfetched{aspect: :params} -> "unfetched"
        other -> other
      end

    occurrence_data = %{
      "request" => %{
        "cookies" => conn.req_cookies,
        "url" => "#{conn.scheme}://#{conn.host}:#{conn.port}#{conn.request_path}",
        "user_ip" => List.to_string(:inet.ntoa(conn.remote_ip)),
        "headers" => filter_headers(conn),
        "method" => conn.method,
        "params" => filter_params(params)
      }
    }

    Word.Errors.do_report(kind, reason, stacktrace, data: occurrence_data)
  end

  defp filter_headers(conn) do
    for {key, value} = tuple <- conn.req_headers, into: %{} do
      case key do
        "authorization" ->
          {key, filter_str(value, 16)}

        _ ->
          tuple
      end
    end
  end

  defp filter_params(params) when is_map(params) do
    for {key, value} = tuple <- params, into: %{} do
      case key do
        k when k in ~w(password passwordRepeat) ->
          {key, filter_str(value)}

        "user" when is_map(value) ->
          {key, filter_params(value)}

        _ ->
          tuple
      end
    end
  end

  defp filter_params(params), do: params

  def filter_str(str, length_to_keep \\ 0) do
    "#{String.slice(str, 0, length_to_keep)}********* [FILTERED]"
  end

  # ---- Dev only: mailer. We can use Mix.env here cause file is interpreted at compile time ----
  if Mix.env() == :dev do
    pipeline :browser do
      plug(:accepts, ["html"])
    end

    scope "/_dev/" do
      pipe_through([:browser])
      forward("/mail", Bamboo.SentEmailViewerPlug)
    end
  end
 
end

@Skyblueballykid
Copy link

Were you able to resolve this error?

I am receiving the same phx_template_not_found error.

Thank you

@Skyblueballykid
Copy link

I should also mention that my code is nearly identical and I also have created the template in the appropriate directory.

@mazz
Copy link
Author

mazz commented Oct 4, 2019

I honestly can’t remember exactly. I think it was some broken reference to a .json in book.view.ex

General rule: if you think it’s Phoenix’s fault it’s probably actually your fault.

@Skyblueballykid
Copy link

Hahaha, thanks for the reply. I have a feeling you're right and I'm not parsing the json correctly (I want to render the output from another API and I have a feeling that's the issue).

Cheers,
Thomas

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment