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.
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.
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
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.
if you want exact order, instead of map you can use list
attrs_list = [
[name: "keywords", content: "........"],
[name: "description", content: "........."],
[property: "og:image", content: "......"]
]
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.
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) %>