Using AB_PageMetaInfoModel to generate markup for meta elements

  • 608 Views
  • Last Post 22 August 2016
dwebb posted this 22 August 2016

UPDATE: See "Use AB_SocialMetaModel in CMS website to generate all social media meta/link/script markup" for simplifying wrapper class.

Most MVC websites need to output some meta tags on each page, usually in ~/Views/Shared/_Layout.cshtml or a partial template. Accelerator 6.4.1 introduces some helper classes to create strongly-typed model objects that represent these tags, and to render them consistently.

See also: AB_PageLinkInfoModel for link elements

See also: AB_PageScriptInfoModel for script tag markup and Json-LD

In the following example, the HttpContext.Current.Items collection is used to pass data up from the page-specific view template to ~/Views/Shared/_META_Elements.cshtml, which _Layout.cshtml renders. This information is used to populate an AB_PageMetaInfoModel object, which is a list of AB_PageMetaEntity objects.

When rendered, only the AB_PageMetaEntity objects that have non-null, non-whitespace Content values will be output. There's no need to condition adding objects to the collection based on whether or not they have a content value.

Each AB_PageMetaEntity must specifiy either Name or Property. Property is only used for Facebook OpenGraph metadata, and for the HTML5 markup to be valid the head element requires a prefix attribute: prefix="og: http://ogp.me/ns# fb: http://ogp.me/ns/fb#"

dwebb posted this 22 August 2016

@using A4DN.Core.MVC.CMS.Models
@{
    var title = HttpContext.Current.Items["Meta.Title"] as string ?? "Surround Technologies LLC";
    var description = HttpContext.Current.Items["Meta.Description"] as string;
    var defaultTwitterImageURL = HttpContext.Current.Items["Meta.ModuleImageURL"] as string;
    if (defaultTwitterImageURL != null && defaultTwitterImageURL.StartsWith("/"))
    {
        defaultTwitterImageURL = Request.Url.GetLeftPart(UriPartial.Authority) + defaultTwitterImageURL;
    }
    var defaultFacebookImageURL = HttpContext.Current.Items["Meta.ModuleImageURL"] as string;
    if (defaultFacebookImageURL != null && defaultFacebookImageURL.StartsWith("/"))
    {
        defaultFacebookImageURL = Request.Url.GetLeftPart(UriPartial.Authority) + defaultFacebookImageURL;
    }
    var openGraphType = HttpContext.Current.Items["Meta.OGType"] as string ?? "website";

    var additionalScriptModels = HttpContext.Current.Items["Meta.ScriptModels"] as List<AB_PageScriptInfoModel>;

    var metaModel = new AB_PageMetaInfoModel();

    metaModel.Add(new AB_PageMetaEntity { Name = "viewport", Content = "width=device-width, initial-scale=1.0" });

    metaModel.AddRange(new List<AB_PageMetaEntity>
    {
        new AB_PageMetaEntity { Name = "description", Content = description },
        new AB_PageMetaEntity { Name = "keywords", Content = HttpContext.Current.Items["Meta.Keywords"] as string },
        new AB_PageMetaEntity { Name = "author", Content = "Surround Technologies, LLC" },
        new AB_PageMetaEntity { Name = "generator", Content = "Accelerator Development Solutions - http://www.surroundtech.com/accelerator" },
        new AB_PageMetaEntity { Name = "rating", Content = "General" },
        new AB_PageMetaEntity { Name = "robots", Content = "Index, Follow" },
        new AB_PageMetaEntity { Name = "revisit-after", Content = "7 days" },
    });

    metaModel.AddRange(new List<AB_PageMetaEntity>
    {
        new AB_PageMetaEntity { Name = "twitter:card", Content = "summary_large_image" },
        new AB_PageMetaEntity { Name = "twitter:site", Content = "@SurroundTech" },
        new AB_PageMetaEntity { Name = "twitter:title", Content = title },
        new AB_PageMetaEntity { Name = "twitter:description", Content = description },
        new AB_PageMetaEntity { Name = "twitter:image", Content = defaultTwitterImageURL },
    });

    metaModel.AddRange(new List<AB_PageMetaEntity>
    {
        new AB_PageMetaEntity { Property = "og:title", Content = title },
        new AB_PageMetaEntity { Property = "og:description", Content = description },
        new AB_PageMetaEntity { Property = "og:type", Content = openGraphType },
        new AB_PageMetaEntity { Property = "og:url", Content = Request.Url.AbsoluteUri },
        new AB_PageMetaEntity { Property = "og:image", Content = defaultFacebookImageURL },
        new AB_PageMetaEntity { Property = "og:site_name", Content = "Surround Technologies, LLC" }
    });

    metaModel.Add(new AB_PageMetaEntity { Name = "apple-mobile-web-app-capable", Content = "yes" });

}

@Html.DisplayFor(m => metaModel)

The final rendering is done by calling DisplayFor() on the AB_PageMetaInfoModel object. You need ~/Views/Shared/DisplayTemplates/AB_PageMetaInfoModel.cshtml:

@model A4DN.Core.MVC.CMS.Models.AB_PageMetaInfoModel
@foreach (var entity in Model.Where(m => !String.IsNullOrWhiteSpace(m.Content)))
{
    if (!String.IsNullOrWhiteSpace(entity.Name))
    {
<meta name="@entity.Name" content="@entity.Content">
    }
    else if (!String.IsNullOrWhiteSpace(entity.Property))
    {
<meta name="@entity.Property" content="@entity.Content">
    }
}

Close