Phoenix Render a template that changes with route

Hello ,

I am trying to render the phoenix context name as a header for a page using templates.

so I have a layout as follows in app.html.eex:

        <%= render ElWeb.Shared.NavigationView, "_navbar.html", assigns %>
        </div>          
        <main role="main">
            <%= render @view_module, @view_template, assigns %>
        </main>

in the shared view I have this function:

 def current_domain(domain \\"") do
"Not yet implemented coz im not a real programmer"
  end

in the router I have a new scope

scope "/users", ElWeb do
   pipe_throug :browser

   get "/", UserController, :index
end

and a fairly standard controller with a pure render function

def index(conn, _params) do
render(conn, “index.html” )
end

What I am trying to do is for each scope to have the navbar partial template, render the scope name/domain name

I have been trying for a couple of hours but I think I might be thinking about it the wrong way.
I did an apply/3 function to run the function in the view with the parameters I wanted from the controller. but I suspect that the template is already rendered and wont update.
I was thinking of using a gen server to store the route name but I think I might be over complicating things.

am I even correct to place the current domain function in the view ?
any tips or prods in the right direction are welcome.

1 Like

You can decide how to render it in "_navbar.html.eex" based on the assigns it receives.

<%= if @conn.assigns.likes_candy? do %>
  # render the candy version
<% else %>
  # render the boring version
<% end %>

And you can set these assigns in a plug before invoking your controller action.

# in your router.ex or endpoint.ex
  pipeline :browser do
    # ...
    plug(MyAppWeb.Plugs.CandyLoverDetector)
    # ...
  end

and in /lib/my_app_web/plugs/candy_lover_detector.ex or somewhere similar

defmodule MyAppWeb.Plugs.CandyLoverDetector do
  @moduledoc "Detects candy lovers and labels them accordingly."

  import Plug.Conn

  def init(opts), do: opts

  def call(conn, _opts) do
    assign(conn, :likes_candy?, :rand.uniform() > 0.42)
  end
end
2 Likes

So basically make a plug , add it to the browser pipeline
get and set the value there ,
and add the current route to the conn struct as a key value pair.
so this will basically be like a global value available to everything the conn touches

I`m gonna give it a try. thanks!

Do you know why the template wasn`t rerendering when running the apply/3 to start the current_domain function in the view? ?

This info is already there, check conn.path_info, for example.

so this will basically be like a global value available to everything the conn touches

More like a shared value.

Do you know why the template wasn`t rerendering when running the apply/3 to start the current_domain function in the view? ?

No, sorry. Maybe you could show us the code?

I got things working thanks ! :slight_smile:

as for the apply/3 function i figured it out. it worked but my grasp of logic failed.