Search code examples
ruby-on-railsruby-on-rails-4metadatameta-tagsslim-lang

Meta tags with slim-rails


I am currently working on a site sweep and am attempting to refine meta presentation for an app already in production. Specifically, the tags seem to live in the _head.html.slim file.

Example of way meta tag is currently represented in app:

    - if content_for?(:description)
meta name="description" content=content_for(:description)

What I would like to replace it with:

    <meta property="og:description" content="DESCRIPTION OF SITE HERE"/>

Am I on the correct track? I am hesitant to completely wipe the "if content_for?(:description) bit.

I have not worked with slim-rails before, and am thrown off. I've gone through some of the documentation on slim gem, but it defines implementation of meta tags in a completely different manner than what I am currently seeing in the _head.html.slim file.

Any advice would be greatly appreciated.


Solution

  • content_for is actually part of Rails and has very little to do with Slim. yield and content_for let you assign "blocks" of content in your layouts that can be filled dynamically by views.

    This is a plain ERB example of dynamically assigning a page title:

    # app/views/layouts/application.html.erb
    <title>MyApp | <%= content_for?(:title) ? yield(:title) : "Foo" %>
    

    Then in your views you can provide content with content for:

    # app/views/products.html.erb
    <%- contents_for(:title, "Products" ) -%>
    

    The end result is that the page title will read MyApp | Products when you visit /products.

    For your example you could simply provide the content for the description in your views.

    # app/views/user/show.slim
    - content_for(:description, "#{ @user.name } on MyApp")
    # or we use provide to tell the layout to stop looking for more contents.
    - provide(:description, "#{ @user.name } on MyApp")
    

    And set it up to display a default in case there is no content provided.

    = meta name="description" content= content_for?(:description) ? yield(:description) : "The awesomest app on the interwebs."
    

    To clean this up you might want to employ a helper method.

    module ApplicationHelper
      # ...
      def og_description(default)
        # note that we use content_for and not yield since we want
        # the value - not to yield (print) to the buffer.
        disc = content_for?(:description) ? content_for(:description) : default 
        tag(:meta, {
          property: "og:description",
          content: disc
        })
      end
    end
    

    This will let you do:

    = og_description("The awesomest app on the interwebs.")