SEO A Simple Approach for meta tags with ExpressionEngine

Custom meta tags for templates/entries can be easily achieved using Template Layouts with ExpressionEngine. This approach is very lightweight, easy to customize and does not rely on an add on.

If the site already uses Template Layouts, then incorporating custom meta tags is a breeze. We’re going to start by setting a custom title and description. Here’a what a simple template layout would look like:

<!doctype html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" dir="ltr">
<meta http-equiv="content-language" content="en-us" />  
<title>{if layout:title != ''}{layout:title} - {/if}{site_name}</title>
{if layout:description}<meta name="description" content="{layout:description}">{/if}
</head>
<body>
{layout:contents}
</body>
</html>

Now on any template you can easily set the title and meta description based on what the content for the template is.

{layout="site/.html-layout"}
{exp:channel:entries channel="news"}
{layout:set name="title"}{title}{/layout:set}
{layout:set name="description"}{meta_description}{/layout:set}
{/exp:channel:entries}

The code above will set the title to the entry’s title and the meta description to a custom field designated for meta descriptions. Additionally if you limit the custom field to 155 characters, you will ensure that the editor does not go above the limit.

The possibilities with such a simple approach are endless. Example code for category pages:

{exp:channel:category_heading channel="news"}
{layout:set name="title" value="{category_name} News"}
{/exp:channel:category_heading}

And my approach to paginated pages is to have the <title> tag have more than one layout variable:

<title>{if layout:title}{layout:title}{/if}{if layout:title-two} {layout:title-two}{/if} - {site_name}</title>

Having two variables allows you to set the title in pieces in different parts of the template. So pagination would look something like:

{layout="site/.html-layout" title="News"}
{exp:channel:entries channel="news" paginate="bottom" limit="10"}
{paginate}
{if current_page != '1'}
{layout:set name="title-two"}- Page {current_page}{/layout:set}
{/if} 
{/paginate}
{/exp:channel:entries}

One last tip: assume that you don’t want the site’s name at the end of the title because the entry’s title + the site’s name may be too long. You can easily add one more template variable to the title that if set – it does not display the site’s name.

<title>{if layout:title}{layout:title}{/if}{if layout:title-two} {layout:title-two}{/if}{! if layout:no-site} - {site_name}</title>

With the above code in place, whenever you don’t want the site name in the title, just set layout:no-site to anything:

{layout:set name="no-site" value="y"}

TrailTalk: A Project of Our Own

Over a year ago we began work on a project that is the brain child of Willow Light Studio. This project allows us to put all our knowledge and experience into a website that we can call our own. Our goal with this new website is (but not limited to):

  • Share our passion of the outdoors with others, and have others share theirs with us
  • Provide a valuable resource to outdoor enthusiasts
  • Connect outdoor enthusiasts with each other and local organizations
  • Inspire people and families to spend more time outdoors

We have big ideas and plans for this project, but are realistic that many of these ideas will have to be developed over time as both time and resources are limited. We are fully committed to making it a success, and also implementing every good idea with the goal of providing a valuable resource for outdoor enthusiasts.

The name and logo were conceived by the two Willow Light Studio staff, Pedro Guimaraes and Sara DeRico. The concept was brought to life by local Maine artist, Daria Norvlaan of Luksin Designs who also created other artwork for the website.

The website will launch on the first day of Spring in 2016.

Website for Maine based Seeds of Independence

We began working with Seeds of Independence earlier in the year with the goal of designing and developing a new website, as well as doing photography for the new website.

The project quickly took a turn into being more than just the regular website, but also an internal website that is a database of the organization’s staff, mentors, youth, programs and more.

The organization can now move from using paper to storing its data “in the cloud”, which can be accessed from anywhere ~ from a mobile phone to an in-office computer. The relational database allows the organization quick access to who’s mentoring who, emergency and medical info for youth and more.

The day where you can have your web presence, along with your organization’s data is here. The information is also likely more secure than paper, thanks to ExpressionEngine being one of the most secure Content Management Systems out there.

We will be getting some photography for this project completed in the next couple weeks and look forward to capturing the essence of the organization.

Sitemaps with ExpressionEngine ~ Create an index and organize entries by year or month

Sitemap Index with ExpressionEngine

Sites that are driven by new entries every week can quickly grow to have thousands of entries in a channel. In which case, having a single sitemap is very taxing on resources, and the end result is a sitemap that is slow to render.

SEO discussions are the politics of web design. Page load speed and resource usage on the other hand are something everyone can agree on. My goal is to show a sustainable solution that is considerate of resources and quick to render.

The example below creates a yearly archive of posts. It can be easily modified to create a monthly archive if necessary.

P.S: I formatted the code for readability and added comments to make it self explanatory

Sitemap Index Template

<?xml version="1.0" encoding="UTF-8">
<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 
    http://www.sitemaps.org/schemas/sitemap/0.9/siteindex.xsd">

{!-- Use EEs channel:month_links tag to generate years or months of entries --}
{exp:channel:month_links channel="articles" limit="10000" status="not closed"}
{year_heading}
<sitemap>

{!-- Link to sitemap for specific year --}
<loc>{site_url}/sitemap/entries-{year}.xml</loc>

{!-- Get the date of the most recent entry --}
{exp:channel:entries channel="articles" dynamic="no" status="not closed" limit="1" orderby="edit_date" sort="desc" year="{year}" disable="member_data|pagination|categories|custom_fields|relationships"}

<lastmod>{edit_date format='%Y-%m-%dT%H:%i:%sZ'}</lastmod>
{/exp:channel:entries}
</sitemap>
{/year_heading}
{/exp:channel:month_links}
</sitemapindex>

Next step is to create a template group named sitemap and add a template named entries to it. Then your template will look something like this:

Sitemap Entries Template

<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" 
    xmlns:image="http://www.google.com/schemas/sitemap-image/1.1" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 
    http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">

{!-- Use entries_year segment from template route to determine year --}
{exp:channel:entries channel="articles" status="not closed" dynamic="no" orderby="entry_date" sort="desc" disable="member_data|pagination|categories|custom_fields|relationships" limit="5000" year="{segment:entries_year}"}

<url>
{!-- Hardcoding URL is highly recommended and saves seconds when dealing with 1000s of entries --}
<loc>http://domain.com/news/{url_title}</loc>
<lastmod>{edit_date format="%Y-%m-%dT%H:%i:%sZ"}</lastmod>
<priority>1.0</priority>  
<changefreq>daily</changefreq>
</url>
{/exp:channel:entries}  
</urlset>

Template Route

The last step is to set the template route for /sitemap/entries to the following:

/sitemap/entries-{entries_year:alpha_numeric}.xml

Reference

  1. Sitemap Index (Google)
  2. Template Routes (ExpressionEngine)