2018 Gulaschprogrammiernacht and organizing sprints for XMPP

| categories: xmpp, foss, omemo, converse.js, plone

Recently I attended the Gulaschprogrammiernacht for the first time.

It's a hacker/maker event in the Zentrum für Kunst und Medien (Centre for Arts and Media) in Karlsruhe, Germany.

AFAIK it's organized by the local chapter of the infamous Chaos Computer Club.

I heard about it from Daniel Gultsch on Twitter. It sounded like fun, so I decided to attend and spend the time adding OMEMO support to Converse.

Guus der Kinderen and I intended to organize an XMPP sprint for that weekend in Düsseldorf, but we were cutting it a bit fine with the organization, so I hoped that we could just shift the whole sprint to GPN.

Unfortunately Guus couldn't attend, but Daniel and Maxime Buquet (pep) did and I spent most of the event hanging out with them and working on XMPP-related stuff. The developers behind the Dino XMPP client also attended and hung out with us for a while and there was someone working on writing an XMPP connector for Empathy in C++.

XMPP hackers at Gulaschprogrammiernacht

Maxime worked on adding OMEMO support, to Poezio, and Daniel provided us with know-how and moral support. Daniel worked mainly on the Conversations Push Proxy.

We had some discussions around the value of holding regular sprints and I told them about my experience with sprints in the Plone community.

The Plone community regulary organizes sprints and they've been invaluable in getting difficult work done that no single company could or would sponsor internally. To me it's a beautiful example of what's been termed Commons-based peer production.

The non-profit Plone foundation provides funding and an official seal of approval to these sprints, and usually a sprint has a particular focus (such as adding Python3 support). Sprints can range from 3 people to 30 or more.

One difference between the Plone and XMPP communities, is that Plone is a single open source product on which multiple companies and developers build their businesses, whereas XMPP is a standardized protocol upon which multiple companies and developers create multiple products, some open source and some closed source.

In both cases however there is a single commons which community members have an incentive to maintain and improve as they build their businesses around it.

Another difference is between the Plone Foundation and the XMPP Standards Foundation. The XSF, for better or worse, interprets its role and function fairly strictly as being a standards organisation primarily focused on standardising extensions to XMPP, and less on community building or supporting software development.

Despite these differences, I still consider sprints a great way to foster community and to improve the extent and quality of XMPP-related software and documentation.

There is an interesting dynamic between cooperation and competition in both the Plone and XMPP communities. Participants compete with one another but they also have the shared goal of maintaining and growing a healthy software ecosystem.

Maxime was particularly excited by our discussion and very quickly put word into action by planning and announcing an XMPP sprint in Cambridge, UK in August.

There's still time to vote on the date of the sprint and to suggest topics.

Hopefully this will be first of many more sprints and communit events.

Unmanned laptops at the Gulaschprogrammiernacht

Sprint Report: Merging Mockup and Patternslib

| categories: mockup, javascript, patternslib, austria, sprint, foss, plone

Alpine City Sprint, 21 to 26 January 2015

This is a report on what I did at the Plone Alpine City Sprint organized by Jens Klein and Christina Baumgartner in Innsbruck between 21 and 26 January 2015.

Firstly, I want to thank to them for organizing and hosting a great sprint and for being such friendly and generous hosts.

My goal for this sprint was to work on merging the Patternslib and Mockup Javascript frameworks and I'm happy to report that very good progress was made.

Long story short, the merge was successful and it's now possible to use patterns written for either project within a single framework.

Before I expand on how this was achieved during this sprint, I'll first provide some necessary background information to place things into context and to explain why this work was necessary.

What is Patternslib?

Patternslib brings webdesign and development together.

Patternslib's goal is to allow website designers to build rich interactive prototypes without having to write any Javascript. Instead the designer simply writes normal HTML and then adds dynamism and interactivity by adding special HTML classes and data-attributes to selected elements.

For example, here is a Pattern which injects a list of recent blog posts into a element in this page:

Click here to show recent blog posts

The declarative markup for this pattern looks as follows:

<section id="alpine-blog-injected">
    <a href="#portlet-recent-blogs"
       data-pat-inject="target: #alpine-blog-injected">

        Click here to show recent blog posts

The dynamic behavior comes from the fact that I have the Patternslib Javascript library loaded in this page.

On pageload, Patternslib scans the DOM looking for elements which declare any of the already registered patterns. If it finds such an element, it invokes a Javacript module associated with that pattern.

In the above example, the <a> element declares that it wants the Inject pattern applied to it, by virtue of it having the pat-inject HTML class.

Patterns are configured with specific HTML5 data properties. In the example above, it is the data-pat-inject property which specifies that the target for injection is the #alpine-blog-injected element in the current page and the content being injected is specified by the href attribute of the <a> element. In this case, the href points to an anchor inside the current page, but it might just as well be a link to another page which will then get injected via Ajax.

More information on how to configure pat-inject can be found on the patternslib website.

Each pattern has a corresponding Javascript module which is often just a wrapper around an existing Javascript library (such as Parsley, Select2 or Pickadate) that properly defines the configuration options for the pattern and properly invokes or applies the 3rd party library.

So, in order to do all this, Patternslib can be broken down into the folowing components:

  • A registry which lists all the available patterns.
  • A scanner which scans the DOM to identify declared patterns.
  • A parser which parses matched DOM elements for configuration settings.
  • The individual Javascript modules which implement the different patterns.

What is Mockup?

Mockup, declarative interaction patterns for Plone..

Mockup was inspired by, and originally based upon, Patternslib and was meant to bring the power of declarative interaction patterns to Plone.

When Mockup started, Patternslib was undergoing significant refactoring and development and it was decided that Mockup should fork and go its own way.

What this means is that the 4 different components mentioned above, were all changed and due to these changes the Mockup project diverged from Patternslib and started developing in a similar but different direction.

So what's the problem?

While Mockup was being developed for the upcoming Plone 5 release, we at Syslab continued using and improving Patternslib in our projects.

Syslab built an intranet for the Star Alliance, which was based on a prototype design by Cornelis Kolbach, the conceptual creator of Patternslib. This design became the inspiration and blueprint for the Plone Intranet Consortium (PIC), which consists of 12 companies working together in a consortium to build an intranet solution on top of Plone.

So, the PIC are building a product using Patternslib, while Plone 5 itself is being built with Mockup, an incompatible fork of Patternslib.

This was clearly a bad situation because we now had:

  • Two incompatible Javascript frameworks being used with Plone.

    Not only were the two frameworks incompatible in the sense that patterns written for the one don't work on the other, but they could also not be used on the same page since the two implementations would compete with one another in invoking Javascript to act upon the same DOM elements.

  • Duplication of effort

    The same or similar patterns were being developed for both frameworks, and when one framework had a pattern which the other wanted, it could only be used after being modified such that it couldn't be used in the original framework anymore.

  • A splitting of the available workforce.

    Developers were either working on Mockup or Patternslib, but almost never on both, which meant that the expertise and experience of developers wasn't being shared between the two projects.

How could this be fixed?

To solve the 3 main problems mentioned above, we needed to merge the common elements of Mockup (specifically the registry, scanner and parser) back into Patternslib.

This will allow developers from both projects to work on the same codebase and enable us to use patterns from both projects together.

At the Alpine City Sprint in Innsbruck, I worked on achieving these goals.

Changes brought in by Mockup

After the fork, Mockup introduced various changes and features which set it apart from Patternslib.

In order to merge Mockup back into Patternslib, I studied these changes and with the help of others came up with strategies on what needed to be done.

Here are some differences and what was done about them:

Mockup allows patterns to also be configured via JSON, whereas Patternslib used a keyword:argument; format

A week before the sprint I added JSON parsing ability to the Patternslib parser, thereby resolving this difference.

Leaves first parsing versus root first parsing

Mockup parses the DOM from the outside in ("root first"), while Patternslib parses the DOM from the inside out ("leaves first").

According to Rok Garbas, the creator of Mockup, the outside-in parsing was done because it reduced complexity in the scanner and the individual patterns.

Wichert Akkerman who originally wrote the Patternslib scanner however provided IMO a very good reason why he chose "leaves first" DOM scanning:

If I remember correctly there are several patterns that rely on any changes in child nodes to have already been made.This is true for several reasons: 1) a pattern may want to attach event handlers to child nodes, which will break of those child nodes are later replaced, and 2) child nodes changing size might impact any measurements made earlier.

Indeed, while refactoring the Mockup code during the merge, I ran into just such a case where a pattern couldn't yet be initialized because patterns inside it weren't yet initialized. By turning around the order of DOM scanning, this problem was resolved and the code in that pattern could be simplified.

So, now after the merge, scanning is "leaves-first" for Mockup patterns as well.

Mockup patterns are extended from a Base object, very similar to how Backbone does it

Patternslib patterns on the other hand are simple Javascript objects without constructors.

The patternslib patterns are conceptually very simple and more explicit.

However, what I like about the Mockup approach is that you have a separate instance with its own private closure for each DOM element for which it is invoked.

After merging, we now effectively have two different methods for writing patterns for Patternslib. The original "vanilla" way, and the Mockup way.

The Mockup parser was completely rewritten

The Mockup parser looks nothing like the Patternslib one and also supports one less configuration syntax (the so-called "shorthand" notation).

This was one piece of code which could not be merged within the time available at the Alpine City Sprint.

So currently we still have two different argument parsers. The Patternslib parser needs to be configured much more expicitly, while the Mockup one is more implicit and makes more assumptions.

Merging these two parsers will probably have to be done at some future sprint.

There are some other more minor differences, such as that every Mockup pattern is automatically registered as a jQuery plugin, but merging these was comparatively easier and I'll won't go into further detail on them.

What I did during the Alpine Sprint

So, in summary:

I refactored the Patternslib registry, scanner and some core utils to let them handle Mockup patterns as well. Luckily the eventual patch for this was quite small and readable.

I changed the Mockup Base pattern so that patterns derived from it now rely on the registry and scanner from Patternslib.

I fixed lots of tests and also wrote some new tests.

This whole task would have been much more difficult and error prone if either Patternslib or Mockup had fewer tests. The Mockup team deserves praise for taking testing very seriously and this allowed me to refactor and merge with much more confidence.

What else is there to still be done?

Being able to use patterns from both projects and merging most of the forked code was a big win, but there are still various things that need to be done to make the merge complete and viable.

I've ranked them from what I think is most important to least important.

1. Update the documentation

Currently documentation is scattered and silo'd in various places (the Patternslib website, the Plone Intranet developer docs and the Mockup developer docs).

The Mockup docs are now out of date ater this merge and need to be brought up to date on these recent changes.

The Patternslib docs are less of a problem because they don't have to deal with Mockup (which can now be seen as an enhancement suite for it), but they can definitely still be improved upon, specifically with an eye on Mockup developers who will start relying on them.

The Plone Intranet consortium also has a useful walkthrough explaining how to create a Patternslib pattern from scratch..

2. Devise a way to also use the Patternslib parser for Mockup patterns

As mentioned, the Mockup patterns still use their own argument parser.

Letting them use the Patternslib's parser will either require extending the Mockup Base pattern to configure the Patternslib parser on a pattern's behalf or instead doing it explicitly in each of the individual patterns.

3. Decide on coding and configuration standards

Unfortunately the coding standards between the two projects differ significantly.

  • The Mockup developers use camelCase as declarative argument names while Patternslib uses dash-separated names.
  • The Mockup source code uses 2 spaces for indentation, Patternslib uses 4 spaces.

4. Remove unnecessary, duplicated patterns

Both projects have patterns for modals, injection, select2 and file upload. These should be merged to get rid of duplication.

5. Move generic patterns (e.g. pat-pickadate, pat-moment etc.) out of Mockup

Mockup has some generic patterns which might also be useful as Patternslib core patterns, in which case they should ideally be moved there.


The sprint was a big success and I'm very happy that all the work has already been merged into the master branches of the matternslib, mockup and mockup-core repositories.

Core code from Mockup is now succesfully merged back into Patternslib and we can use patterns from both projects in the same site.

I had a lot of fun working with talented and motivated software developers and had a lot of opportunities to improve my German.

Thanks again Jens and Christine for organising a great sprint and I look forward to doing such a sprint again!

Innsbruck, the alpine city

Antifragile Software Ecosystems

| categories: open-source, bitcoin, cryptocurrencies, antifragile, foss, plone

Antifragile, by  Nassim Nicholas Taleb

I recently finished reading the book Antifragile, by Nassim N. Taleb, in which he discusses the idea of "antifragility", the property that allows something to ultimately improve and grow stronger when subjected to volatility and stressors.

I highly recommend Taleb's books, they have a tendency to throw conventional wisdom on its head and make you think differently of our world, in which randomness, volatility, opacity and non-linearity takes precedence.

As a software developer, I kept wondering how the insights gained from this book apply to the world of software. Especially given the fact that software is very fragile. The answer lies in the communities or ecosystems that form around software. Many of them are fragile, but some are antifragile.

If you're also a software developer, you'll want to be in the second category.

What is antifragile?

Taleb splits everything into three categories, fragile, robust and antifragile.

The initial chapters explain in detail why robust is not the opposite of fragile, and why the neologism "antifragile" is needed to describe the opposite of fragility.

Medusa is antifragile

Medusa, courtesy of

If fragile systems are sensitive to stress and volatility, and need to be kept "safe" from harm, lest they suffer or break down, then antifragile systems are ones which ultimately benefit from randomness and stress.

In Greek mythological terms, one can think of Medusa, which grows another two snakes on her head for each one that's cut off. That's antifragile.

So fragile and antifragile can be considered opposites, e.g. positive and negative, while robust is simply neutral. It suffers little harm from volatility but also gets little to no benefit.

Evolution is antifragile

Ostriches have evolved from dinosaurs

Ostriches have evolved from dinosaurs

Some good examples of antifragile systems are found in nature and ecology. For evolution to work (i.e. for a species to adapt to its randomly changing environments), random mutations are required between individuals in that species.

A random mutation in a member of a species holds the possibility of making that member better adapted to its environment. By virtue of it being better adapted, that member will on average live longer and produce more offspring, which will be likely to have inherited the same advantageous mutation. The process continues, propagating the beneficial mutation throughout the species, in so doing, the species evolves and becomes more fit and adapted to its environment.

Nature is able to discard less well-adapted specimens and keep the better-adapted ones. An ability which Taleb refers to as optionality. It has the option to keep the "good" specimens and discard the "bad" ones.

The opposite of an option is an obligation. Nature is under no obligation to keep the poorly adapted members of a species, and if it were, it wouldn't be antifragile anymore.

So, although individual members within a collection (like a species) are fragile to certain stressors, the overall effect on the collective level is antifragility.

Software is fragile


Image courtesy of

Unmaintained and unsupported software degrades when exposed to the stressors of time and use.

The more software you install on your computer, the higher the chance that your machine will eventually become slow and prone to crashes and bugs.

The word "bitrot" is sometimes used to refer to the gradual degradation of a software program over time and is related to the idea of entropy.

Large software systems that are composed of multiple interacting subsystems, are especially vulnerable to bitrot, due to the fact that a given subsystem cannot anticipate all the bugs or changes that might be introduced to other subsystems over time.

The more a piece of software is used, the more variance there is in how it's being used. For example in the order, type and amount of inputs it receives as well as in the hardware its being installed on.

Lets assume that a very specific interaction with the software, which the programmer never foresaw, will cause the software program to crash and become permanently degraded.

Given enough time, someone will eventually interact with the software in this specific way, thereby permanently degrading the functionality of the software program (for example due to data corruption).

Are software businesses also fragile?

Businesses are generally fragile. They require a certain level of stability to operate and are sensitive to volatility (like regulatory changes, lawsuites or changing consumer tastes).

An antifragile software business however would be one that does well whenever some metric related to the software experiences increased volatility.


  • something that's antifragile wants more volatility, because the benefit from increased volatility outweighs the harm.
  • Similarly, you are fragile to a specific source of volatility when the potential downsides outweigh any upsides.

So, let's take "number of security flaws" as the metric.

The fortunes of a company that does security audits would improve every time there is a publicised security flaw in the software itself, or the software is compromized by an attacker.

They would therefore be antifragile to the "bad news" of exposed security flaws.

Perhaps with an upper bound. If there are too many security flaws, the reputation of the software itself might suffer irrevocably, and with it that of the company.

This illustrates the point that antifragile systems can handle volatility and stressors up to a point. Given enough volatility and stress, the entire planet can die out.

Conversely, a company whose business model depends on the software being stable, and on attacks not happening, would be fragile to the software having security flaws.

A community of fragile members can itself be antifragile

So, as mentioned earlier, an ecosystem can be antifragile, even if the individual units that make up that system are fragile.

It is however important that the units themselves are relatively redundant and that the fragility is not systemic inside the entire ecosystem.

To put it in more technical terms, units inside the system need to be "hot-swappable" and their interactions with one another should be "loosely coupled". This is necessary to prevent complex and hard dependencies within the system, which in the case of breakdown of one unit would cause cascading failures and damage rippling through the entire system.

Antifragile software ecosystems

So, we now get to the crux of this article.

Software itself might be fragile, as well as businesses built around that software, but the larger ecosystem that encompasses the software and businesses, can be antifragile.

A software ecosystem that is distributed over many small and relatively self-contained businesses, each providing services around a common shared resource of Free and Open Source software (FOSS), coupled with a low barrier to entry for new businesses, is antifragile.

Conversely, a software ecosystem that is centralized around one large provider (often playing the role of gatekeeper or rent-seeker), artificially restricting access to the software, attempting to stifle any competition with its own services, is fragile and sensitive to large negative Black Swans (difficult to predict but extreme events).

I'll elaborate on why this is by identifying the requirements for an antifragile software ecosystem.

Requirements for an antifragile software ecosystem

  • Distributization

    Centralized systems provide a large single point of failure that can cause the collapse of the entire ecosystem. Distributed systems can take shocks much better and are able to route around failures and breakdowns.

  • Redundancy

    When one unit breaks down, others need to be able to pick up the slack. For that to happen, they need to collectively be able to perform the functions of the defunct one. For example, if a software community relied solely on one unit in that community for supplying hosting services, then the entire community would break down if that one unit collapsed.

  • Optionality

    The individual members in an antifragile ecosystem need to be able to modify and adapt.

    For a software ecosystem, this means the ability to modify and adapt the software itself. Only through being able to modify the software in a distributed, bottom-up way, can the ecosystem withstand stressors in an antifragile way, by making use of optionality.

    Optionality refers to having the option to take (or do) something or not. As mentioned earlier, it's how evolution is able to "design" extremely sophisticated organisms, by keeping the "good" ones and discarding the bad ones, and it applies to software ecosystems as well.

    The Plone logo

    For example, in the Plone CMS (content management sytem) community, add-on modules are developed in a redundant and distributed way. There are multiple blog add-ons, commenting add-ons, newsletter add-ons and so on. Through a process of optionality and selection, the good ones rise to the top while the weaker ones are eventually discarded.

Why the requirement for Free and Open Source software?

FOSS facilitates all three of the above requirements. Communities and ecosystems that develop around FOSS are by nature distributed, redundant and provide optionality.

Distributization and redundancy come from the lack of gatekeepers, "rights-holders" and rent-seekers. Anyone can start using FOSS and selling services around it from anywhere in the world. No license, special qualification or permission required.

Optionality comes from the fact that anyone can do trial-and-error tinkering with the software and keep their improvements. They can also choose the best or most appropriate changes and modifications made by other people.

Without optionality a software ecosystem will not be antifragile, and without FOSS, a software ecosystem will not have optionality.

Additionally, software that is Free (as in Libre) displays qualities much more akin to information than non-Free software, which due to it's source opacity functions more as a black-box application. As Taleb explains in his book, information is antifragile. You can't easily kill it, and by trying to suppress it you have to acknowledge its existence and refer to it.

Lastly, the lower barrier to entry fosters competition.

In order to differentiate themselves, individual developers or businesses need to compete on quality and/or price. It's survival of the fittest, as opposed to the rent-seeking, vendor lock-in and monopoly so often seen in proprietary software ecosystems.


In the book, Taleb alludes to Silicon Valley's "fail fast, be foolish" model as being antifragile as opposed to a more centralized environment with inherent systemic risks, such as the New York banking system (his example).

Silicon Valley might provide an antifragile method for producing businesses, but the software produced by these businesses don't necessarily result in antifragile ecosystems.

Look at the software businesses that have arisen out of Sillicon Valley. Facebook and Google are both large and centralized. Increasing centralization and size results in increasing fragility of the web.

If Google's servers were to go down (or be compromized or blocked by a government), a very large part of the web would cease to function. The chance of Google's servers going down are of course very small, it's a negative Black Swan event. Something which society nevertheless needs to shield itself against.

Antifragile against what?

Having mapped out the requirements for an antifragile software ecosystem, it makes sense to consider the kinds of stressors such an ecosystem will be antifragile against.

This section is a bit more speculative, mostly because we cannot know the exact nature and extend of the stressors a system will be exposed to. Luckily we don't need to know the stressors to be able to make use of antifragility.

It's also important to know that stressors are information. In fact, stressors often appear through the disclosure of "negative" information. When negative information is revealed, it can cause shocks to software ecosystems. The fragile ones will suffer and might even break down, while the antifragile ones will ultimately benefit.

Here are some examples of stressors a software ecosystem can be antifragile against:

  • Malicious Hacking (Cracking)

    FOSS is more resistant to cracking than closed source software. Additionally, distributed systems are much harder to target and infect.

    Increased awareness and fear of cracking, makes FOSS, its ecosystems and communities more attractive to software users (individuals, companies, governments etc.) and therefore antifragile to the "bad" news.

Surveillance cameras

Image courtesy of

  • Surveillance

    A big part of surveillance is actually also cracking, so the same rules apply here.

    It's much more difficult for eavesdroppers to embed backdoors in software with freely available and visible source code.

    Encryption software is especially vulnerable and can't be trusted if its closed source.

    News of security flaws spread quickly throughout the community and fixes are generally pushed out almost immediately. You won't easily have the problem of a FOSS community member privately disclosing security flaws to an intelligence agency (so they might use if for surveillance) while hiding it from the users.

    Again as surveillance and privacy fears increase, FOSS becomes more attractive, making the communities and ecosystems around it more antifragile.

  • Negative economic circumstances

    Many governments are experiencing budgetary constraints and employing austerity. Governments are able to make significant savings when they switch to FOSS ecosytems. Not mentioning the increased autonomy and control of their software and resulting digital formats.

There are of course many more stressors that might ultimately benefit distributed FOSS ecosystems, for example censorship and economic boicot, but for the sake of brevity I won't go into detail for each one.


I've mapped out the requirements for a software ecosystem (and community) to be antifragile, and have alluded to Plone as an example of such an ecosystem.

The Bitcoin logo

The Plone software, like other Free software (Drupal, Wordpress, Apache, Firefox, Libre Office, GNU/Linux etc.), is a technological commons. It belongs to humanity as a whole.

Everything I wrote also applies to the ecosystems around cryptocurrencies, like Bitcoin, Litecoin and Anoncoin.

There are usually vibrant communities of developers, packagers, integrators, evangelists and users around these pieces of Free software, and they usually conform to the requirements mentioned above. Members are distributed all over the world, there is redundancy in development skills and support offerings and the source code is Free (as in beer and in speech).

Thanks for reading and please leave a comment if you have anything to add, I'd be happy to discuss the finer details perhaps missed in this article.

Converse.js: XMPP instant messaging with Javascript

| categories: backbone.js, instant messaging, xmpp, javascript, strophe.js, plone, converse.js

It is now possible to use converse.js, the Javascript from, in a standalone way, to communicate with any public Jabber account.

Lately I've been spending time refactoring converse.js the Javascript library used by the instant messaging add-on for the Plone CMS. My goal is to make it usable on it's own, requiring nothing else except an XMPP server to communicate with.

This would enable any website owner to add instant messaging functionality to their website, and due to the federated nature of XMPP, users could chat to any other public XMPP account (once they have been accepted as a contact).

One thing that previously prevented you from using converse.js on its own, was the fact that it made XHR calls to the Plone backend to fetch user data. To fix this, I added vCard support, to converse.js but also to Plone by adding it to collective.xmpp.core.

Last week I reached a significant milestone on the path to this goal, and I'd like to take a moment and share with you.

It is now possible to use converse.js (in a static HTML page) to communicate with Jabber accounts on any public server.

In the demo below, I illustrate this by chatting to a Google user and to a user. In the converse.js page, I'm authenticated with a account and I also use their connection manager to connect to their XMPP server. If you're doing XMPP via HTTP (i.e in the browser), you'll need a connection manager as a bridge to your intended XMPP server. Thanks a lot to the Jappix guys for making their connection manager public!

Note: For detailed fullscreen, make sure that video quality is set to HD, by clicking the gear icon on the video player.


UPDATE: Since this blog post, a production ready version of converse.js has been released. So the following is no longer applicable.

I'm sorry to say that converse.js is not yet 100% ready for primetime as a standalone JS app. There are a few more hurdles (and nice-to-haves) to overcome before we'll achieve this goal:

  • Searching and adding new users still does XHR calls to Plone and should instead query the XMPP server.
  • Service discovery support (e.g so that multi-user chat is only available for servers that support it).
  • Some kind of "Keep me logged in" support when users log in manually.
  • I'm not proud of the CSS and it could probably be improved upon quite a bit.
  • The Jasmine tests are out of date and not passing, also more tests are required.

If you are interested in the project, please contribute by forking the code on github.

Thanks a lot to Alec Ghica and David Ichim from Eau de Web who've made various improvements to both and converse.js over the past months.

Report on the Beer and Wine Sprint in Cape Town

| categories: south-africa, plone, sprint

The Beer and Wine sprint wrapped up on Sunday and it's now a good time to report on what was South Africa's first ever core Plone sprint. This was a joint sprint between Cape Town and Munich, which in hindsight, was a very good idea. The two groups of sprinters had daily meetings via Google hangouts, and the structure and support we received from Munich helped a lot. Connecting with the sprinters on another continent brought home the point that we are a global community and that no core Plone work is done in isolation. The daily hangouts also motivated us to get cracking so that we could have something to report on!


South Africa is geographically isolated from the places where most Plone development takes place (notably Europe and North America) , which results in the local Plone community not getting as much exposure to sprints and community events as would have been possible otherwise. The goal of this sprint was to help change that, and to provide an opportunity for us to contribute back to the Plone community from which we've received so much.

Most of the people who attended the sprint were first-timers, and it was a joy to see the enthusiasm with which people started working. Eric Steele and David Glick flew down to join us here at the tip of Africa, and provided much needed experience and support.


About 14 people met at sprint venue on Thursday morning and after introductions and a quick hello to the Europeans via the wormhole, we formed groups and started sprinting.


Mike Metcalfe and Campbell Mckellar-Bassset (rockfruit) started working on porting CMFPlone tests from Products.PloneTestCase to They kept at it with dogged determination for the next four days of the sprint and made good progress. Izak Burger and Jurgen Blignaut tackled some TinyMCE bugs, while Rudi Ackhurst, Witek, Johan Beyers and myself started working on Plip #13260. We did this via Dojo sessions, which we held for most of the sprint. Other people did tutorials and proofreading of documentation.

It appears as if the sprinting bug has bitten at least some of the people who attended, and there's already been talk of doing this again some time. I personally had an amazing experience and learned a lot while organising this event.


To the bittereinders who sprinted every single day (Thursday to Sunday), thanks for your energy and support! This would have not been possible without you. We laid a solid foundation for future core Plone contributions from our local group.

Lastly, thanks a million to everyone involved in making this sprint a reality, Eric, David and all the people who attended, our sponsors the Praekelt and Plone Foundations, the guys in Munich and all those who helped with support and advice. And thanks to Liz Leddy who planted the initial seed in my head that this was not only possible, but a actually great idea!

P.S Credit for 3 of the photos goes to David Glick


Next Page »