6

I have created AJAX page transitions based on:

https://designbycosmic.com/journal/craft-cms-ajax-page-transitions-with-history-pushstate

It's all working nicely, the main content of the site (everything except the header) is loaded through ajax with a page transition using velocity.js.

My question is how would I go about getting all the metadata (or intact any of the information stored in to refresh for each page. At the moment the meta data is stuck with whatever is there when the browser loads.

I know this isn't specifically craft but any help would be appreciated.

Scott

3 Answers 3

3

You'll need to send the new pageview to Google Analytics manually on your ajax success. You'll want to read the Google documentation page, but it can be as simple as added the following line where ga_page is the new url:

ga( 'send', 'pageview', ga_page );
2

The way I am currently doing this @scott is passing back meta data in the ajax response as well.

Throwing in the Google Analytics line @luke suggested as well!

Example Json object:

{
  "meta":{
      "title":"This is the default global title of the site pages. | My Website",
      "meta":{
        "name":{
          "keywords":"default,global,comma-separated,keywords",
          "description":"This is the default global natural language description of the content on the site pages.",
          "dcterms.Identifier":"http:\/\/mywebsite.com\/competition",
          "dcterms.Title":"This is the default global title of the site pages.",
          "dcterms.Subject":"default,global,comma-separated,keywords",
          "dcterms.Date":"2016-06-30",
          "dcterms.Description":"This is the default global natural language description of the content on the site pages."
        },
        "property":{
          "og:type":"website",
          "og:locale":"en_us",
          "og:url":"http:\/\/mywebsite.com\/competition",
          "og:title":"This is the default global title of the site pages.",
          "og:description":"This is the default global natural language description of the content on the site pages.",
          "og:site_name":"My Website"
        }
      },
      "link":{
        "rel":{
          "canonical":"http:\/\/mywebsite.com\/competition"
        }
      }
    },
}

Then loop through the meta data with JavaScript within you ajax success method. jQuery is used in this example.

Example JS:

    $('head').find('title').text(meta.title);

    $.each(meta.link, function(k, v){
        $.each(v, function(kk, vv){
            $('head').find('link[' + k + '="' + kk + '"]').attr('href', vv);
        });
    });

    $.each(meta.meta, function(k, v){
        $.each(v, function(kk, vv){
            $('meta[' + k + '="' + kk + '"]').attr('content', vv);
        });
    });
4
  • Thanks for your reply. Okay so I understand (first time I've used AJAX or Json) I need to find a way for each page to generate a Json object. The JS sits on the _layout page and refreshes the head? How do I generate the object. Something like the prune plugin? That uses json_encode(). Or, am I way of the mark? Commented Jun 30, 2016 at 13:13
  • Twig has json_encode builtin. Otherwise JSON is pretty easy to "encode" manually if you're only spitting out a few key/values. Commented Jun 30, 2016 at 15:15
  • I've managed to get get a Json object produced for each page. I can test it on the page by rendering with json_encode() | raw and it displays as your example. However, I can't get the javascript to replace the tags into the head. I'm assuming the JS can just be placed in the main layout? Commented Jun 30, 2016 at 15:31
  • @scott the JS has to be fired from the ajax success method. So when you update the page contents you would also update the meta tags.
    – Fyrebase
    Commented Jun 30, 2016 at 23:47
1

I was having difficultly getting the JS (that is responsible for AJAX page transitions) to read the Json object that the page generated. In the end I had to run a script on the page itself. For the un-JS savy people like me this is what went at the bottom of the page:

<script type="text/javascript">
$(document).ready(function(){
    var jsonMeta = {{ jsonMeta|json_encode|raw }};
    $('head').find('title').text(jsonMeta.meta.title);
    $.each(jsonMeta.meta.link, function(k, v){
        $.each(v, function(kk, vv){
            $('head').find('link[' + k + '="' + kk + '"]').attr('href', vv);
        });
    });

    $.each(jsonMeta.meta.meta, function(k, v){
        $.each(v, function(kk, vv){
            $('meta[' + k + '="' + kk + '"]').attr('content', vv);
        });
    });
});
</script>

An at the top I did this to get the Json object

{% set jsonMeta = [] %}
{% set jsonMeta = jsonMeta | merge({
  "meta":{
    "title": entry.title,
  "meta":{
    "name":{
      "keywords":"keywords",
      "description": entry.journalBody|striptags|truncate(180),
      "author" : entry.author.fullName,
      "dcterms.Identifier": craft.request.url,
      "dcterms.Title": siteName,
      "dcterms.Subject":"keywords",
      "dcterms.Date": entry.dateUpdated.iso8601,
      "dcterms.Description": entry.journalBody|striptags|truncate(180)
    },
    "property":{
      "og:type":"website",
      "og:locale":"en_uk",
      "og:url": craft.request.url,
      "og:title": entry.journalBody|striptags|truncate(180),
      "og:description": entry.journalBody|striptags|truncate(180),
      "og:site_name": siteName,
      "article:published_time":entry.dateCreated.iso8601,
      "article:modified_time":entry.dateUpdated.iso8601



    }
  },
  "link":{
    "rel":{
      "canonical":craft.request.url
    }
  }
},
})
%}

No idea whether this is bad solution but it works.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.