Using PowerShell to generate Jekyll tag pages
I’m hosting this blog on GitHub using Jekyll which is a fantastic free combination. But with anything that’s free there are some drawbacks. Primarily it’s the inability to use custom Jekyll plugins in GitHub.
I want to keep this combination so I’ve been following an article that describes how to generate tag pages without having a custom plug-in.
All is well-and-good, but for every tag that’s been made, a static page must be created which lists all posts with that tag. This seemed like a pain to keep up-to-date and a perfect opportunity to test my PowerShell skills!
The first step is to iterate over the lines in the .\_data\tags.yml file which is in this format:
net:
  slug: dot-net
  name: .Net
android:
  slug: android
  name: Android
angularjs:
  slug: angularjs
  name: AngularJS
The Get-Content PowerShell command will fetch the contents then I can filter only the lines I want with Select-String and a regular expression:
get-content .\data\tags.yml | select-string "^[^ \t]"
That regular expression is simply ignoring any line that begins with either a space or a tab.
So now we have a list of lines like this:
net:
android:
angularjs:
I’m going to need to get rid of the trailing colon and then I can use each keyword to create a string:
... %{ $a = $_.Line.TrimEnd(':'); "--- `nlayout: blog_by_tag`ntag: $a`npermalink: /blog/tag/$a/`n---`n`n"
Here I’m:
- Using 
%which is an alias forFor-Each - Within the 
For_eachbody$_represents the current item - The previous 
Select-Stringreturn aMatchInfoand a member on that object that returns the line containing the match isLine - I’m using the .Net 
TrimEnd()to remove the trailing colon - Assigning the result of the 
TrimEnd()to a variable$a - I can then create a brand to string using double-quotes - and this is important since using double-quotes will use string interpolation and therefore any contained variables will be expanded. In other words 
"$a"becomesthe string dataif$a = "the string data"whilst'$a'will remain$a. - In the string I’m outputting newlines with ``n`
 
The final step is to write each of these strings to a new file basing the filename on the keyword stored in the variable $a:
... | Out-File -FilePath ".\blog\tag\$a.md" -Encoding ascii }
The annoying thing here is Jekyll wants UTF-8 encoded ]files but without a BOM but this isn’t easy with Out-File and so I’ve just used ascii instead which is fine for the moment.
So put all together this command is:
get-content .\_data\tags.yml | 
select-string "^[^ \t]" | 
%{ 
    $a = $_.Line.TrimEnd(':'); 
    "---`nlayout: blog_by_tag`ntag: $a`npermalink: /blog/tag/$a/`n---`n`n" | 
    Out-File -FilePath ".\blog\tag\$a.md" -Encoding ascii 
}
The next improvement would be to iterate over the posts themselves, find all the unique tags and write the tags.yml file… but that’s for another day.
Post by: Philip Hendry