AlchemistCamp

AlchemistCamp

How to replace render_existing/3 with function_exported?/3

I have several apps with something like the following in the app.html.eex or app.html.heex:

<%= render_existing(view_module(@conn), "_meta." <> view_template(@conn), assigns)
  || render AppWeb.LayoutView, "_meta.html", assigns %>

This setup renders the metadata for a given view “foo.html” by looking for “_meta.foo.html” and rendering it if it exists. I use the meta templates for holding SEO-related meta, OG meta, and various other tags that go into the tag of a document.

If meta doesn’t exist, then the logic above renders a default template called layout/_meta.html. as the default source.

After upgrading Phoenix, I’m now seeing a compilation warning telling me to use function_exported?/3 instead of render_existing/3.

warning: Phoenix.View.render_existing/3 is deprecated. Use function_exported?/3 instead
  lib/app_web/templates/layout/app.html.eex:2: AppWeb.LayoutView."app.html"/1

What would be a good way of following this advice (without breaking the behavior of 100+ _meta templates)? There’s a considerable gap in the interface of the suggested replacement function.

Most Liked

AlchemistCamp

AlchemistCamp

I gave it my best shot this morning during a livestream before work and unfortunately, just couldn’t get a working solution.

Without render_existing/3, we can no longer determine whether a template exists. Depending on deployment strategies, the filesystem is sometimes no longer available.

Unfortunately, function_exported?/3 doesn’t fill the gap since render/3 will always be exported.

This means the only options would be

  • writing and maintaining hundreds and hundreds of meta functions throughout the application
  • crawling the filesystem at compile time to create a list of all existing template names
  • using try and rescue on every page load
  • some kind of macro wizardry I haven’t yet been able to think of
LostKobrakai

LostKobrakai

The idea is moving to function components over templates. Function components are a lot more flexible than templates and given they’re based on (differently named) functions there’s less phoenix magic needed – magic the phoenix teams seems to like to get away from. But not everybody will jump on board of restructing their projects immediately, therefore I feel the deprecation was a bit premature.

You’d replace your code with something like this:

<%= if function_exported?(view_module(@conn), :meta 1), do: view_module(@conn).meta(Map.merge(assigns, %{template: view_template(@conn)}), else: meta(assigns) %>
# LayoutView
def meta(assigns) do
  ~H"""
  …
  """
end

# OtherView
def meta(%{template: "index.html"} = assigns) do
  ~H"""
  …
  """
end

…

From those meta functions you can also call your existing templates using:

render("_meta.#{assigns.template}", assigns)
AlchemistCamp

AlchemistCamp

I looked at the docs before creating this thread. It’s because the examples provided weren’t applicable to my use case that I asked here in the first place.

I’ve found that _meta.foo.html files for simpler cases and defining a render("_meta.foo.html", assigns) functions in the view for more complex cases a very useful pattern.

Where Next?

Popular in Questions Top

electic
Hi, I am new to Elixir. I am trying to use the DateTime component to insert a date into MySQL however the there seems to be no way to fo...
New
9mm
I am constructing a JSON object (map) and I need to conditionally set a field. I’m trying to write proper elixir-way code… and I’m at a l...
New
Darmani72
If I have a post route which an argument: post /my_post_route/:my_param1, MyController.my_post_handler How would get the post params ...
New
mgjohns61585
Could someone help me? I’m making my first elixir program, number guessing game. I can’t figure out how to convert the user’s guess from ...
New
johnnyicon
Hi all, I’ve just started learning Elixir and Phoenix Framework, so please pardon my n00bness at this stage. I’m trying to use Postgres...
New
freewebwithme
Using vs code and installed ElixirLS: support and debugger. And I got an error popped up on start up says Failed to run ‘elixir’ comma...
New
aalberti333
As the title describes, I’m trying to run Enum.map() over a list of key/value pairs, where the value is a map. My data looks like this: ...
New
lucidguppy
I have a super simple question about elixir - how would I take a file like this foo bar baz and output a new file that enumerates th...
New
jason.o
In the code below, if the create action is not set to accept “extra_key” as an input, it errors out with a message shown above. Is there ...
New
senggen
Erlang/OTP 25 [erts-13.2.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] 15:22:35.803 [error] gen_event {lager_file_backend...
New

Other popular topics Top

lastday4you
I wanted to check elixir version in phoenix because i found that my elixir is 1.5 but when i use Enum.chunk_by it said the function is un...
New
chrismccord
As promised, the first release candidate of Phoenix 1.3.0 is out! This release focuses on code generators with improved project structure...
New
TunkShif
This post is an instruction guide to help you setup your Neovim for Elixir development from scratch. It includes general information on h...
274 42158 114
New
Nvim
Anybody knows a comprehensive comparison of Django and Phoenix, thanks for the help. Where are they similar? Where do they differ the m...
New
danschultzer
None of the current solutions worked well for me, so I went ahead and built a user management system from scratch. This project took far...
548 29703 241
New
greenz1
I have a phoenix application from which a user can download multiple(5-6) files of size 1MB. I couldn’t find anything related to sending ...
New
AngeloChecked
What learn first? Rust or Elixir Hi Elixir community! I’m here because i want learn a new language. I’m a junior developer and mainly i ...
New
freewebwithme
Using vs code and installed ElixirLS: support and debugger. And I got an error popped up on start up says Failed to run ‘elixir’ comma...
New
joeerl
Hello again - after a longish gap I’ve decided I really must dig into Elixir and see what’s been happening here - so I have a few questio...
New
alice
Hey, Just curious what are the main benefits of Elixir compared to Clojure? When is Elixir more useful than Clojure and vice versa? Th...
New

We're in Beta

About us Mission Statement