In router.ex I have a plug that assigns some variables to app.html.ex template, one of it is @locale, while this works well in regular controllers, I noticed something that for me is strange in render function:
In live view controller, if I display html with the sigil ~L, like this, previously assigned variables are bound and available:
def render(assigns) do
~L"""
<p>Hi</p>
"""
end
However, if I use a file template (needed not to dirty the code too much with a large html) in the following form, then none of the assigns from my plugs are available, thus it generates an error:
def render(assigns) do
AppWeb.IndexView.render("index.html", assigns)
end
Provided views/index_view.ex like
defmodule AppWeb.IndexView do
use AppWeb, :view
end
Am I missing something so it does not work in one form but works in another?
Thanks.
Edit, Question related: How to access then previous assigns made by router’s plugs in the same way I can access them from a regular controller? In this case, it would be access that @locale from liveview’s html.leex
I am not sure I fully understand, but in general it seems to me that if @locale is in app.html.leex, calling AppWeb.IndexView.render to render index.html.leex is not going to pass the new assign to/trigger a re-rendering of app.html.leex.
Everything that is in the controller (such as locale) that you want to be available in your liveview you need to put it in the LiveView session. If you are setting the LiveView from your router, there is a session option where you specify which keys you want to pass through. Putting the locale in the session is a quick way to achieve that. You can also explicitly have a controller and call live_render from the controller passing everything you want in the session.
I’ve created a minimal testcase of this issue and uploaded on GitHub, I would be very thankful if you can take a look.
If loaded via localhost:4000/normal, a normal controller will be displayed, if loaded via localhost:4000/live a live controller will be shown, reflecting the current problem.
That @test variable is assigned by router, defined in router.ex as a plug
The live macro in the router only allows specifying values to copy from the conn cookie session to the LV, so you need to use the controller approach and pass your local explicitly. No assigns are shared from the conn to the LiveView mount. Check out the life-cycle docs for more info