samgaw

samgaw

SVGs & EEx Tags: Inlining from External File?

There are already a couple of helper packages on Github to manage inlining external SVG files into templates which is great from a readability point of view. However I’m guessing because of the way templates are evaluated, EEx tags treated as strings.

Taking the thoughtbot package as the base for a simple example, do something along the lines of:

def inline_svg(file_name) do
  path = static_path(file_name)
  case File.read(path) do
    {:ok, file} -> {:safe, file}
    {:error, _} -> raise "No SVG found at #{path}"
  end
end

defp static_path(file_name) do
  path = "assets/static/svg"
  [path, "#{file_name}.svg"] |> Path.join() |> Path.expand
end

That will render the SVG but include the EEx as strings rather than the output of <%= some_func() %> included in the SVG file as expected because of the {:ok, file} -> {:safe, file}. But removing that and going with {:ok, file} -> (file), or wrapping the svg_inline() function with raw() still doesn’t give me the desired outcome.

So I’m wondering where in Phoenix’s order should I be attempting to run this so that tags included in the inlined SVG are rendered as expected?

Thanks.

Most Liked

LostKobrakai

LostKobrakai

Your problem is that you’re using a function here. The function will be called at runtime, but at runtime the svg’s won’t be available (when using releases) or at least the path might no longer match. You’d want to use a macro, so you read the svg’s content at compile time and only have the result inlined with all the other eex template contents.

al2o3cr

al2o3cr

I’m definitely missing something - the inline SVG macros above are designed to be used like:

    <button class="btn btn-primary mb2 btn-ple" style='margin-left: 5px' type='submit'>
      #{ Svg.inline("SquareOk") } 
    </button>

(from the code AndyL linked)

But if you’ve got EEx markup that needs to be compiled into a function to return the SVG, it seems like render with an .svg.eex partial should do the right thing:

  <div class="place-where-svg-goes">
    <%= render("my_template.svg", some_param: "foo") %>
  </div>

What about the render approach doesn’t work for your use case?

hauleth

hauleth

Your macro:

defmacro inline_svg(file_name) do
  path = static_path(file_name)
  case File.read(path) do
    {:ok, file} -> quote do: {:safe, unquote(file)}
    {:error, _} -> raise "No SVG found at #{path}"
  end
end

Where Next?

Popular in Questions Top

sen
Hi All, I set a environment variables in dev.exs , like below code. when i start server, how can i set the ${enable} value? thanks. d...
New
albydarned
Hello all! I am typing this post from my new MacBook Pro with the M1 chip. I’m loving it so far, and will probably use it as my daily dr...
New
chrisalley
ExUnit now has describe blocks which is a welcome addition coming from RSpec. In the docs, it states that nested hierarchies of describe ...
New
lessless
I believe there are people here who are dealing with CSV files import on the daily basis, and since Excel is a really popular tool there ...
New
myronmarston
The Elixir Typespec docs show the following syntax for keyword lists in typespecs: # ... | [key: type] # keyword lists...
New
minhajuddin
I have seen a lot of code which picks the first element from a list using Enum.at(0) instead of List.first. Is there a reason why people ...
New
ycv005
I have followed this StackOverflow post to install the specific version of Erlang. And When I am running mix ecto.setup then getting fol...
New
nsuchy
Hi. I’ve noticed that Windows Powershell has it’s own IEX command and you cannot access Elixir’s IEX due to the conflict. This isn’t a cr...
New
joaquinalcerro
Hi there, I am working with Ecto-Postgresql and I need to call all of the records from a specific table but the table has 40,000 records...
New
marick
I had some trouble figuring out how to make many-to-many associations work. Once I got it working, I wrote a blog post. Because I’m a nov...
New

Other popular topics Top

Harrisonl
We have an ECS cluster with 4 services, where each task joins a single cluster, via discovery ECS discovery service. Currently when I de...
New
gshaw
What is the idiomatic way of matching for not nil in Elixir? E.g., First way: defp halt_if_not_signed_in(conn, signed_in_account) when...
New
msaraiva
Surface is an experimental library built on top of Phoenix LiveView and its new LiveComponent API that aims to provide a more declarative...
564 43622 214
New
grych
Hi folks, Few months ago I have announced the proof-of-concept of the library to manipulate the browsers DOM objects directly from Elixi...
639 52341 488
New
RisingFromAshes
I’ve read in another post that it may be possible with a router helper - but I couldn’t find an appropriate one, and tbh, I’m still just ...
New
sergio_101
I am VERY much an elixir newbie. I have taken one elixir course and one phoenix course on Udemy. During that course, I saw the instructor...
New
ashish173
I am using Ecto timestamps with postgres, I can see the timestamps() use the :naive_dateime but for my use case I wanted to store the ti...
New
klo
Got a question about when to concat vs. prepending items to list then reversing to achieve appending. So i know lists boil down to [1 | ...
New
AstonJ
We’ve put together this wiki for Phoenix LiveView - please feel free to add any info you feel is worth including. What is Phoenix LiveV...
New
PeterCarter
There are pre-rolled solutions for other frameworks that do work. However, Phoenix does not seem to have these. Have people had good expe...
New

We're in Beta

About us Mission Statement