Question

Many apologies for the title that doesn't quite make sense; I have no idea how to describe this. Suggestions would be greatly appreciated.

I have this script which Squarespace injects into the footer of each blog post on a webpage, as well as into the footer of a blog entry's individual page. When loaded in the individual page, the code executes just fine. However, on the webpage where it's loaded once per blog entry, things get a little messier.

This is the code:

  <a name="comments-outer-wrapper" />

  <a class="muut" href="https://muut.com/i/test/comments:test">Comments</a>

  <script>
    var mtitle = document.title.slice(0, -13);
    var mhref = $("article").attr("id").substring(8);
    var mcount = "//api.moot.it/postcounts?path=/test/comments:" + mhref;

      $.getJSON(mcount, function(json) {

      var results = $(".entry-actions");

      $.each(json, function(key, val) {
        results.prepend("<a class=\"entry-comments\" href=\"{permalink}#comments-outer-wrapper\" title=\"Comments\">" + val["size"] + " Comments</a>");
        });
      });

    $(".muut").attr( "href","https://muut.com/i/test/comments:" + mhref);
    $(".muut").attr( "title",mtitle);
  </script>

What happens on individual article page line by line as the browser reads the code injection, I think, is that the script executes as intended.

However, since on the blog summary page Squarespace injects the code once PER article, I think that's what causes the problem. The code executes 3, 4, 5 times, and a result from the .getJSON function is prepended to the <a class="entry-comments"> section for each execution - what ends up happening is this:

Screenshot of the offending webpage

"1 Comments" is repeated three times (once for each blog entry on the page). Additionally, the HREF for each of those <a> elements is the same URL, which suggests to me that the var mtitle, var mhref, and var mcount is the same for each; the variables weren't dropped, refreshed, or undefined between each instance.

So, in my primitive mind, what I believe is happening is this:

[BLOG WEBPAGE]--[mtitle3]-[mhref3]-[mcount3]
       |
       |--[BLOG ARTICLE 1]--[SCRIPT]-[mtitle1]-[mhref1]-[mcount1]
       |   
       |--[BLOG ARTICLE 2]--[SCRIPT]-[mtitle2]-[mhref2]-[mcount2]
       |
       |--[BLOG ARTICLE 1]--[SCRIPT]-[mtitle3]-[mhref3]-[mcount3]

Only the last collected variable is being used.

What I'd like to happen is this:

[BLOG WEBPAGE]
       |
       |
[MASTER SCRIPT]--[mtitleX]-[mhrefX]-[mcountX]
       |
       |--[BLOG ARTICLE 1]--[mtitle1]-[mhref1]-[mcount1]
       |   
       |--[BLOG ARTICLE 2]--[mtitle2]-[mhref2]-[mcount2]
       |
       |--[BLOG ARTICLE 1]--[mtitle3]-[mhref3]-[mcount3]

I hope this wasn't too long or vague.

Was it helpful?

Solution

What you need to do is add a unique ID to the anchor. I saw above that someone pointed out you were reusing the ID, so you switched to using a class, but that's not the right solution.

Typically, the solution would be to use whatever server language you are using to insert that for you. Since you are using squarespace, you don't have direct access to the language, but it appears you still have options. According to their tag reference page, you can embed the post id in the page using this: {squarespace.page-id} - http://developers.squarespace.com/quick-reference/

So in your case, I believe you can achieve working code with a few small tweaks:

  <a name="comments-outer-wrapper" />

  <a id="comments-link-{squarespace.page-id}" class="muut" href="https://muut.com/i/test/comments:test">Comments</a>

  <script>
    var mtitle = document.title.slice(0, -13);

    // This needs to be updated to point to a specific article, like $("article#
    var mhref = "{squarespace.page-id}";

    var mcount = "//api.moot.it/postcounts?path=/test/comments:" + mhref;

      $.getJSON(mcount, function(json) {

      var results = $("#article-{squarespace.page-id} .entry-actions");

      $.each(json, function(key, val) {
        results.prepend("<a class=\"entry-comments\" href=\"{permalink}#comments-outer-wrapper\" title=\"Comments\">" + val["size"] + " Comments</a>");
        });
      });

    $("#comments-link-{squarespace.page-id}").attr( "href","https://muut.com/i/test/comments:" + mhref);
    $("#comments-link-{squarespace.page-id}").attr( "title",mtitle);
  </script>

EDIT:

Quick review shows it might not be {squarespace.page-id}, it might actually be {item.id} or something like that - http://jsont.squarespace.com/#Data-Tags . Basically you want the unique ID for each post to use.

EDIT 2:

Since it sounds like you don't have access to those, this solution should work out instead, and should be able to work whether it's embedded once or a billion times. Check out the code comments for more info:

<script type="text/javascript">

// This checks to see if the code has already been run, and if not, sets the var
//     to ensure that it's run but not run again.  It's important that it's
//     defined as a globally scoped variable.
if(typeof(mut_comment_counts_initialized) == "undefined" || !mut_comment_counts_initialized){

    //set globally scoped var to true to keep this from being set again
    var mut_comment_counts_initialized = true;

    //queue up a function to execute once the whole page is loaded
    $(function(){

        //since the whole page is loaded, we can now loop through all the articles on the page at once
        $("article").each(function(){
            //grab this and put it in a scoped var inside of this anonymous function
            var article = $(this);

            //grab the article id from the ID attribute
            var article_id = article.attr("id").replace("article-","");

            //define the api url using the article id
            var api_url = "//api.moot.it/postcounts?path=/test/comments:" + article_id;

            //do a json request for the article
            $.getJSON(api_url, function(json) {

                //find entry actions inside of previously scope article var
                var entry_actions_container = $(article).find(".entry-actions");

                //loop through each json result
                $.each(json, function(key, val) {

                    //create new anchor to add to
                    var new_anchor = $("<a></a>");

                    //add attrs and values to anchor
                    new_anchor
                        .addClass("entry-comments")
                        //I'm not convinced this url is right, especially since you said you can't use tags
                        .attr("href", "{permalink}#comments-outer-wrapper")
                        //i think this is probably what it should be (happened right when i tested it)
                        //.attr("href", "https://muut.com/i/test/comments:" + article_id)
                        .attr("title", "Comments")
                        .html(val["size"] + " Comments");

                    // add new anchor to container
                    entry_actions_container.prepend(new_anchor);
                });
            });

        });

    });
}
</script>

OTHER TIPS

You're gonna need a bit of a change in your logic. This is mainly pseudo code, but the gist of it is:

Edit: a bit hacky fix, but I can't think of something else at the moment:

if (!window.addedCommentLinks) {
    $('article').each(function() {
        var mtitle = $(this).find('h1').text();
        var mhref = $(this).attr("id").substring(8);
        var mcount = "//api.moot.it/postcounts?path=/test/comments:" + mhref;

        $.getJSON(mcount, function(json) {
            var results = $(this).find(".entry-actions");

            $.each(json, function(key, val) {
                results.prepend("<a class=\"entry-comments\" href=\"{permalink}#comments-outer-wrapper\" title=\"Comments\">" + val["size"] + " Comments</a>");
            });
        });

        $(this).find(".muut-comments").attr("href", "https://muut.com/i/test/comments:" + mhref);
        $(this).find(".muut-comments").attr("title", mtitle);
    });
    window.addedCommentLinks = true;
}

Since this is injected at the footer of the page, the logic should work both for the index and on an individual post (the article loop would just have one iteration since there's only one article item).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top