WebCamp Ljubljana 2017: Lessons learned

This years WebCamp was massive. 500+ attendees, 38+ speakers, 36 sessions, 4 tracks, Internet of Things corner, VR room, sponsors booths, alternate reality games and kids corner. Core team of 10 and additional 30 people volunteered on the day of the event. Event itself was in planning since June 2016 with most of the work done in the last 6 months.

What follows are some of my general notes about running an event of such size and complexity. First “BarCamp” event we did in Slovenia was in 2009 and Eventbrite tells me that this was 8th WebCamp event.

On Size

Last year, we stopped at 300 attendees. This means that this year, we almost doubled in size. The amazing thing with having a faculty as a hosting institution is that it’s designed for such amount of people. The venue itself can probably take another 200 attendees.

Having said that, the feeling of event was different for me. Maybe we broke through the magical number of attendees, where event stops being an extended family and turns into a bigger conference.

From organisational perspective, there is not much difference between organising event for 300 people, vs. 500. It gets a bit riskier with a bigger budget and there’s a more communication required inside each sub-team. With current setup, it should be possible to scale this type of festival to 1000+ attendees.

But since we’re not an extended family anymore, communication with attendees matters a lot more. One of the things that we learned is that people don’t read newsletters/emails. They also ignore almost all of social media. So the things that used to be given, now need to be spelled very clearly on the page of event itself (we’ll probably learn in 2018 edition, that people also don’t read websites).

On having a Modern Event

I’m very spoiled by tech events I attend. The organisers always make sure that different voices from community are represented, are giving consideration to gender identity and make sure that everyone has a chance to fully participate in a healthy way. I always fail to appreciate what a massive undertaking that is.

It’s not hard to do something on a large scale. Lets say, order two vans of pizza boxes and sugar pastries. It becomes a problem when you decided that pizza is not enough and that you also want healthy options. So now instead of having to talk to two vendors, you’re talking to four. This has ripples through out the system – planning overhead, time for person doing logistics, two more invoices to pay, etc. This means that anything that we added to the system, compared to last year, increased complexity of whole operation.

But it turns out, that it matters to people. One example was kids corner that we added relatively late. We got 30 parents that indicated interest of bringing their kids and about 10 actually showed up with them in the morning. Kids had a blast and by the feedback from parents, grownups also had a good time.

Besides increasing complexity, it also has consequence for timelines. When I still had hopes that people will show up and do a “BarCamp”, we basically called people a week before the event and let them know that they should come and that they’ll be speaking. It worked mostly ok.

But above example with kids has effect on timelines.  Since we need to know how many kids to expect and what are their ages. There are different considerations, if there are 5 or 15. To have this number, we need attendees to have tickets, and then we need to survey them. It would be great to have 2 weeks to do this. So that pushes tickets 2 weeks back, and with it everything else (speaker selection, event promotion, etc.). The more we try to make it a friendly event, the bigger operation becomes and farther out we have to schedule things.

On Budget and Tickets

People actually laugh at me when I tell them we were doing WebCamps on about 2,500 EUR of complete budget. This year with all the improvements and bigger size it will be about 6,000 EUR of total cost. WebCamp itself is an volunteer operation.

But the change from recent years is that we actually raised a bit more money that we spent. This means that for the first time in recent WebCamps, I didn’t have to do creative accounting to budget with hidden funds coming from my personal money. A first step to making this potentially a sustainable separate organisation and that I won’t have to front all the money for 2018 edition.

I still have no idea what to do about tickets. I’m humbled that 50 people and organisations actually supported event with 60 EUR per ticket. It also introduced a lot of additional paper work and accounting. What we didn’t figure out yet – what’s the story behind supporter tickets. Do we need to give them anything extra in return, or is warm and fuzzy feeling enough?

We also have a problem that there is more demand than we can realistically fulfill. Web is growing and it would be great to have at least one more Web conference in Slovenia.

On Future

WebCamp has been bigger than myself for a few years now. There’s still too much of it that it’s stuck just in my head and in processes that are internal to my company that I lend so that we have an entity to do the event.

Given the fact that current team already excitedly talks about 2018 event, there will most probably be some kind of event. Of what size and focus, I don’t know. It’s not (just) up to me anymore and that’s a good thing.

Co-Authors Plus WordPress JSON REST API

I was trying to figure out if someone already wrote an REST API endpoint for WordPress Co-Authors plugin. There is wp-api-co-author-plus-endpoints, but it seems that it is focused on guest authors. For my project I needed to include information about co-author users. It turns out it’s very simple to extend existing REST API endpoints.

Here’s a full snippet:


if ( function_exists('get_coauthors') ) {
    add_action( 'rest_api_init', 'custom_register_coauthors' );
    function custom_register_coauthors() {
        register_rest_field( 'post',
                'get_callback'    => 'custom_get_coauthors',
                'update_callback' => null,
                'schema'          => null,

    function custom_get_coauthors( $object, $field_name, $request ) {
        $coauthors = get_coauthors($object['id']);

        $authors = array();
        foreach ($coauthors as $author) {
            $authors[] = array(
                'display_name' => $author->display_name,
                'user_nicename' => $author->user_nicename

        return $authors;

This allows you to query and get coauthors key back in response.

What I learned by becoming a Pokémon trainer for a week

I have just survived a week of the latest cultural phenomenon – Pokémon Go. It started innocently enough – with a US iTunes account and a couple of free hours on a Monday evening. Since I wanted to meet a few more players, I decided to create an event for the following Friday. Something simple – let’s meet at the Congress Square in Ljubljana to mingle. It exploded almost immediately. On the first day, 300 people indicated on Facebook that they would come. By the end of the week, this number rose to 750 with 2000+ interested.

Lesson 1: Facebook is still a great viral machine

Organising events is a lot like a horror movie. You never go alone into the woods. In this case Alja Isakovic co-hosted the event and provided the much-needed sanity check. As a consequence, we had a Facebook Event that looked official (correct style of announcement, good graphics, sane venue and time). But most importantly, it was about something that everyone was hearing about, but was still hard to get in Slovenia. With the basics in place, we just had to share it to our personal Facebook networks. This exposed the event to enough people that we got noticed by existing Facebook Pokémon Go communities. A couple of cross-promotion partnerships later, we 10x our reach. More importantly, we reached the right people – early Pokémon Go adopters.

InterviewLesson 2: Journalists like a positive, feel-good story

Within a few hours of creating the event, we also got contacted by journalists. In my experience, once the first journalist gets in touch, others soon follow. Alja and I cleared our schedule for the next day and started explaining the game. The aspect that I liked the most is that we didn’t focus on the actual game content too much. We rather talked about the social and urban aspects of it. As it stands right now, the game itself is a pure antithesis of modern society. It encourages you to go out and explore the world around you, mingling with other players, and working together on the same goals. This explained the context for the global interest and makes it easier for journalists to explain it to the general audience. At some point, Alja also suggested that we need better titles. It was a light, summer-time story, so picking Pokémon trainer made complete sense. It’s just silly enough that it brings smile to people’s faces. It will also give me an opportunity to measure its reach and how long people will remember it.

Lesson 3: Letting it go

Pokémon Go is big at the moment and it’s going to have a huge following for months and years ahead. But high level of required engagement and battery drain on phones will be deal breakers for the general public. This will reduce the audience to the younger generation that will actually play the game. Discuss all the stats, trade Pokémon (once thats available) and battle each other. This will be a community of interest that needs enthusiastic leaders that will help them teach and organise follow-up events. I’m happy that many of them them came to the event in person and I’m sure they’ll figure out how to collaborate.


Facebook on its own is enough to get you traction, but you still need traditional media to get legitimacy and wider reach.

When 750 people on Facebook say they are going, 20% of that number will actually come (~150), as seen in our case. Still a huge success, just don’t plan your food budget based on that.

Just relax and go with the flow. Not everything has to have an immediate business value or a long term goal.

Thanks to Tamara Muhic, for proof-reading draft of this post.

Example of ember-form-for and mirage server side validation

At the time of writing, ember-form-for is the top Ember.js plugin for forms on Ember Observer. It provides a straightforward way to display form fields without having to write all the boilerplate HTML code around it.

What you do is you take:

    <label>First name: {{input value=model.firstname}}</label>
    {{#each model.errors.firstname as |error|}}
      <span class="errors">{{error.message}}</span>

and replace it with form-for-model helper:

{{#form-for model as |f|}}
  {{f.text-field "firstname"}}

  .. // other fields and submit button

It will generate HTML code for you, as well as display validation errors.

Complete form becomes much more readable this way:

{{#form-for model as |f|}}
  {{f.text-field "firstname"}}
  {{f.text-field "lastname"}}

  {{ "gender" "unknown male female"}}
  {{f.checkbox-field "terms" label="I agree to the Terms of Service"}}

  {{f.submit "Submit"}}

I’ve created a dedicated Github branch ember-form-for, that you can experiment with:

Travel Time distances from Ljubljana Center


View the interactive map

My friends are looking to buy an affordable house around Ljubljana. But what are their options, if they want to choose based on commute time? I decided to build a tool to visualise their options.

An isochrone map (isochrone plan, isochrone diagram) in science and urban planning is a map showing areas related to isochrones between different points. An isochrone is defined as “a line drawn on a map connecting points at which something occurs or arrives at the same time” (

Methodology and Technology

I’ve generated a grid of ~40.000 points in Slovenia and calculated travel time to it from a fixed point in Ljubljana Centre. Each point is displayed on a map with radius of 800 meters. It’s a tradeoff between number of points and realistic travel time with a car in a populated area.

For routing and time calculations, I used Project OSRM with OpenStreetMap database of Slovenia. A Python script connected all of this together into a static dataset for the the web site.

Lessons learned

I first coded a prototype with  Google Maps Directions API. It turns out that 2500 requests/day isn’t enough to make such an application practical.

I then found OSRM and it allowed me to host directions API directly on my computer. It’s also really fast. On a single i7 core, it can do about 40 requests/second. In practice is almost as good as commercial API’s. Based on my tests, the difference of results is about +/- 5 minutes.

What is missing is traffic data. OSRM is returning travel time in optimal traffic conditions. While some of this data is openly available, I’m not sure how to incorporate it. It would also mean that the whole visualisation would need to display the time component too.

What’s next

I’d like to build a similar version for public transportation – both inside Ljubljana and in the greater Ljubljana region.

It wouldn’t be too hard to make this map dynamic – so you could select your own starting point.

I’ve also discovered that running your own directions API opens up a number of new possibilities. One of them would is potentially adding a layer of routing to so we could calculate travel time and also suggest rides that pass through your city.

Do you have any ideas?

Let me know in the comments.

I now also have a newsletter so you can be notified when I release something new. Subscribe to it now 🙂.