Silencing @AusGLAMBlogs

18 August 2017

A little while ago, GLAM blogger Danielle asked if it would be possible to allow bloggers to stop AusGLAMblogs from indexing and tweeting a particular post. Many bloggers mix professional and very personal posts, so Danielle's request seemed pretty reasonable - bloggers don't want some personal posts to be pushed into their professional sphere, and, frankly, most GLAM professionals probably don't want to read them anyway.

I've finally gotten around to creating a simple workaround. My first solution was pretty straightforward:

var notGlam = _.contains(item.categories, 'notGLAM') || _.contains(item.categories, 'notglam');
  if (!notGlam) {
    // all the rest of the RSS ingest logic goes here
  } else {
    // don't do anything
  }

The AusGLAMBlogs app and Twitter bot are entirely driven by RSS, that wonderful web technology of which pundits keep declaring the death, at precisely the time it is single handedly powering the spread of the new hotness in web content (aka podcasts). The app looks for new posts every ten minutes, and if it finds any, adds them to the listing and queues a tweet. The obvious way to stop a post from being added and tweeted is to include a bit of metadata in the RSS feed for that post, and filter it out. The code above simply says "if the post has a tag of 'notGLAM' or 'notglam', don't do anything".1

The thing that makes this a lot simpler is that Meteor, the JavaScript/nodejs framework I used to write the app, includes underscorejs by default (because it's needed within the Meteor code itself). Underscorejs is a really useful library of 'functional programming helpers' - it allows you to do things that are possible with plain vanilla JavaScript, but much simpler if you can just use the underscore function. In the example here, I use the npm feedparser package to grab the RSS feed and spit it out in nice, normalised JSON. Each post in an RSS feed will have an array called "categories", which includes anything a CMS or blogging platform calls a category or a tag. So _.contains does what you probably expect it would: returns true or false depending on whether the array does indeed 'contain' the value you're looking for.

I was feeling quite pleased that I'd found a simple solution to this problem, until I remembered that I've been pushing all the AusGLAMBlogs code to GitHub in the hope that it might be useful to (and used by) other people. That means that it really needs to be relatively easy to customise. The other problem with the initial solution is that if I want to add new filter tags I have to keep adding more 'or' statements. What we really want here is a list of filter tags, and then to check whether anything in that list is included in the tags from each post. Luckily, underscorejs saved the day again, with _.find. This function allows us to check each value in an array against a function, and return true or false (i.e. 'found') if the function returns true for any of the values. So we can combine both of these underscore functions to take each tag in a post, and run _.find against a function that asks if the filter list _.contains the tag:

var filterList = ["notGLAM", "notglam", "Notglam", "#notglam", "#notGLAM"];

var hiddenPost = _.find(item.categories, function(tag){
  return _.contains(filterList, tag)
});

if (!hiddenPost) {
  // all the rest of the RSS ingest logic goes here
} else {
  // don’t do anything
}

Now if someone wants to make their own app for, say, people who blog about cricket, they can change the filterList to use the tag notCricket and it will work the same way.

The upshot is - if you're writing a post for your usually-GLAM-themed blog and you don't want it to be ingested into AusGLAMBlogs and tweeted, simply include notGLAM as a tag. Simple!

Oh, and thanks to Danielle for the suggestion!


1

Technically what is actually says is "If the post isn't not about GLAM, do stuff", because "not about GLAM" is an exception to the normal behaviour of the app, and I prefer to put exceptions second in an if / else statement.