1. I just faked having a task queue for note posting tasks using Symfony HttpKernel::terminate() and it was the easiest thing ever.

    Instances or subclasses of HttpKernel have a terminate($request, $response) method which, if called in the front controller after $response->send(); triggers a kernel.terminate event on the app’s event dispatcher. Listeners attached to this event carry out their work after the content has been sent to the client, making it the perfect place to put time-consuming things like POSSE and webmention sending.

    Once you’ve created your new content and it’s ready to be sent to the client, create a new closure which carries out all the the time consuming stuff and attach it as a listener to your event dispatcher, like this:

    $dispatcher->addListener('kernel.terminate', function() use ($note) {
        $note = sendPosse($note);

    Then, provided you’re calling $kernel->terminate($req, $res); in index.php, your callback will get executed after the response has been sent to the client.

    If you’re not using HttpKernel and HttpFoundation, the exact same behaviour can of course be carried out in pure PHP — just let the client know you’ve finished sending content and execute code after that. Check out these resources to learn more about how to do this:

    Further ideas: if the time consuming tasks alter the content which will be shown in any way, set a header or something to let the client side know that async stuff is happening. It could then re-fetch the content after a few seconds and update it.

    Sure, this isn’t as elegant as a message queue. But as I showed, it’s super easy and portable, requiring the addition of three or four lines of code.

  2. So I got in-stream reply contexts showing — perhaps summaries of comments next? I like Facebook’s approach of showing the last 4, a total count and a “show me more” button, which could be implemented simply as a link to the note page initially.

    Reply context stream example: http://waterpigs.co.uk/notes?tagged=reply

    Still TODO: make the ↪ a link to the in-replied-to page, add the datetime to the title for that link, remove the in-reply-to info from the bottom of in-stream notes as it’s noise now

  3. UI : service which finds the average number of characters/words/lines in a note and automatically makes the “new note” box that size. Potential extension: Make it one line bigger/smaller to encourage longer/shorter writing.

  4. Sandeep Shetty: Barnaby Walters So you have 3 types of tags (from an interface perspective): note body, meta data (visible) & machine tags (invisible)?

    sandeepshetty yep, this is certainly something I need to document on the wiki.

    In fact most of the machine tags were a hack to add schemaless data to my MySQL-managed schema, but as I move to flat files + ad hoc indexes I might migrate some of my machine tags to “real” data — it’s not like they’re doing much good where they are at the moment.

    The main benefit is easy editing — I just use my tag editing UI instead of building another UI for each different bit of data.

  5. This evening’s project: catching up on a bit of dev. :

    • remove lines — whitespace FTW
    • get rid of crappy AJAX+backbone for calling new note UI into notes page, replace it with iframe+postMessage
  6. New CRUD fetcher/saver design coming on well. Decided on per-semantic-indexing, with abstract indexes and APIs so I never have to think about the SQL under the logic (which I do with ORMs like Doctrine).

    Implementing the whole lot using traits, too — mixins FTW.

  7. This morning’s update: ditched the crappy old DRY-violating tags module and replaced it with a super lightweight one. Soon I’ll add the ability to store tag descriptions, synonyms/related tags as well as dynamically pull content in from the URLs it lists so the tag pages aren’t quite as boring.

  8. I’m noticing a pattern emerge whilst writing the simplified auth code: multiple event listeners which don’t know about each other working on the same object, augmenting and changing it.

    E.G. RememberMeListener looks for an encrypted cookie with a URL (my user ID of choice) in — if it finds one it makes an ActivityStream person object and puts it in request.attributes.user.

    Then, in the same event chain but at a lower priority level, the Contacts module looks in request.attributes.user for a URL. It looks up the URL in my people DB and, if there is anyone, augments request.attributes.user with all the extra info (full name, roles, photo URL, rel value, etc.)

    Then, another listener could run, looking for request.attributes.user with only URL — and look the URL up on identengine.com, caching the response.

    Other example is @-name autolinking, working on a similar basis of: basic transformation (raw data => common data format), then progressive augmentation adding URLs, names and rel values.

    I think this a very powerful and flexible pattern and something I will make a founding principle of Taproot.

  9. Finally decided that symfony Security component is way too complicated for my little , so ditching it — but I’ve learnt a lot from digging through it and my further efforts will try to provide some of the amazing flexibility it gives whilst being more performant and easier to understand #php

  10. Anna Debenham in your style guide researches, have you come across any great open source project styleguides? I’m looking into making myself more design-accountable for a project I’m releasing soon.

  11. I got tired of WPSM looking and working the way it does (I wrote it when I was 13 and learning PHP), so I’ve taken the data and started building the Music module. Live here. Major but already looking and working better than the old one!