Structure and Roadmap

Principles, and internal structure of, todo list and roadmap for the future. (WPC) is my online identity hub. It's inspired by design principles from various projects including Diaspora, IndieWebCamp, OStatus(+ActivityStreams), which I've boiled down to the following:

  • A person should represent themselves on the web
  • People should be able to publish content to their own website and push it out to other services
  • Pushed copies should link back to the original
  • People should present their activities in a feed of some form so they can be followed

My aim is to satisfy these principles, and then some.

Backend Structure

WPC is a CodeIgniter install with various libraries a few custom helpers (some of which I will be making public in the future). is a PHP application running off a (currently non-public) small modular framework made from the Symfony Components (amongst other things). I am gradually making more and more of its code available on Github.

The base of the application is a subclass of Symfony HttpKernel which provides routing, security (soon to be moved to a listener), module loading and basic cross-cutting dependency injection (logger, config, DB connections and the like). All actual functionality is provided by plugins (listeners, e.g. tagging utilities) and modules (typically routable content types, e.g. Notes, Index, Articles, Mentions, etc.).

At some point in I plan to make the entire thing available to the public, including all my plugins, modules and documentation. It is hard to name something so very modular, but the working title of the entire package is Taproot.


Taproot is not yet strictly RESTful, as it stores authentication information on the server.

It does use HTTP methods as its interface for accessing and modifying content, and implements Content Negotiation (optionally overridden by tacking an extension onto the URL) to serve up different representations of the same content. The exact list of representations differs depending on the content type/module, but amongst the types supported are:

Modules (Content Types)

Currently the following modules are developed and available publically:

  • Index (deals with the homepage)
  • Notes (At the moment just tweets, but with a greater scope)
  • Articles (Longer-form text, with edit histories)
  • Contacts (A listing of people I know)

The following modules are in development:

  • Mentions (A central location for storing Pingbacks and the like)

The following modules are planned but not yet started:

  • Music (to replace WPSM)

Listeners (Plugins)

While Modules provide content type CRUD and URIs, there are many tasks which apply equally to multiple content types, or equally to any request. These are implemented as listeners. The following listeners are implemented and live:

  • REST Request and Response Listeners to deal with various HTTP stuff and conneg
  • Markdown and auto-linking listeners
  • auto-h-carding listener
  • Nominatim listener to add geocoding machine tags
  • Syndication listeners (see below)


I implement POSSE, syndicating plaintext to Twitter on the backend via the TwitterSyndicator, and annotated plaintext posts (Link, name, description, thumbnail) to Facebook on the front end via the Facebook Feed Dialog.

All of my syndication code (including HTML → µblog syntax converter) can be found under the POSSE namespace in my php-helpers repo.

Currently only a single Atom feed is provided. It's a 'normal blog'-type feed containing only t and b type posts. It's generated from the posts table and only contains implied AS Activities.


Content is all stored in one database table…Changed to reflect changes to the backend system

Each module controls it’s own table(s), based off the table for notes, which is considered the bare minimum of fields required. Other tables (e.g. Articles) expand this base set to suit requirements. Similarly, the CI model for each content type is a subclass of a base model that deals purely with the base fields.

The DB schemas and base properties are based upon the spec. I have adopted for content modelling purposes, but am not using the actor/verb/object model as I do not feel it is very useful.

This base field set is as follows:

Discovery and Identity

Currently webfinger for is supported and provides real information.

I gave up on webfinger (TODO: write article on why) and now provide contact information via h-card on my home page. I am also planning to add WebID through embedded FOAF if possible.


Actually more of a vague Todo list with some timeframes. In order of priority.

Next Steps

  • Get Mentions module live and working
  • Add webmention to Mentions module
  • Add other module listeners to Mentions module

In the Near Future

  • Make Taproot open source