Recent Articles

GitFocus

Automate entering GitHub & GitLab issues into OmniFocus

Styled to a ‘B’

BBStylish – attractive, customisable BBEdit Preview CSS

Welcome, Number Thirteen

There’s nothing unlucky about BBEdit 13

Strings Strummed

Finding creativity and rediscovering GarageBand

I haven’t used GarageBand since it was released in 2004. Not for any particular reason, mind. I’ve never been much of a music maker, so I didn’t have any occasion to use it. Clearing out my iPad last night, I realised I still had the app installed. Bored, I opened it to have a look around. I’m glad I did.

I was immediately taken by the magic and pleasure you get from playing an instrument, and I was surprised at how good – realistic – the instruments sound. You can download even more, including some really fun ones like toy instruments.

After spending a fair amount of time playing instruments I found the loops and lost myself completely. It was so easy to start building music that sounded great with no effort. I was able to just ‘get in the zone’ and be creative. It was a lot of fun, and .

I’ve been struggling with creativity for the past few months. Lots of factors have contributed to this – not least of all my job change – but a bevy life and lifestyle changes, too. Some of the creative spirit has returned the past couple of weeks, and making music last night resonated deeply. It’s time to blow out some of the cobwebs.

Erin

A remembrance

I seem to love endings, and due to some flaw in my nature, the messier and more unsettling the better. When I was a teacher, it was like I had a subscription. Every year, more goodbyes. And in most cases, for forever.

Maybe not forever forever, though. Maybe.


There are no maybes today. Erin is gone. She was my best friend, my pseudo-sister, my platonic soulmate.

She left Japan and moved home a few years ago. We had our goodbyes, both quite certain we’d see each other again before five years had passed – unequivocally certain before ten had done. But that was before the illness, the malevolence that broke all certainties, except for one: it would kill her in three.

At our parting, we decided no tears were to be shed – it wasn’t forever, after all. I wish I could have kept that pledge, but this time it was forever and such things cannot be helped.

Goodbye, my love.

A photograph of a woman, Erin, presenting her unusually small glass of beer at a restaurant in Japan.

GitFocus

Automate entering GitHub & GitLab issues into OmniFocus

If you needn’t read more, download GitFocus from GitHub.

I recently started a new job where all of our documentation is managed through git and a lot of my work comes from issues and merge requests filed on GitLab. To keep track of them, I turn to OmniFocus, no surprise.

It was clear by the second day that I didn’t fancy making all the actions by hand, though. Because of security concerns, I couldn’t turn to a web-based service like Zapier to help, so I decided to write an AppleScript. That’s more my pace anyhow.

How the scripts work

I had two goals: make the action title attractive and save it to an OmniFocus project corresponding to the GitLab project.

Fortunately for me, GitLab and GitHub alike have page titles that are information-rich, and it’s trivial to use AppleScript to fetch those titles from Safari. On the other hand, I had no desire to deal with processing that text in AppleScript. For that, I wrote two small Perl scripts, which feed their results back in to the AppleScript.

Together, they perform four primary tasks:

  1. Collect information about the web page from Safari.
  2. Transform the page title into an action title.
  3. Based on your specifications, determine which OmniFocus project the action is saved to.
  4. Make the action in OmniFocus.

Titling

The first Perl script called is the titler, which transforms a web page title like this:

Update 'this thing' to 'that thing' and link to them from each (#8155) · Issues · content / web / support / en · GitLab

…into an action titled:

resolve ❮#8155❯ – ‘Update 'this thing' to 'that thing' and link to them from each’

I put the ticket number at the front so that both it and the titles would start in roughly the same position for each action, improving readability. The heavy angle brackets are there to help the issue numbers stand out to make them scannable.

If you want to change the verb, capitalisation or anything else about the action title, instructions can be found in the gitfocus-titler.pl file.

Sorting

The resulting action gets sorted into a corresponding OmniFocus project based on the sorter. Beware, for it to work, it must be configured.

Full instructions for how to set up the sorter are in the gitfocus-sorter.pl file. In short, the script checks if a search string is in the page title. If found, the project name is passed back to the AppleScript. For the current example, I’d use the following to save the action to the Support Pages project in OmniFocus:

print "Support Pages" if $page_title =~ m`content / web / support`;

Action Creation

All being well, once the script has all the information it needs, it will make the action and save it to the project as specified. If the script is called on a page that’s not GitHub or GitLab, or if it fails to recognise the site correctly, the new action is dropped in the quick entry window.

Into the wild

I was content leaving this in a rough state for myself, but hearing about my work, Rose’s ears perked up. I shared the scripts with her and she decided she wanted a little more information in her actions. With a quick bit of JavaScript wizardry, she had the script saving the issue content and author in the notes field. Then, with thanks to Ken Case, she added a button to reveal the created action in OmniFocus.

After all the work, she thought we should write it up to share with others. I agreed, but if it were to be presented to a general audience, I wanted sharp edges padded where possible, and where not, explained. Thus, I wrote up some documentation and added a little error handling, particularly because the issue content and author are prone to failure, should GitLab change their page markup.

Get GitFocus

Perhaps unsurprisingly, GitFocus lives on GitHub. You can always download the latest version there.

Issues, Bugs, Feature requests

Should you encounter any problems with the scripts, file an issue on GitHub or email me. I will review pull requests and accept those that fix bugs or add features that seem fitting.

To use GitFocus

  1. Copy all three script files to the Safari scripts folder at: ~/Library/Scripts/Applications/Safari/
  2. Edit gitfocus-sorter.pl to add your GitLab or GitHub, and OmniFocus projects.
  3. Run the AppleScript. You can invoke it from the system Scripts menu, but I recommend using a keyboard shortcut assigned with FastScripts.

Styled to a ‘B’

BBStylish – attractive, customisable BBEdit Preview CSS

To repurpose a Douglas Adams line:

It can hardly be a coincidence that no language on Earth has ever produced the expression ‘As pretty as Times New Roman.’

I’m being uncharitable, of course. And besides, in this case, it’s not Times New Roman, but rather Times. Though you’d be forgiven for mistaking the two. Be that as it may, Times is, to my eye, no more attractive than its cousin.

This is the first and most noticeable problem with previewing Markdown files in BBEdit.

Speaking with Rose the other day, she lamented this fact. I had largely put the default look of the Preview in BBEdit window – which comes from WebKit – out of my mind.

Annoyed by excessively long lines, small text and, yes, Times, I made my own default stylesheet for previewing Markdown ages ago. I don’t know how many other people have gone to this trouble, though.

I considered sharing my stylesheet for others to use. Knowing that I’m pretty picky about things like this, when I considered the idea, I saw a glaring problem. Other people are bound to want slightly different text sizes, fonts, colours – and all the rest. Fine, but will everyone be willing or able to edit the CSS?

Perhaps not, so I came up with another solution – I made a new stylesheet but made it approachable and more easily customisable. As is tradition, I named it with a ‘BB’ prefix and called it BBStylish.

Introducing BBStylish

BBStylish is a stylesheet for BBEdit’s Preview window that offers attractive defaults, but which can be customised with little to no knowledge of CSS.

Screenshot of this article previewed using the BBStylish stylesheet in the ‘Preview in BBEdit’ window.

Download BBStylish (Version 1)

How BBStylish works

You can customise BBStylish to better suit your preferences. Out of necessity this requires some precision, but I’ve tried to make it approachable, even if you’re not familiar or comfortable with CSS. Explanations and examples are given for each of the ‘settings’.

The setting (variable) is preceded by two hyphens and ends with a colon, like so:

--text-zoom:

Your setting goes after the colon, followed by a semicolon. Thus a full setting line looks like this:

--text-zoom:  120;

Important: This bears repeating – the line must end with a semicolon.

Apart from that, the other important note is that spaces and tabs are ignored, except between quotation marks.

How this works, more technically

I’ve made the setting system using CSS variables, calculations and by concealing the various units like em, ch and, for consistency, %. The variable names are understandable and there’s an excessive amount of comments to explain what each does, and how to edit them to get the desired effect.

Thus, to change the line height in the Preview window, and have it affect – and keep beautiful – the rest of the page, you need only edit the value for one line instead of eight:

--line-height: 1.65;

In the case of line height, a unit isn’t necessary. But for others, like --footer-space, it is. I hide this away and only ask the user enter a number. Then, in the body selector I use the calc function to effectively convert it (second line):

margin-top: calc( (var(--line-height) * 2.5rem) +
                  (var(--footer-space) * 1rem) );

The converted value is added to the default to help ensure the layout stays attractive and readable. Negative numbers also work.

How to use BBStylish

The DefaultCSS_Markdown.css file must be placed in the Preview CSS folder of BBEdit’s Application Support folder. The easiest way to open that folder is from the menu bar: choose BBEdit › Folders › Preview CSS and drag the file to the folder.

Then, write.

When you’re ready, open the Preview window: Markup › Preview in BBEdit (⌃⌘P)

Note: If the name of the file is left unmodified, BBStylish will be used as the default stylesheet when you preview any Markdown file. If you don’t want that, rename the file and ensure that the .css extension is maintained. When you want to use it, choose the file from the ‘CSS’ pop-up menu in the Preview window.

Customising BBStylish

All the instructions for editing the settings for BBStylish are included in the file. And obviously the best way to edit the file is in BBEdit.

You can open the file directly from the Preview window, hold down the Option (⌥) key as you choose the file from the CSS pop-up menu. When you save the file, the changes are reflected immediately.

Dark Mode and BBStylish

When your system appearance, or the BBEdit appearance, is set to dark, BBStylish will use the --dark-mode- colours specified in the file. Enjoy.

If you always want the light or dark version, despite the appearance, duplicate the desired colour values to be the same for both sets.

Font choices

Every Mac comes with some fantastic typefaces you could use for BBStylish. I chose the system San Francisco font as the default because it pretty much always looks good. Georgia can also look nice:

Screenshot of this article previewed using the BBStylish stylesheet, this time using the New York Small font.

Excellent choices abound – Gill Sans and Hoefler Text, for example – try different ones, with different text zoom factors and line heights, to find your favourite.

Fortunately BBEdit can, unlike Safari, still access your locally-installed fonts so anything you’ve got installed is also fair game.


I love the Preview in BBEdit window. I use it for previewing articles on my site, checking work-in-progress NetNewsWire Help Book files, and of course, previewing any Markdown file. I hope this will make you love it a bit more too.

If you have any questions, comments or suggestions about BBStylish, please email me at rd@nostodnayr.net.

Welcome, Number Thirteen

There’s nothing unlucky about BBEdit 13

I’ve heard tales of other text editors for the Macintosh but I find such stories hard to believe. To my mind, there is no other text editor than BBEdit.

The BBEdit logo

It’s been my companion for over twenty years. I’ve never seriously considered any alternative – BBEdit doesn’t let me down, and is never anything short of helpful.

Today we welcome a new version, BBEdit 13. Throughout its twenty-six years, each release has refined and improved what appears to be something so simple – editing text. Plain text.

Version 13’s opening move is in search and the editor. BBEdit’s various search capabilities have always been a killer feature, thanks in no small part to its integration of a regular expression engine. The editor – obviously the killer feature.

BBEdit 13 Editor Updates

New line bar and gutter

I suspect the first thing you’ll notice when you launch BBEdit 13 is the new line number bar and gutter. Rather than being peripheral to the editor, they’re now fully integrated. This comes with two big changes: the current line is highlighted and the numbers are displayed using the same font and size as the editor.

Though I wasn’t complaining, I like both of these changes. The one sticking point is that I still prefer a smaller text size for the line numbers. Fortunately it’s easy to set a maximum size using an expert preference. I write in 18 point Consolas, so I set the line numbers to be a maximum of 12 points:

defaults write com.barebones.bbedit MaximumLineBarPointSize -float 12

The change takes place immediately, so you can try different sizes to see what fits you best, if the default doesn’t suit you. (If you use a Unix Worksheet, you needn’t even leave the app.)

Though I’m not one of them, some people write in BBEdit using a variable-width font. Line numbers in such a font might not look right, so you can instead use the system font’s fixed-width numbers instead:

defaults write com.barebones.bbedit UseSystemFontForLineBar -bool TRUE

Large interface appearance

My favourite enhancement is to the editor’s status bars – a large text option. My eyes are still good enough to see the normal size but the large version is just a bit more comfortable to read. Importantly, though the widgets are larger, they don’t feel it.

A comparison between BBEdit’s status bar in normal (left) and large (right) appearances.

As the change notes state, the status bars name is chosen for brevity. Other items, like pop-up menus, increase in size with the large appearance setting. Weary eyes be eased.

A comparison between BBEdit’s functions pop-up menu in normal (left) and large (right) appearances.

The only problem is that it leaves me wanting more. There are many places in the app where the text is (subjectively) small. Nonetheless, having some of the most commonly tread paths be more accessible is a great improvement. Perhaps such an affordance will be made by the operating system instead some day.

System Appearance and BBEdit Colour Schemes

BBEdit 13 changes how its colour schemes and the Mac OS appearance (light or dark mode) interact. I find the new system easier to understand, but it’s still (necessarily) complex.

You can tell BBEdit to always use either light or dark mode, irrespective of the OS setting. Alternatively, BBEdit will follow the system setting, changing to fit in.

Also in the interest of fitting in, BBEdit maintains a separate colour scheme setting for each appearance. That way you can use one scheme for light mode and another for dark. How this works, or that it works isn’t explicitly stated. Just know that when you change a theme, the change sticks for the current system appearance.

An aside on colour scheme switching

The change is not quite a solution to my problem. I generally want to use a light colour scheme during the day and a darker one at night, but without changing the OS appearance. An esoteric request, which I wouldn’t expect to be accommodated.

In BBEdit, such a situation can often be solved by creating one’s own features using scripting. This is no different, though it doesn’t use the traditional AppleScript approach. Changing the colour scheme preferences using the Mac OS defaults command takes effect immediately. Thus it’s trivial to write a shell script to automate changing schemes.

To change the Light Mode colour scheme:

defaults write com.barebones.bbedit SelectedColorSchemeName "BBEdit Light"

And Dark Mode’s scheme:

defaults write com.barebones.bbedit SelectedColorSchemeNameDarkMode "Toothpaste"

Search in BBEdit 13

Search is surely synonymous with the Find window, and with good reason. It’s not the full story, though. There’s also Live Search and Multi-File Search. Going deeper, there are the line processing commands in the Text menu – and more.

Searching with grep regular expressions

All of these, and other commands, have the power of regular expressions, grep searching, at their behest. For the uninitiated, chapter eight (né seven) of BBEdit’s user manual has long been an excellent learning resource, offering a crash course in writing regex. It’s where I and doubtless many others first learnt of their sorcery.

BBEdit 13 takes steps to bring those teachings into the application proper. First, with the addition of a regex cheat sheet, which lists nearly every possible useful option with a brief explanation of what it does.

BBEdit’s 13 regular expression (grep) cheat sheet
          pop-up menu.

Upon entering a search pattern into a Find window, you’ll now also see potential matches highlighted in the editor, similar to Live Search. It’s great for writing grep searches because it means you can immediately see how much, or how little, you’re matching.

BBEdit’s 13 Find window and a text document showing the new live search result highlighting.

Pattern Playground

Writing a regular expression can be challenging and error-prone for even the most experienced practitioners. When using them for creating replacements using capturing parentheses and backreferences, doubly so.

Enter the Pattern Playground – an extension to the Find system which helps you build search patterns.

The first way it helps is by providing feedback about errors in the entered pattern. If you forgot to close a character class, or missed out an escaped ], you’re told of it immediately. It helps make the grep search less of a black box.

The other help comes when using capture groups and replacements. Say you want to convert this list of dates from a difficult to understand format (month-day-year) to something more standard (year-month-day).

If you want to try along, open a Pattern Playground window, choose Scratch Space from the contents menu and paste in this text:

06-20-1967
05-11-1993
08-04-1997
05-04-1998
11-06-1998

Then enter this search pattern:

(\d{2}-\d{2})-(\d{4})

The pattern has three parts:

  1. A group for the two-digit month, a hyphen, and a the two-digit date
  2. A hyphen
  3. A second group for the four-digit year

Entering that pattern into the Pattern Playground, you’ll see a listing of what each group is capturing (group 0 is always the whole match). Even better, if you enter a replacement pattern like \2-\1 you’ll see how the current match will be affected by the replacement.

BBEdit 13’s Pattern Playground window showing
          the search and replace pattern and a list of dates.

Using the Next button, you can step through each match to check your pattern works as expected. Once you’re happy with it, click the Use for Find button. The pattern will appear in the Find window, whereupon you can perform the operation.

The Pattern Playground is a brilliant help when making any complex pattern. It’s also good for, as the name implies, playing. You might use it to learn or better understand regex, or to improve pre-existing patterns. I find it a perfect complement to the existing search tools.

One small tip for when writing complex regular expressions: Don’t forget that you can turn on Perl-style expanded patterns using (?x). Newlines, tabs and spaces will no longer have an impact on the pattern, meaning you can write a more readable pattern. For clarity, also consider adding comments (?# … ) to any pattern you might save for repeated use. Here’s the pattern from above, transformed:

(?x)
(\d{2}-\d{2}) (?# month-day)
-             (?# add this back in the replacement)
(\d{4})       (?# year)

Other BBEdit 13 Changes

I couldn’t possibly list and explain all the changes in BBEdit 13. But I needn’t anyhow, as it’s already been done: BBEdit 13.0 Release Notes.

Enjoy reading through them with a nice hot drink, and maybe a bit of cake – we’re celebrating! There’s nothing unlucky about this thirteen.

Madness Meets Modernity

Options for using old Movable Type today

I’m a fan of Movable Type – the de facto blogging platform

…of the 2000s.

Movable Type is a static site generator by default, but since its fall, the web has moved on to much lighter static site generators. None of them is as elegant in design or templating to my admittedly nostalgia-tinged eyes. (I dare not consider the other side, with the PHP behemoth.)

It’s not just the web which has moved on, of course. The language Movable Type is written in, Perl 5, has changed too. Most notably, since version 5.14 or so, the language has started to evolve and break old syntax. It is because of this that Movable Type no longer runs correctly, or at all, with modern Perls.

That’s not to say Movable Type 4 won’t run today – it and even earlier versions will, but it takes a little work. We must either:

There are problems with both approaches. Once you find the offending lines, editing the Movable Type code is not too difficult, provided you understand a bit of Perl. This was my approach at my former web host and it worked pretty well. There were still lingering problems, though – there were frequent warnings and image manipulation functions in MT didn’t work. I accepted the trade-offs as a temporary solution. Besides, that was my only option on shared hosting.

Once I moved this site to its own server, running an old Perl became feasible. But again, modernity brought problems. Understandably, any current and supported distribution of Linux is likely using Perl 5.26 or later. Though I may be comfortable running old software for myself, I will not run a publicly-accessible server on a so-called end of life operating system.

Then, CentOS 6. Distributions of CentOS are supported for a very long time and version 6 shipped with Perl 5.10. It was perfect for my needs but it too was a temporary solution. The operating system is only receiving the most critical updates at this point and all support will end in late 2020.

It is necessary to go another way: build and run your own Perl. This version must run parallel to the system’s Perl, and only for those applications which need it. Unless you’re a well-seasoned sysadmin, the process is a bit of an undertaking. It’s imperative to configure the building and installation of the Perl core, and its modules, so as not to disturb the system Perl.

Though it may take effort, and perhaps multiple attempts, it is possible to do on your own. It’s probably not advisable, though.

I am not the only person who has wanted to do this – perhaps even you might. Many people have the need and for that reason, the Perlbrew utility exists. It handles the messy details for you. This is the first step to getting a web app like Movable Type 4 running on modern systems.


Perlbrew is only part of the solution, but it’s probably the majority. You also need to get the web server to use the new old Perl and this takes some additional preparation and work. In a follow-up to this piece I intend to share the details of how I got it working on my machines. For anyone else out there who loves Movable Type and is slightly mad.

Fizsh

Fishy zishy

Armin Briegel, author of Scripting OS X, has been writing a series of articles on his transition from Bash to the Z Shell (zsh). So far there are seven parts, touching on a number of things encountered in zsh:

I’ve really been enjoying reading these articles. There’s at least one more big article to come, covering scripting with zsh.

I was always a bash user because that’s what OS X shipped with. I had put some time in over the years customising aliases and functions, but never anything too deep. After all, I didn’t spend that much time in the Terminal.

About a year ago I started spending more time at the command line and changed my shell to the ‘modern’ shell called fish. It comes with lots of nice in-built features like colourisation! Not just in syntax highlighting on the command line, but you don’t even need to specify a --color or -G flag to get colourised ls output, for example. Holding down Option and pressing the left or right arrow key also does what I expect (as a Mac user), and jumps word-by-word.

Reading this had me wondering whether I should move to zsh myself. Last weekend I spent some time setting it up, moving over aliases and customising my prompt. I’ve been using it since and in that limited time I’ve not found a lot compelling – but I’m also not using any plugins like oh-my-zsh. I agree with Mx Briegel on the matter. I’d rather configure it how I like without assistance, at least at first.

Scripting

Both shells offer nicer scripting syntax. Here I agree with Dr Drang who wrote:

I think people who script in the shell—any shell—are masochists.

Most scripts I’ve got are simple enough that writing them in Perl instead might qualify as more masochistic. However, the script I wrote a couple weeks ago started simple and grew to the point where I was regretting it. I bumped up against bugs and incorrect or poor documentation of the fish specification.

As a result the script is less robust and featured than I’d like, even if it’s only something I’ll use. My mistake. Naturally the bugs and documentation should be corrected, but I should have been using a better tool for the job.

For now I suspect I’ll stick with fish. I can imagine a situation where I might use both: zsh on Linux but fish on my Mac. I will, however, continue to use zsh for a while as I explore features and maybe try some plugins.

Customising DuckDuckGo

Making search match

It is possible to customise DuckDuckGo for yourself using the settings page. Customisations include changing the site’s colours and fonts, but also behaviour, like infinite scrolling and whether the header appears.

Of particular interest to me is that these settings can be modified using query strings. Thus, when you use the search form, the search results page at DuckDuckGo uses colours from my site.

The colour values and other customisations are fed to DuckDuckGo via hidden fields in the search form. For example:

<input type="hidden" name="kj"  value="#41072A"><!-- header-->
<input type="hidden" name="k8"  value="#333333"><!-- text -->
<input type="hidden" name="k9"  value="#C00076"><!-- links -->
<input type="hidden" name="kx"  value="#B4B4B4"><!-- url -->

The work of getting the search from here to DuckDuckGo is handled by redirect rules in my web server configuration. In part because of how I’ve set that up, searching using the https://nostodnayr.net/search/query syntax isn’t customised. It should be possible to make it work, but not really worth the effort.

The Near Past

Producing a ‘Recent Articles’ block with Movable Type

Several weeks ago I added a ‘Recent Articles’ box to the site. At times I may go a couple of weeks between writing these more focused, ostensibly interesting, pieces of writing. It depends mostly on my free time, but also motivation.

Writing these pieces takes several hours, often across multiple days. If I were to set aside the self-deprecation for a moment, I might even say I like these articles and maybe even be proud of them. (I had better stop before I pass out.)

The consequence of these feelings it that I want them to be noticeable and not get buried under the slightly more frivolous link posts. Thus the ‘Recently’ block was born to highlight some of my recent entries. I decided to put it on two pages: the most recent link entry page and ‘below the fold’ of the home page.

Note: The templates discussed below are only the relevant excerpts and the indentation may a bit wonky, at least for my tastes. Links are provided to view the full templates. Alternatively you can download them all at once.

Generating the content block

The most integral part to this is generating the HTML that builds the block. Because it’s used in two places, I saved it as a template module that saves the generated content in a variable called recentlyContent. The items it generates differs slightly depending on where I want the block to go.

If the Recent block is appearing on a link page, then I want the last three articles displayed, no matter when they were posted. When it’s being placed on the home page, there’s a bit more nuance. If the latest article is one of the three most recent posts to the site, I don’t want it to appear in the block.

Plugin Note: This requires the MultiBlog plugin which allows the system to pull data from multiple blogs at once. I call it using the blog_ids attribute. In my case, blog 1 is articles and blog 2 is for linked posts.

The initial <mt:Unless> block handles this logic. The value for the variable on_link_page is specified in another template we’ll see later. If it is unset, <mt:Entries> gets three posts and loops through them testing whether any entries are from blog 1. If one is found, it sets an offset variable which will be used later in this template.

Full template: recentlyContent.mtml

<mt:SetVarBlock name="recentlyContent">
    <mt:Unless name="on_link_page">
        <mt:Entries blog_ids="1,2" lastn="3">
            <mt:If tag="EntryBlogID" eq="1">
                <mt:Var name="articleOffset" value="1">
            </mt:If>
        </mt:Entries>
    </mt:Unless>

The second block of code, in an <mt:If>, gives the Recently block a header and opens the <div>. It handles a special case for setting margins when the block is on a link page, again evaluating the on_link_page variable.

<mt:If name="on_link_page">
    <h2 id="recently-head" class="on-link-page">Recent Articles</h2>
    <div id="recently" class="on-link-page">
<mt:Else>
    <h2 id="recently-head">Recent Articles</h2>
    <div id="recently">
</mt:If>

The final block does the work of putting the article titles and subtitles into HTML. The articleOffset variable appears here as the <mt:Entries> requests the last three articles starting from 0, unless the offset was set to 1 in the initial logic.

    <mt:Entries blog_ids="1" lastn="3" offset="$articleOffset">
        <a href="<mt:EntryPermalink replace='.html',''>" title="Read ‘<mt:EntryTitle>’">
            <p class="recently-title"><mt:EntryTitle widont='1'></p>
            <p class="recently-subtitle"><mt:EntryExcerpt widont='1'></p>
        </a>
    </mt:Entries>
</div>
</mt:SetVarBlock> 

Permalinks have their file extension removed (for clean URLs) and the titles are processed by the Widon’t plugin. The finished <div> is saved in the aforementioned recentlyContent variable to be output in the template which calls/includes the module.

‘Recently’ on the home page

The Recently block is put onto a page in two steps. First, the HTML is generated and placed into the recentlyContent variable as detailed above. This process is called by using the <mt:Include> function.

Full template: index.mtml

<mt:Include module="Variable – Recently">

The template continues by opening up the <main> content block and entering the primary <mt:Entries> loop, calling additional modules to display articles and links.

<main class="page-content">   
    <mt:Entries blog_ids="1,2" lastn="23">
    <mt:If tag="EntryBlogID" eq="2">
        <mt:Include module="Entry Body – Link">
    <mt:Else>
        <mt:Include module="Entry Body – Article">
    </mt:If>

The second step in the process is simply outputting the contents of the variable. For me, choosing where is a bit complicated. On the home page I prefer for the block to appear ‘below the fold’. Which is to say that I want it to appear slightly or completely below the initial viewable area; you have to scroll to see it.

To accomplish this is an inexact science only using HTML and CSS. I concluded that using a basic word count would suffice. If the first item listed is fewer than 110 words, then Recently will be ‘delayed’ and placed after the second.

To get this, I check if the current entry is the first using the __first__ meta variable. If it is, I use the setvar tag modifier (a shortcut for <mt:SetVarBlock>) and count_words, which unsurprisingly counts the number of words returned from a tag.

<mt:If __first__>
    <mt:EntryBody count_words="1" setvar="firstEntryWordCount">

The following <mt:If> evaluates the word count and if there are more than 110 words, it gets the content saved in recentlyContent – done and dusted. Otherwise it sets a variable indicating that Recently should be delayed until after the first entry. The loop then continues to the next entry.

<mt:If var="firstEntryWordCount" gt="110">
    <mt:GetVar name="recentlyContent">
<mt:Else>
    <mt:SetVar name="delayRecently" value="1">
</mt:If>

As the next entry is displayed, it’s no longer __first__, causing the following to be evaluated. If delayRecently is 1 (true), then recentlyContent will be output. This would be true for all following posts, so the final piece is to set the delay variable to 0 (false), ensuring the block is not displayed again.

    <mt:ElseIf var="delayRecently" eq="1">
        <mt:GetVar name="recentlyContent">
        <mt:SetVar name="delayRecently" value="0">
    </mt:If>

    </mt:Entries>
</main>

Once the 23 entries have been evaluated, the main content block is complete.

Compared to the logic used on the home page, link pages are quite simple. I only need to place the block on the most recent entry. These link pages are produced as an ‘individual archive’ in Movable Type parlance. The biggest difference is that the pages aren’t produced in the <mt:Entries> loop, so we can’t use the __first__ variable. Each entry is effectively both first and last as it’s being written by the system.

Instead we can use a slightly roundabout way to evaluate if this is the latest entry by using the <mt:EntryNext> tag. If a next entry doesn’t exist, then include the Recently template and pass the on_link_page variable. (blog_id specifies which blog the template belongs to and is necessary since the Link template is in blog 2.) Finally, display the content generated by the variable.

Full template: link.mtml

<mt:Unless tag="EntryNext">
    <mt:Include module="Variable – Recently" blog_id="1" on_link_page="1">
    <mt:GetVar name="recentlyContent">
</mt:Unless>

That’s all that’s required.

Though it is possible for Movable Type to generate dynamic pages, I still prefer to keep plain, static, HTML pages. Every time I publish a new item its file is created by Movable Type.

Following that logic, every Link page would end up with the Recently block on it. When the page was generated, it didn’t have a next entry. The block would also be stale. But it’s not.

Working around this would be convoluted, but fortunately we can lean on Movable Type’s behaviour to correct the issue. The link pages include navigation links to next and previous entries. When a new entry is created, the previous needs to be updated to add a link to it, regenerating the page. This means our <mt:Unless> block is re-evaluated and Recently is not displayed. Very convenient.