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
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
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
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
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance








