Gerard Condon's Blog

Journal of a software developer.

Adding Microposts to Middleman

I came across the idea of microblogs from Manton Reece’s blog. The idea is that instead of just using the blog for long content, you can post short Tweet like items there also. Needless to say you can just use Twitter for this but it’s more fun to do something unneccessarily complicated! I have form here - like using Octopress for a blog instead of WordPress.

Basically, instead of using Twitter to publish short notifications, you can post them to your own site and if necessary to the likes of Twitter from there. Having control of your own content gives you independence from third party sites - if Twitter shut down tomorrow then my posts would still be available here. If I’m putting content on the web then ideally I would like it to be on my site under my own domain name. I’ve decided to add them first to my chess site and then if they work out there, try to port them to Octopress.

That blog is written using Middleman, which has the ability to use data files. Any yaml file in the data folder is available to the Middleman app using a data.filename.foo like syntax. This means that I can create a yaml file containing the microblog posts and then use that to generate the appropriate html pages.

I have a microposts.yml file with each entry having text and date entries. This is sufficient for the moment but also yaml is flexible enough that I can add more attributes later.

microposts.yml
1
2
3
4
- text: here is another post
  date: 2016-11-19
- text: here is a post
  date: 2016-11-20

I use the Middleman blog extension to generate the blog portion of the site. I want to keep using this as it handles rss, tags, archive pages, pagination etc. It works by generating posts from files in a source folder. In order to integrate with this, I want to generate a file per micropost in the correct location. Under the source folder I split out my posts into two folders manual and automated. I updated the regex in config.rb to handle this blog.sources = "posts/{type}/{year}-{month}-{day}-{title}.html". Middleman will process these equally but now I can check what type the post is by using data["type"].

In the config.rb I delete the contents of the automated folder on each build. I tried using before_build hooks but they were being called too late - the Middleman data structures were already created with the previous contents of the automated folder. This lead to build errors and issues with sitemaps etc. So I just perform the File operations directly in the config.rb. This ensurs that they are executed before the blog extension processes the posts folder. Then I iterate through the micropost data from the yaml file and create the appropriate file in the automated folder.

config.rb# Clear out automated posts folder
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
automated_posts_folder = "#{config[:source]}/posts/automated"
FileUtils.rmtree(automated_posts_folder)
FileUtils.mkdir(automated_posts_folder)

post_counter = 1
data.microposts.each do |micropost|
  post_content = "---\n"
  post_content += "title: mp#{post_counter}\n"
  post_content += "date: #{micropost.date}\n"
  post_content += "tags: microposts\n"
  post_content += "micropost: true\n"
  post_content += "---\n"
  post_content += "#{micropost.text}"

  File.write("#{automated_posts_folder}/#{micropost.date}-mp#{post_counter}.html.md", post_content)
  post_counter += 1
end

I’ve added micropost: true metadata to each of my generated files so that I can check if the post is a micropost using if data["micropost"]. This allows me to customize how I display these posts - in particular I don’t show a title for these posts.

Speaking of titles, some special handling is required for these as the Middleman blog extension uses these for the generated html file names. I added an attribute display_title to the BlogArticle class which will return an empty string if the post is a micropost. This allows me to specify a fake title for each micropost using an incrementing ID counter. The blog extension can use this fake title as normal but it will never be seen by the viewer of the blog. Instead anywhere that a title is required in html markup I can change it to use the display_title attribute. The fact that Ruby has open classes makes adding this very easy - I can do it in the config.rb file and don’t need to go mucking about in the Blog extension code.

config.rb
1
2
3
4
5
6
7
8
9
module Middleman
  module Blog
    module BlogArticle
      def display_title
        data["micropost"] ? "" : data["title"]
      end
    end
  end
end

This means that I can display these microposts just using the main text and not displaying a title. They interleave nicely with longer form blog posts.

Using the Middleman Blog Extension means that I also get RSS integration for these posts. I edited the xml templates to remove the title if the post is a micropost. Now in my RSS reader, they show up with the body text as the title instead of the fake title needed to make the extension work.

This current implementation is basic enough and I have a few ideas of how to improve it in future.

  • I like the idea of the static site but the editing part is not particularly nice and is a bit of a barrier to posting. I would like to use something like Contentful so that I can add posts without having to open a dev environment.
  • Once you have something like Contentful, then the next step would be to use that to trigger automatic builds once a new post is added. This would mean that the site is always updated and assuming Contentful works well from Android, would allow me to make these microposts from my phone.
  • I could use IFTTT to cross post the microposts to Twitter - however I would have to deal with the 140 character limit there. I would also like to automatically post a notification to Twitter when I put up a normal blog post.
  • Currently everything is going into the same RSS feed. I would like to add separate RSS feeds e.g. micropost only, normal post only. I think this would also help with using IFTTT to post to Twitter.
  • One nice consequence of using the Middleman data files is that there is a much better separation of content from markup. I would like to expand this to also apply to full blog posts. Ideally everything content related would come from the data files. Then I have more options as to how to generate those data files e.g. Contentful for the tweets or a Rails app for the pgn files.

Fixing Octopress 2.0 to Work With JQuery

After updating the site to add JQuery, I noticed that the Github aside and the sidebar toggle no longer worked.

Opening up the console I saw the following errors

TypeError: Object 0 has no method ‘charAt’

and for the Github plugin

`Method JSONP is not allowed by Access-Control-Allow-Methods`

Googling for these lead me to Daniel Hilgarth’s blog where he has two posts on how to solve the charAt and jsonp issues.

Fixing Twitter Sidebar for Octopress 2.x

I noticed recently that the Octopress Twitter plugin for my sidebar was broken. The reason is that Twitter no longer supports the APIs that the plugin accesses. Instead now they have a widget page to generate html code that will embed a list of your tweets on your page.

I created a widget for myself and customised it by adding the nofooter transparent noheader attributes to data-chrome. These remove various headings and background colouring so that it blends in with the site a bit more.

To add this to an Octopress site, you replace the code in source/_includes/asides/twitter.html with this new code. I also added a follow button which displays a Twitter formatted follow button and a count of your subscribers.

The full code is as follows

source/_includes/asides/twitter.html
1
2
3
4
5
6
7

<section>
  <h1>Latest Tweets</h1>
  <a class="twitter-timeline" data-chrome="nofooter transparent noheader" data-tweet-limit="5" href="https://twitter.com/gercondon">Tweets by gercondon</a> <script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>
  <a class="twitter-follow-button" href="https://twitter.com/gercondon">Follow @gercondon</a>
</section>

Upgrading to Rails 4.2 on OpenShift

I updated my Rails test app from 4.1 to 4.2. However when I pushed to OpenShift I got the following error

You have already activated rack 1.5.2, but your Gemfile requires rack 1.6.0. 
Using bundle exec may solve this. (Gem::LoadError)

I found the answer on Google Groups here. The root cause is that OpenShift is dependent on Rack 1.5.2 and Passenger 4.0.18. The proper fix will have to wait until they update their versions of that software. Until then to fix this error, ssh into the OpenShift app and in the app-root folder run

gem install rack

Publishing an Application to OpenShift

I was doing some sample Rails apps recently and was looking for a place to run them. Heroku would have been my first port of call but given the limits on database size for the free account, I looked around to see what else was out there. I ended up on OpenShift. The free account gives 3 gears (or VMs) with 1GB storage on each. This is better for me as I can run a proper database on it without the 10000 row limit. The 1GB storage is also persistent so you can use it to store assets.

Redhat has an rhc gem which allows you to control your gears from the command line. You can create new apps from here or you can do as I did and create them from the OpenShift web page. They have a large list of pre-configured applications covering languages such as Java, Ruby, Python and frameworks like Node and Rails.

I selected the Rails 4 application. This forks the Rails 4 example repository from Github. The name you give your application forms the basis for its url i.e. appname-username.rhcloud.com. You can choose a database - the options for Rails are MySql and Postgres. This creates a blank Rails application - to add OpenShift support to an existing application you can follow the steps here.

After a short wait a screen pops up with the database credentials and instructions on how to clone the application to a local git repository.

After I clone the repository I typically change the configuration. I want to also store the application code on Github, so I rename the origin repository to openshift.

 git remote rename origin openshift

Then I add a new origin remote using

git remote add origin git@github.com:gerardcondon/rails-app.git

and I do an initial push to this remote

git push origin

The current master branch is still tracking openshift/master so now I change this to track origin/master using

git branch master -u origin/master

Now by default changes are pushed to Github when I run git push. When I want to deploy to OpenShift I have to manually specify it using

git push openshift

After the push, Openshift will stop the application, perform any db migrations and restart it again. There is also support for adding in your own operations at various stages in the deployment.

If I want to clone the repository on a new machine then I clone from Github and add an OpenShift remote using

git remote add openshift ssh://<<openshift repository ssh url>>

The repository’s ssh url is available from the application’s dashboard on OpenShift.

Linx 7 Standby Battery Life Fix

One issue I had with my Linx 7 was that the battery was draining really quickly in standby mode. I was having to shut down the tablet completely between uses. I found this page on a Linx forum site which recommended upgrading the wifi driver. I installed the driver and now the standby battery life is excellent.

Mini Linx 7 Review

I recently bought a Linx 7 tablet for 70 euro. For the price it’s a great little tablet. It comes with a full version of Windows 8 and a year’s subscription to Office 365. It’s great for Youtube/videos, Twitter and internet browsing. It’s cheap enough, compared to a four or five hundred euro iPad, that I can leave the two year old watch his favourite videos on it without worrying too much. Some parts of the hardware are not up to scratch - the camera is terrible and the headphone jack has static noise - but for the price it’s fine.

One of the best features of the tablet compared to iOS is that it comes with a micro-SD card slot. That means that it is really easy to copy over files from my desktop. I recently tried to load up my iPad with photos and vidoes to show the in-laws. Even though the videos were shot on another iOS device, it was a nightmare to get them on the iPad - a convoluted process involving re-encoding and syncing through iTunes. On the Linx, I just copied the original files to the SD card in Windows, plugged the card in into the slot and was able to watch them immediately.

In fact that original iPad is really only used now as an ereader. I think the usefulness of the applications on iOS has been going down recently compared to other platforms. Quality-wise they’re absolutely fine but they’re fairly shallow compared to what they could be. The race to the bottom app-store economy and the limitations that iOS puts on inter-app communications severely limits the type of apps being written.

I play a good bit of chess and the apps on iOS are nowhere near the quality of those on Windows. And apparently also those on Android. However with the Linx I can run any Windows chess app. Even Chessbase runs fine on it, which gives access to a vast library of Chessbase Fritz Trainer videos. I can open pgn files in multiple different applications and copy and paste data between them. I can use source control to version my notes. Also on Windows, developers are able to charge proper rates for their applications, thus ensuring a robust marketplace for software.

The problem with using Windows applications on the Linx is that the UI is really awkward to use with just your fingers. However to me, this is a small price to pay for being able to use these apps at all on a tablet. Also you can use Bluetooth mice and keyboards with the Linx so at least you have some options.

Update If you have a Linx tablet then you should upgrade the wifi drivers to fix the battery life.

Ruby Command Line Input Using Highline

I’ve been using Rakefiles a lot recently to automate tasks. I find it really useful in comparison to shell scripting as I can run the rakefiles under different OSes (OS X and Windows) and have it behave the same in all cases.

I was building a simple script to automate the generation of pgn files for my chess games. I wanted to be able to enter the details of the games on the command line and then have my script output a pgn file.

I didn’t want to have to go messing about with low level operations such as puts and gets so I searched for something better. I found the Highline gem for this and was really happy with it.

It allows for a variety of input formats

  • To display a prompt to the user and then store the input in a variable use event = ask("Event Title: ")

  • You can specify default values and the default will be listed as part of the prompt. On the command line simply hit enter to get the default value. timeControl = ask("TimeControl: ") { |q| q.default = "5400+15" }

  • You can create a menu from an array of values using the choose function. result = choose("1-0", "1/2-1/2", "0-1", "*")

These can be customised and there are a lot more options available such as entering passwords. If you are doing text input in Ruby, I would advise checking it out.

Open Plan Offices and High Tech Architecture

Jeremy Paxman recently wrote an article criticising open plan offices. They have been a bugbear of mine for a while also. My working life has been spent in open offices or cubicles (never hot desking thank God) and they’re terrible compared to proper offices. Background noise, air-con issues, lack of privacy and personal space are just some of the issues.

Paxman’s article put me in mind of a TV series which featured a lot of open plan offices. This was the Brits who Built the Modern World series on the BBC which detailed the work of the architects such as Norman Foster and Richard Rogers, who were the pioneers of High Tech Architecture. It’s an excellent series and I highly recommend it. The buildings shown typically had a fantastic exterior with really distinctive features. I was really impressed with the level of quality and inventiveness that went into these structures.

However the interiors of these buildings were typically vast open office spaces. The inventiveness that characterized the outsides, had completely vanished when it came to fitting out the inside. Bog-standard, modular office furniture. was the norm. One of the best examples was Norman Foster’s Willis Building in Ipswich. This has a stunning exterior of dark glass panels and a rooftop garden, all combined with a soul-destroying, open plan interior.

The really odd thing for me was that the architects really bought into the open office ideals. They truly thought that this was the best way to design a workplace. I would have loved to have seen what they could have done, if they had put the effort in to design proper working spaces which combined private, focused space along with collaborative areas. They thought they were designing workplaces which were more efficient and collaborative, but to my mind all they succeeded in doing was creating an environment where everyone is distracted and disrupted most the time. It’s a real pity and a waste of their talents.

PS Let’s hope no-one ever interviewing me for a job in an open plan office reads this :)