How to Promote Posts Based On Labels And Recency in Blogger


Awesome Tips Series about Blogger

The Goal

  • Popular Posts in Blogger shows posts that are most viewed in last 7/30 days, last year or all time. But maybe some posts are popular because of its simplicity, or shared by you or others in stack-overflow or social media.
  • As a tech blogger, We want to promote in-depth posts, and also consider their recency.

When to Use It

  • Add Label Must Read to posts that we want to promote.
  • Add a HTML/JavaScript gadget with the following HTML/JavaScript code.
  • We can have multiple gadgets to promote posts from different label.
  • We can also add Related Post to current page to promote posts with same label.
    • We don’t have to manually add or update the related posts.
    • demo link
    • I use markdown to write post. ```markdown

```

Series
  • We may continue to write multiple articles about same topic.
  • We can use the script to automatically pull new posts from this series and show them in old posts.

The Implementation to Randomly Pick N Items From Weighted List

  • Use feeds API to get top 50 latest updated posts from label: Promo and give each item a weight based on updated time.
  • We can use HTML minifier to minify the code.
  • As these functions may be used by different widgets or places, we can add the code into a “HTML/JavaScript gadget” and put it right below header at Layout.
<script type="text/javascript">
var maxRelatedPostsCount = 10;
var maxPopularPostsCount = 20;
var publisedPopulars = new Set();
var publisedRelateds = new Set();
var maxPopularTrendingCount = 20;
var publisedTrednings = new Set();

function weightedRandomPopularPosts(json) {
  document.write('<li>', "<a class='home-link' href='/p/archives.html'>Archives</a>", '</li>');
  weightedRandomImpl(json, publisedPopulars, maxPopularPostsCount);
}
function weightedRandomTredningPosts(json) {
  document.write('<li>', "<a class='home-link' href='/p/archives.html'>Archives</a>", '</li>');
  weightedRandomImpl(json, publisedTrednings, maxPopularTrendingCount);
}

function weightedRandomRelatedPosts(json) {
  weightedRandomImpl(json, publisedRelateds, maxRelatedPostsCount);
}

function weightedRandomRelatedPostsAddToParent(json) {
  var parentNode = document.getElementById("related_posts_content");
  weightedRandomImpl(json, publisedRelateds, maxRelatedPostsCount, parentNode);
}
// TODO random or order? get all or not
function weightedRandomImpl(json, publisedPosts, maxCount, parentNode) {
  var weightedPosts = getPosts(json);
  if(weightedPosts ==null) return;
  while (publisedPosts.size < maxCount) {
    var picked = pickOne(weightedPosts);
    if (picked == null) break;
    if (publisedPosts.has(picked.post)) break;

    publisedPosts.add(picked.post);
    weightedPosts.delete(picked);
    if (parentNode) {
      var li = document.createElement("li");
      li.innerHTML = picked.post;
      parentNode.appendChild(li);
    } else {
      document.write('<li>');
      document.write(picked.post);
      document.write('</li>');
   }
  }
}

function getPosts(json) {
  var weightedPosts = new Set();
  if(json.feed.entry == null) return;
  var totalCount = json.feed.entry.length;
  for (var count = 0; count < totalCount; count++) {
    var entry = json.feed.entry[count];
    var postTitle = entry.title.$t;
    var posturl;
    for (var b = 0; b < entry.link.length; b++) {
      if (entry.link[b].rel == 'alternate') {
        posturl = entry.link[b].href;
        break;
      }
    }
    if (window.location.href == posturl) continue;
    if (postTitle.toLowerCase().startsWith("draft")) continue;
    weightedPosts.add({
      post: postTitle.link(posturl),
      weight: totalCount - count
    });
  }
  return weightedPosts;
}

function pickOne(weightedPosts) {
  var totalWeight = 0;
  for (let post of weightedPosts) {
    totalWeight += post.weight;
  }
  var randomWeight = Math.random() * totalWeight;
  var currWeight = 0;
  for (let post of weightedPosts) {
    currWeight += post.weight;
    if (currWeight > randomWeight) {
      return post;
    }
  }
}

function series(json){
  seriesImpl(json);
}
function seriesImpl(json, publisedSeries) {
  var weightedPosts = new Set();
  var totalCount = json.feed.entry.length;
  for (var count = 0; count < totalCount; count++) {
    var entry = json.feed.entry[count];
    var postTitle = entry.title.$t;
    var posturl;
    for (var b = 0; b < entry.link.length; b++) {
      if (entry.link[b].rel == 'alternate') {
        posturl = entry.link[b].href;
        break;
      }
    }
    if (postTitle.toLowerCase().startsWith("draft")) continue;
    var finalUrl = postTitle.link(posturl);
    if (publisedSeries && publisedSeries.has(finalUrl)) continue;
    if(publisedSeries) publisedSeries.add(finalUrl);
    document.write('<li>', finalUrl, '</li>');
  }
}
</script>
<script src="https://lifelongprogrammer.blogspot.com/feeds/posts/default/-/Must Read?orderby=updated&alt=json-in-script&callback=weightedRandomPopularPosts&max-results=60">

Demo

Labels

adsense (5) Algorithm (69) Algorithm Series (35) Android (7) ANT (6) bat (8) Big Data (7) Blogger (14) Bugs (6) Cache (5) Chrome (19) Code Example (29) Code Quality (7) Coding Skills (5) Database (7) Debug (16) Design (5) Dev Tips (63) Eclipse (32) Git (5) Google (33) Guava (7) How to (9) Http Client (8) IDE (7) Interview (88) J2EE (13) J2SE (49) Java (186) JavaScript (27) JSON (7) Learning code (9) Lesson Learned (6) Linux (26) Lucene-Solr (112) Mac (10) Maven (8) Network (9) Nutch2 (18) Performance (9) PowerShell (11) Problem Solving (11) Programmer Skills (6) regex (5) Scala (6) Security (9) Soft Skills (38) Spring (22) System Design (11) Testing (7) Text Mining (14) Tips (17) Tools (24) Troubleshooting (29) UIMA (9) Web Development (19) Windows (21) xml (5)