Categories
CPAN

Two New Modules

There was a London Perl Mongers meeting at ZPG about ten days ago. I gave a short talk explaining why (and how) a republican like me came to be running a site about the Line of Succession to the British Throne. The meeting was great (as they always are) and I think my talk went well (I’m told the videos are imminent). The photo shows the final slide from my talk. I left it up so it was a backdrop for a number of announcements that various people gave just before the break.

In order to write my talk, I revisited the source code for my site and, in doing so, I realised that there were a couple of chunks of logic that I could (and should) carve out into separate distributions that I could put on CPAN. I’ve done that over the last couple of days and the modules are now available.

MooX::Role::JSON_LD

The first is called MooX::Role::JSON_LD. It’s a Moo role that you can add to your classes in order to make it easy to generate JSON-LD from your objects. What’s JSON-LD? I hear you ask. Well, it’s JavaScript Object Notation for Linked Data. The most popular use for it is to add structured data to web sites. Adding structured data to your web site makes it easy for Google (other search engines are available) to understand what your web site is about and that, in turn, will hopefully persuade Google to list your site higher than it otherwise would. You can see JSON-LD in action on a couple of my recent projects – https://lineofsuccession.co.uk/ and https://towerbridge.dave.org.uk/ (you’ll need to look at the source to see it).

I’ve written the module as a Moo role, which means it should be usable in Moose classes too. To add JSON-LD to your class, you need to do three things:

  • Add the role to your class
  • Define a method called json_ld_type() which defines the type of JSON-LD object that you want to generate (see Schema.Org for a list of types)
  • Define a method called json_ld_fields() which defines the fields that you want to include in your JSON-LD. There are a few ways to define that which allow you to do things like mapping an output field to a method of a different name. The details are in the documentation.

Your class inherits two methods from the role – json_ld_data() returns the data structure which will be encoded into JSON (it’s provided in case you want to massage the data before encoding it) and json_ld() which returns the actual encoded JSON in a format that’s suitable for embedding in a web page.

Genealogy::Relationship

One of the most satisfying parts of the Line of Succession site to write was the code that shows the relationship between a person in the line and the current sovereign. Prince Charles (currently first in line) is the son of the sovereign and Tāne Lewis (currently thirtieth in line) is the first cousin twice removed of the sovereign.

That code might be useful to other people, so it’s now on CPAN as Genealogy::Relationship. To be honest, I’m not sure exactly how useful it will be. The Line of Succession is a rather specialised version of a family tree – because we’re tracing a bloodline, we’re only interested in one parent (which is unlike normal genealogy where we’d be interested in both). It also might be too closely tied to the data model I use on my site – but I have plans to fix that soon.

Currently, because of the requirements of my site, it only goes as far as third cousins (that’s people who share the same great, great grandparents). That’s five generations. But I have an idea to build a site which shows the relationship between any two English or British monarchs back to 1066. I think that’s around forty generations – so I’ll need to expand the coverage somewhat!

But anyway, it’s there and I’d be happy if you tried it and let me know whether it works for you. The documentation should explain all you need to know.

The Line of Succession site doesn’t get much traffic yet – I really need to do more marketing for it. So it’s satisfying to know that some of the code might, at least, be useful outside of the project.

Categories
CPAN

Genealogical Timelines in Perl and SVG

If you ever read my (mostly dead) more general blog, you might know that I’m a bit of an amateur genealogist. I’ve been tracing my family for over twenty-five years and I’ve got some branches of it back to the 1700s (actually, I have one branch back to the late 1600s).

One problem in genealogy is how to present data in a readable and easily-understandable way. Family trees are messy things. Both the roots and the branches can get very tangled. A good way to cut through all of that is to ignore unnecessary branches and just show the ancestors of a given person on the tree.

And that’s what the image at the top of this post shows. In the right-hand side of the image, halfway down, you will see Prince George of Cambridge (ok actually, you’ll see “Princ”, that’s a bug that I need to fix – it works when someone’s lifespan is long enough to fit their name in!) Above and below him (at a quarter and three-quarters of the way down the page) you’ll see his parents. And so on back through time until on the left of the page you’ll see his great, great, grandparents – most of whom were born back in the nineteenth century.

It’s all created with a Perl program, of course. I’ve just uploaded SVG::Timeline::Genealogy to CPAN (it should be there at some point later today) and that can be used to draw these diagrams.

The module is very similar to SVG::Timeline which I wrote about a couple of weeks ago. And that’s completely unsurprising as it’s a sub-class of that module. Interestingly, early drafts of this module pre-date SVG::Timeline, but I recently realised that it should be a sub-class so I spent yesterday re-implementing it (and making more than a few changes to SVG::Timeline as some idiot had made it hard to sub-class!)

There are two ways to use the module. The hard way involves writing your own code:

The easy way involves putting the information in a data file and using the treeline program that is included in the distribution.

The fields in the data are separated by tabs.

The important bit to get right is the “ahnen” attribute. “Ahnen” is short for “Ahnentafel Number” and it’s a concept that is common in genealogy. You take a person in your family tree (say you for example) and give that person a number of 1. Your father then has a number of 2 and your mother is 3. Carry on with that scheme through the generations. You paternal grandparents are 4 and 5, your maternal grandparents are 6 and 7… and so on.

These numbers have a couple of interesting properties. Firstly, if a person has an Ahnentafel Number of $x, then their parents are 2 * $x and 2 * $x + 1. Secondly, with the exception of person 1 (who can obviously be of either sex) all the men have even numbered Ahnentafel Numbers and the women all have odd numbers.

It is therefore these numbers that allow us to convert a flat data file into a tree structure. They tie the records together in the correct order. If you want to know more, I have a module called Genealogy::Ahnentafel which allows you to manipulate these numbers in various ways.

So that’s, SVG::Timeline::Genealogy. Hope you find it useful. Please share any interesting genealogies that you find.