Search code examples
phpseoexpressionenginemeta

Expression Engine CMS How to populate meta tags dynamically?


I'm trying to add meta tags for description and keywords to my expression engine website.

My structure is this: I have a {top} snippet which is called in every template

Inside of the head tag I have this

<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="{exp:channel:entries}{blog_seo_description}{/exp:channel:entries}">
<meta name="author" content="http://epicsoftware.com" >
<meta name="keywords"  content="{blog_seo_keywords}" />
{if segment_1 == ""}
<title>Epic Software Group, Inc.</title>
{if:else}
{exp:channel:entries channel="main|blog|projects" limit="1" disable="categories|category_fields|custom_fields|member_data|pagination"}
<title>Epic Software Group, Inc. - {title}</title>
{/exp:channel:entries}
{/if}

When I write the description for one page it's applying the same description everywhere, I think that's because the top snippet doesn't know where the information is coming from. Also, I can't create another channel field with the same name in other channel field group

I need to create a channel field for each channel and show the information of THAT channel entry in the meta tag.

Expression Engine version: 2.11.2


Solution

  • You can do that a lot easier by using layouts: https://docs.expressionengine.com/v2/templates/layouts.html basically, you'll have a wrapper template that contains your basic template, and you feed the content from another template to this template. This way you only have to use the channel:entries tag once to set all the data. this is the basic template where i set the variables:

    {layout="_partials/_wrapper"}
    {exp:channel:entries 
     channel="pages" 
     disable="categories|pagination|member_data|relationships"}
    {layout:set name="extra_header_content"}<script src="/assets/js/my_extra_script.js">{/layout:set}
    {layout:set name="browser_title"}{browser_title}{/layout:set}
    {layout:set name="seo_description"}{seo_description}{/layout:set}
    {layout:set name="page_title"}{page_title}{/layout:set}
    {layout:set name="body_content"}{body_text}{/layout:set}
    {/exp:channel:entries}
    

    see me embedding the layout template on the first lin. My wrapper template looks like this:

    <!doctype html>
    <html class="no-js" lang="nl" dir="ltr">
    <head>
    <meta charset="utf-8">
    <meta http-equiv="x-ua-compatible" content="ie=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>{layout:browser_title}</title>
    <meta name='description' content='{layout:seo_description}' />
    <meta name="twitter:description" content="{layout:seo_description}" />
    <meta property="og:description" content="{layout:seo_description}">
    {layout:extra_header_content}
    </head>
    <body>
    <h1>{layout:page_title}</h1>
    {layout:body_content}
    </body>
    </html>
    

    since you're on EE 2 you'll need to create fields for every browser title in it's own field group. this might be tedious, however if you name the fields a bit logically, you can use preload_replace https://docs.expressionengine.com/v2/templates/globals/preload_replacement.html to make your templating easier:

    say you have a channel called news, call your field "news_browser_title" and for the channel called pages create a field called "pages_browser_title"

    In your template you can now use it like this:

    {layout="_partials/_wrapper"}
    {preload_replace:channel="pages"}
    {exp:channel:entries 
     channel="pages" 
     disable="categories|pagination|member_data|relationships"}
    {layout:set name="extra_header_content"}<script src="/assets/js/my_extra_script.js">{/layout:set}
    {layout:set name="browser_title"}{{channel}_browser_title}{/layout:set}
    {layout:set name="seo_description"}{{channel}_seo_description}{/layout:set}
    {layout:set name="page_title"}{{channel}_page_title}{/layout:set}
    {layout:set name="body_content"}{{channel}_body_text}{/layout:set}
    {/exp:channel:entries}
    

    Update: You can put your wrapper template in whatever template group you like. I basically have a folder called _partials, which houses all my templates that i embed into other templates. Say you have a template group setup like this:

    _partials
        -_wrapper
        -_another_template
        -_some_other_template
    blog
        -index
        -item
    news
        -index
        -item
    

    in each of your templates in blog or news you can embed the same wrapper template with {layout="_partials/_wrapper"} because it just takes the template_group/template_name as input.

    If you need more help, just head over to https://expressionengine.stackexchange.com/ for more specific EE advice