Hello,
I want to create dynamic meta tag in each controller and view, for example :
in show action function
<meta name="keywords" content="...." />
<meta name="description" content="...." />
<meta property="og:image" content="...." />
<meta property="og:image:width" content="1074" />
<meta property="og:image:height" content="506" />
<meta property="og:title" content="...." />
in index function
<meta name="keywords" content="...." />
<meta name="description" content="...." />
<meta property="og:image" content="...." />
in these functions, meta tags are different, it should be noted I need to add custom code in head like this:
....
In summary, I need to have full head access to import something which I will be able to edit in controller , because I read these property with database
What do you have a suggestion for me? I don’t need fix meta !!
I read these:
https://www.brainarama.com/thought/dbfe9020-b431-11e7-ae34-3f710d564c96/Elixir-Phoenix-framework-pass-data-from-controller-action-to-layout-view-app-html-eex
Public facing websites need to have some basic search engine optimization (SEO) tags, such as and <meta name="description">. In Rails, you could achieve this pretty simply by putting a yield :head tag in the appropriate layout.
1 Like
Sure, just provide a list of keys/values for each meta tag and then map those to Phoenix.HTML.Tag.tag/2
. You’d put this in your layout view or a shared view:
def meta_tags(attrs_list) do
Enum.map(attrs_list, &meta_tag/1)
end
def meta_tag(attrs) do
tag(:meta, Enum.into(attrs, []))
end
Assuming your data fits into this shape:
attrs_list = [%{name: "keywords", content: "........"},
%{name: "description", content: "........."},
%{property: "og:image", content: "......"}]
Then you can use it like this in your layout:
<%= if @meta_attrs, do: meta_tags(@meta_attrs) %>
Of course, you’ll need to provide meta_attrs
in the assigns for each controller. You could also do it with a plug if that gets tedious.
5 Likes
Hello, Thank you very much, I have a problem when I decade to start Phoenix server
== Compilation error in file lib/trangell_html_site_web/views/layout_view.ex ==
** (CompileError) lib/trangell_html_site_web/templates/layout/app.html.eex:9: undefined function meta_tags/1
Step 1
in templates/layout/app.html.eex
path I write
<%= if @meta_attrs, do: meta_tags(@meta_attrs) %>
Step 2
in controllers/page_controller.ex
path :
def index(conn, _params) do
attrs_list = [%{name: "keywords", content: "........"},
%{name: "description", content: "........."},
%{property: "og:image", content: "......"}]
render(conn, "index.html", meta_attrs: attrs_list)
end
Step 3
in views/page_view.ex
path :
def meta_tags(attrs_list) do
Enum.map(attrs_list, &meta_tag/1)
end
def meta_tag(attrs) do
tag(:meta, Enum.into(attrs, []))
end
where did I make a mistake?
Try defining them in views/layout_view.ex
instead of views/page_view.ex
1 Like
it works for me , but I think it has some problems
see please :
<meta content="test1" name="keywords"><meta content="test2" name="description"><meta content="......" property="og:image">
at frist it loads content
and after loads name
, I saw https://hexdocs.pm/phoenix_html/Phoenix.HTML.Tag.html#tag/2 , but it doesn’t have any example
I’m not sure I understand what the problem is. If you’re concerned about the order of attributes (content
before name
), then I’m pretty sure it doesn’t matter.
1 Like
if you want exact order, instead of map you can use list
attrs_list = [
[name: "keywords", content: "........"],
[name: "description", content: "........."],
[property: "og:image", content: "......"]
]
2 Likes
Here -> http://cloudless.studio/articles/27-implementing-page-specific-titles-in-phoenix you can find a very nice and simple example for implementing dynamic page specific titles.
2 Likes
Awesome stuff, I just had to change the heex part to the Phoenix 1.6.6:
<head>
...
<!-- METAs -->
<%= if assigns[:meta_tags], do: meta_tags(@meta_tags) %>
1 Like