The Stochastic Game

Ramblings of General Geekery

Announcing September

While I was working on the documentation for PieCrust 2, I decided I might as well do something proper, like support for translations and versioning. The documentation is now in the same repository as the code, and it’s easy to bake the documentation pages for each release.

To do this, I needed a simple tool that could do the basic work of cloning a repository, syncing back to given points in times, and do something. In theory, this would be a simple bash script or something, but I also wanted it to do nothing if it already did something for that same specific point in time.

Thus September was born (if you don’t get the reference, even with the picture above, I can’t help you).

It’s a simple Python script that still packs some goodness to it. It basically lets you roll your own readthedocs kinda website (in a very basic way of course), with appropriate hooks to your repositories.

You run it from inside your repository (Mercurial or Git at the moment) and it will sync back to each tagged changeset and run a command of your choice. You can specify a bunch of stuff in a configuration file, like the command itself (which supports interpolation with a few useful values), the oldest tag to start from (in case you don’t want to go all the way back to the first release), and a couple of other things. It will work out of a temporary directory in which it clones your repository, and stores a cache file that describes what it’s doing. If you keep that temporary directory around, it won’t re-do the work it previously did (so it will only rebake my documentation pages if I moved a tag or added some new ones, and it will re-use and update the repository clone).

It’s still all new and a bit squeaky, so make sure to file some bug reports if you see anything wrong. Oh, and it’s on Github too for you Git kids.


Piecrust 1.x is Officially Deprecated

It had to happen eventually, but PieCrust 1.x is now officially deprecated. It was deprecated more or less unofficially before, as you can see from the lack of activity on the repository, but, well, here it is.

PieLab: Empty Plate

The PieCrust 2 help pages are now showing up by default at the official URL, and that’s where I’ll be focusing from now on.

If you want to upgrade your existing 1.x website to 2.0, you can follow the installation and upgrade instructions. And of course, please contact me if you have issues or feedback!


Actual Play: Realm Of Shadows

After the nice one-shot “The Murderer of Thomas Fell”, my new gaming group decided to continue with the 1930s horror genre and we played through roughly a third of the Realm of Shadows campaign for Call of Cthulhu.

It ended with a near-total-party-kill.

You can read the actual-play for “Kith and Kin” (the first chapter) and “Provender of the God” (the second chapter) over in the RPG section.

One thing that I realize now that I’m writing those things up is how often I feel the need to explain why, as a GM, I’m doing this or that – making the bad guys attack here, adding some clues there, etc. Most of the “actual plays” out there only focus on what happened around the players’ side of the table. But I’m finding it more interesting to also include what’s happening behind the GM’s screen.

This is especially interesting because investigative adventures rely a lot on the GM improvising events and moving around clues to keep the story going, as opposed to, say, a dungeon crawl, where most of the design decisions can be done upfront during the preparation phase, and the improvisation is mostly about adjusting enemies to keep combat balanced.

Adding the GM side of the game makes it easier for me to see what I did right and what I did wrong, and may even get me some constructive feedback on some of those decisions. I’ll try to keep adding things like that in the future reports.


Fanexpo Vancouver 2015

This week-end in Vancouver was FanExpo, with the shopping frenzy, celebrity line-ups, cosplay contests, and friendly comic-book sketching that you’ve come to expect from such conventions, albeit at a smaller scale for our relatively young Vancouver edition.

IMG_3672.jpg

Here’s my artist-commission-focused loot this year:

2015-04-05 17.06.12.jpg

Nadia (from Kukuburi) by Ramon Perez, Conan by Cary Nord, and Iron Fist by Kaare Andrews. And a nice Thundercats t-shirt because I always need a new t-shirt.

After the jump you can see some cosplay pictures I took, although you can probably see better ones elsewhere on the internet.

IMG_3667.jpg
IMG_3652.jpg
IMG_3645.jpg
IMG_3627.jpg
IMG_3631.jpg

You can see the other pictures in my FanExpo 2015 album.


Design For South Paws

Sarah Baird talks about what us left-handed people have put up with all our lives, and all the way back through history:

Day in and day out, though, the biggest hurdle faced by lefties isn’t discrimination — it’s mundane, basic functioning. Almost all facets of society, from ink pens to urban design, are crafted and structured to support, abet and cater to the right-handed majority. For lefties, functioning means a constant, conscious consideration of how they can reverse or modify their natural behavior in order to most effectively move around in the world.

The funny thing is that most of the time, I’m not even thinking about it. I’ll be, say, getting hot air blowing all over me from holding the vacuum-cleaner “the wrong way”, and not really realize that this wouldn’t happen if I was right-handed. It’s just like living in a world that’s slightly less well-designed.

Generally speaking, I’ve probably encountered less hurdles growing up in France than most North-American lefties: spiral notebooks were not used a lot (we had properly bound notebooks) and student chair/tablet combinations were pretty much inexistent.

The last time I really felt the pain of being part of a market minority was when I was shopping for a new computer mouse. Being a palm gripper, I ideally need a so-called “ergonomic” mouse. But those mice are only ever manufactured for right-handed people. The only left-handed ergonomic mouse that I’ve been able to find is the Razer Death-Adder Left-Handed Edition. Many people dislike Razer for their annoying configuration software but I figured I still needed to vote with my money. And, you know, I needed a mouse.

As expected, the configuration software is annoying, but the mouse is really nice.


Piecrust 2 Documentation Preview

I’ve been quite silent for the past few weeks because I’ve been mostly working on the PieCrust 2 documentation website – a lot of time spent writing stuff, trying out different layouts, figuring out how to organize the information, and coding the infrastructure tools that will generate separate documentations for each release.

Now at least I’ve got half of something to show, in case some of you want to provide feeback or – gasp – help! Head over to the PieCrust 2 documentation preview to see it in all its work-in-progress glory!

At this point, it’s only about a third done, so there’s probably another few weeks of work. But it’s interesting how writing documentation forces you to polish a product. This is not new – it’s really a variation of README-driven development – but that’s why it’s taking a long time: a good chunk of the documentation writing time is looking at what I just wrote, thinking that it’s completely stupid, writing what it should be like, and then fixing the code so it does exactly that.

Anyway, back to writing…


Actual Play: The Murderer Of Thomas Fell

To celebrate 2015 (happy new year!) I’m starting a new section on this website: actual play write-ups of RPG games. I got back into gaming a few months ago, GM’ing a few Call/Trail of Cthulhu games.

The first one is “The Murderer of Thomas Fell”, a simple, one-shot adventure that acted as an introductory adventure to my new group of players. If you’re the kind of person that reads actual-plays, or if you plan on running that adventure, you can head over here.


Gutentags for Vim

Autotags is my second “official” Vim plugin (after Lawrencium). It confirms a trend of having a terrible name (although this time for different reasons), but I’m open to changing it since it’s still early. And as that terrible name implies, this new plugin is all about automatically managing your tags.

Edit: thanks to Reddit, it was renamed to Gutentags! I edited this post after this point to use the updated name and links.

Classic Airline Baggage Tags

One of the biggest problems you face when using Vim with a large codebase – and one of the reasons most users still go back to an IDE for their day job – is that tags files in Vim suck. No wait, it’s not even that they suck, it’s that there’s nothing out of the box to help you with it. Which, well, sucks.

In case you don’t know, tags files are basically a reverse index of the symbols defined in a given codebase, as generated by an external tool like Ctags. This is what lets you put the cursor on a function call and jump to the definition of that function. It’s basic stuff that “just works” in an IDE1, but in Vim you need to create, update, and otherwise manage that thing yourself. It’s insanely archaic even by Vim’s standards.

But there’s no reason it shouldn’t “just work” in Vim, and that’s why I wrote Gutentags. Head over to the official website to get started in less than a minute.

In case you’re wondering how this plugin is different from the many other similar plugins out there, or from just doing it the retarded way (i.e. run !ctags -R . every now and then), here it is:

  • No dependencies on anything else than Vim and Ctags: no Python, Ruby, or whatever.
  • Cross-platform: should work at least on Mac and Windows at the moment, Linux should be fine too2.
  • Automatically index new projects: when you open a file in a new project, Gutentags will start indexing it right away. You don’t need to manually run it if you don’t want to.
  • Incremental tags generation: when you edit and save a file, Gutentags will properly and automatically update the index, but only for that file. Re-generating the whole index obviously doesn’t scale for large codebases, yet that’s what most tutorials tell you to do! This is madness and it has to stop.
  • Background update: you shouldn’t have to wait while the index is (re)generated (which is what !ctags -R . does! Again, madness).
  • Keep tags files away: don’t like to see lots of tags files polluting your projects everywhere? Tired of adding tags to every .gitignore or .hgignore file ever? Me too. Gutentags lets you keep them in a hidden place of your own choosing.

At the time of writing this post, Gutentags has been tested on a glorious total of 3 machines (all my own with the same Vim configuration), so watch our for bugs, and please report them on Github or BitBucket.

The usual disclaimers are in effect (this is a random piece of code you found on someone’s blog!), but I just want to warn you that since this plugin kicks off background ctags processes, there could be bugs that will generate humongous tags files while saturating your laptop’s CPU and ending up burning your balls and/or snatch. Again, report them via Github/Bitbucket after calling your local emergency dispatch centre.


  1. Except when it doesn’t. See also: Visual Studio’s Intellisense. ↩︎

  2. Yeah, I’m expecting many bug reports. ↩︎


New features in PieCrust 2

Now that you know about PieCrust 2 and you’ve upgraded your website, it’s time to look at the really new features. Today we’ll talk about the 2 ones that I think are most important: the new content model, and the new pagination model.

And yet another apple pie

(this post is going to be a bit long so here’s something to keep you hungry)

Sources, routes, and taxonomies

In PieCrust 1, like in most other static website generators, the way content was defined was quite rigid: you could have pages, and you could have blog posts. PieCrust did a few extra things, like letting you have multiple blogs, each with its collection of posts, but that was it.

The only way to have a specific set of pages, different from other pages, was to use page metadata and filtering (say, filter pages where type is recipe to get all recipes), but that didn’t translate to a good file-system organization, required remembering to tag things correctly, and required to use the inverse filter to get the other pages. You also couldn’t have a different URL format for all recipe pages, as compared to normal pages.

Enter PieCrust 2, where all the content is, under the hood, defined with sources, routes, and taxonomies. Those are generated for you to something equivalent to PieCrust 1 content if you don’t define them, but you can override that for totally custom content.

Sources

Sources are where pages come from. Two source types you already know (if you used PieCrust 1 before) are:

  • the “simple” page source, where pages are found recursively under a given directory, and their relative path translates to their relative URL.
  • one of the “blog” page sources, where pages are found in a closely structured directory, and both the date and “slug” of the post are defined by the filename. So in the case of, say, the flat post source, all posts are files named YYYY-MM-DD_foo-bar.md directly under the posts/ directory.

Because a site can have as many sources as you want, it already means you could create a “recipes” source, and put all the recipes in a different directory than the other pages, so that’s already nice.

But in the future there will also be more advanced sources. See, the “simple” page source just gives one piece of information about a page: its relative URL. But the blog post sources give more information, like the date of the article (“simple” pages need to specify it as part of their config header).

You could therefore imagine, say, a page source where each folder applies a tag to pages inside it. So if you created a page like recipes/pies/fruits/apple-pie.md, it would automatically have tags pies and fruits applied to it, as if you wrote tags: [pies, fruits] in its configuration header. Another useful source would be one that applies a hierarchical order to its pages, based on a filename prefix – this would be well suited to things like documentations.

Routes

Now that PieCrust knows where to find your content, routes define how it’s exposed – or parsed, if you were to run PieCrust as a lightweight CMS, or when running chef serve.

A route defines the shape of the URL of a page. If you’ve used PieCrust 1, you can think of it as a generalization of the post_url/tag_url/category_url settings.

At the moment, it can only use the same information as the one provided by the source (e.g. the year, month, day, and slug of a post for a blog post source), but in the future you’ll get to use all the other page metadata too (so that you can generate URLs that include categories or tags if you want).

Taxonomies

Another generalization from PieCrust 1 are the taxonomies. Before, only categories and tags would have automatically generated listing pages. Now you can have whatever you want. You just need to specify if a taxonomy can have several terms applied to a page (like tags) or not, the name of the term listing page (like _tag.html and _category.html), and a few other optional things.

Putting it all together

Let’s say we want to have a section in our website where visitors can browse our favorites recipes. We want to put all recipe pages in a recipes/ directory (next to pages/ and posts/), be able to tag them by ingredients, with listings of recipes by ingredient being created automatically, and be able to tweak the URLs for all of this.

We’ll specify appropriate sources, routes, and taxonomies in the site configuration. Let’s start with just getting the recipes going:

site:
    sources:
        recipes: {}
    routes:
        - url: /recipe/%path%
          source: recipes

This will make PieCrust look for pages in the recipes/ directory, using the default page source (since we didn’t specify anything), i.e. the same as the one used for pages/. URLs that look like /recipe/foo/bar will match our new route, and a file named foo/bar.md will be loaded from the recipes/ directory in that case.

Now’s the time to add the “ingredients” taxonomy. This gets more complicated because we have several things to specify:

site:
    sources:
        recipes: {}
    taxonomies:
        ingredients:
            multiple: true
    routes:
        - url: /recipe/%path%
          source: recipes
        - url: /recipes/with/%ingredients%
          source: recipes
          taxonomy: ingredients

This does:

  • Add a new taxonomy named ingredients. It’s a multiple taxonomy, meaning that pages can have more than one ingredient assigned to them (this tells PieCrust it potentially has to generate listing pages for combinations of ingredients).
  • Add a new route for listing recipes by a given ingredient. Here, the %ingredients% token, along with the taxonomy: ingredients setting, let PieCrust know how to properly find and match content for this route.
  • When a listing page needs to be generated, PieCrust will look for a recipes/_ingredients.md page, passing whatever value was matched by %ingredients% to an ingredients template variable. This is analogous to how tag and category listing pages work in PieCrust 1.

Some other interesting facts:

  • You can list all recipes by starting with {% for recipe in recipes %}.... Sources have a page iterator exposed by default to a template variable of the same name as themselves.
  • You can create a new recipe page easily with chef prepare recipes foo-bar.

There are many advanced settings to change the behaviour of PieCrust, but they’re outside the scope of this already quite long blog post.

Pagination

Another big change in PieCrust 2 is how pagination is handled. In PieCrust 1, you could only paginate blog posts, but in PieCrust 2 you can paginate any list of items – pages or otherwise.

The new paginate filter lets you do that, by returning a Paginator instance, exactly like the existing pagination object. But where the pagination object returns something that lists the posts in the default blog source, the paginate filter will return something that lists whatever it was passed.

This is especially useful for galleries, as shown with my Meeting Notes doodles. This was done more or less like so:

{% set thumbs = assets|paginate(9) %}

{% for thumb in thumbs.items %}
<img src="{{thumb}}" alt="Note" />
{% endfor %}

[Older entries]({{ thumbs.prev_page }})
[Newer entries]({{ thumbs.next_page }})

Of course in reality there’s more fluff (CSS classes, etc.) and tests around using prev_page and next_page, but you get the idea. Just like in PieCrust 1, assets returns the list of page assets URLs (in this case, a whole bunch of pictures), and the paginate filter makes sure only 9 of them will be shown on a given page. It also tells PieCrust to generate sub-pages.

Obviously, you can’t use 2 pagination sources on the same page – PieCrust wouldn’t know how to generate sub-pages that go in 2 different directions, so you’ll get an error if you try that.

Call for feedback

Please get in touch with me, or post comments here, if you have some constructive feedback about this new content model. PieCrust 2 is still in alpha, so there’s time to change the design without messing up every other PieCrust user.


Upgrading to PieCrust 2

The recently announced PieCrust 2 is all fine and dandy if you were to create a new website – the command line interface and user experience are essentially the same out of the box – but you will find that it can’t handle an existing PieCrust 1 website. This is because a few things have changed… luckily, the chef import command and this blog post will get you going in no time!

Installing PieCrust 2

First, get PieCrust 2 on your system:

  • Install Python 3.
  • Run pip install piecrust in a console.

If you want to install the bleeding edge (read “unstable”) version directly from BitBucket or GitHub, instead of the latest posted release from the Python package manager, you can do one of:

  • pip install hg+https://bitbucket.org/ludovicchabant/piecrust2#egg=PieCrust
  • pip install git+https://github.com/ludovicchabant/PieCrust2.git#egg=PieCrust

There are many other options if you want to install PieCrust for advanced scenarios. See the pip documentation.

Check that everything’s OK by running chef --version. At the time of writing, you should get something like 2.0.0-alpha2.

Note: If you still get a 1.x version, you probably have the PieCrust 1 directory showing up first in your PATH environment variable, so go change that (or delete PieCrust 1 altogether!).

Upgrading a PieCrust 1 website

The chef import command was previously used for importing content from other CMSes like WordPress. Now it can also import content from a PieCrust 1 website, and even upgrade it in place. Get in your website and try:

chef import piecrust1 --upgrade

You’ll notice that a lot of things got moved. The previous layout for a website looked like this:

+ root
|- _cache/
|- _content/
|     |- config.yml
|     |- pages/
|     |- posts/
|     |- templates/
|- css/
|- images/
|- lots/
|- of/
|- other/
|- crap/
|- whatever
|- .gitstuff

Now it looks like this:

+ root
|- _cache/
|- assets/
|     |- css/
|     |- images/
|     |- other-crap/
|- pages/
|- posts/
|- templates/
|- config.yml
|- whatever
|- .gitstuff

Basically, the _content directory is gone… everything got moved up one level, while all the asset files (CSS, images, fonts, etc.) got moved into an asset folder1.

The benefits of this change are:

  • It looks better! There’s no more mix of different “things” at the root level (magic folders, assets, source-control files, miscellaneous things…). Instead, “things” are arranged in different folders that are almost self-explanatory (mostly because you can choose them!).
  • All the assets that should be processed and copied as part of the bake are in assets. Anything that’s only for development purposes (source control files, miscellaneous stuff) can be in the root directory, or in a different folder than assets, and they won’t be picked up by the bake. This prevents a lot of “oh shit” moments where you forgot to add something to the baker/skip_patterns config and a whole bunch of files are baked but you didn’t mean to.
  • It’s going to be easier to manage interoperability with other tools such as Grunt, by having such external tools operate on other top-level directories.

A few other things also changed, mainly because of the move from Twig to Jinja as the default templating engine. Although they’re very similar, they do have some differences in terms of built-in functions and filters.

  • An example is that Twig’s slice filter maps to an array notation in Jinja (so {{items.slice(3, 6)}} becomes {{items[3:6]}}), and Jinja’s slice does something completely different (although very useful)!
  • Another example is date formatting, which is different between PHP and Python.

The importer will try to fix those things automatically for you (or at least warn you about it and provide guidance), but it’s probably going to miss a few ones since I only know about those I ran into while upgrading my own websites. Please report any such problems, thanks.

Unsupported features

PieCrust 2 is not quite feature complete compared to PieCrust 1 – I can’t reasonably wait until 100% of the feature set is implemented before getting it out there for feedback.

Here are things I know are missing:

  • Running as a CMS: there’s not much code needed for that, but there’s no WSGI application class yet.
  • A plugin API: not much code needed yet either, but yeah, you can’t at the moment drop anything in the plugins folder, it won’t get loaded.
  • Slugification of taxonomies: tags and categories containing non-ASCII characters will keep them for now. PieCrust 1 had options for transliterating them into their non-accentuated/ASCII counter-parts.
  • Support for RSS/Atom feed scaffolding (chef prepare feed).
  • Mustache as an alternative template engine.

There are also probably things I don’t know are missing, so make sure you ping me if something you care about is not on this list.

In the next blog post, we’ll finally take a look at the new features in PieCrust 2, including the completely new underlying system for specifying pages, taxonomies, and URLs.


  1. Don’t worry, it’s configurable. You can put your asset files in a
    different folder, or even in multiple folders. ↩︎