48 Hours of Writing Stylesheets with Etherpad and a Gong

A video of the redesign of the OSP homepage, from a traditional blog based site to a site that is used to communicate our design process in a ‘release early, release often’ manner: every time we add a file to our shared repository it shows up on our site.

The screenshots above are from a period of 48 hours where we work on the site together. To write CSS, we keep a shared Etherpad. One person is in charge of the gong: when she rings, she copies the contents of the pad into the site’s CSS file, and uploads it—after which everyone can refresh their browser and see the updated styles.

Update 2013-11-10:

If you run a recent version of Etherpad, you can install ep_export_less_and_css, a plugin bnf created that enables CSS export directly from Etherpad.


So if you were all writing these styles on an Etherpad together, is there no way to ‘hotlink’ to the pad directly, instead of copying it over all the time?

One would figure, because the Titanpad we are using here does allow to export a plain text version of the pad. The problem is, this old version of Etherpad needs a ‘cookie’ before it allows a download. In the newest Etherpad that is not at a problem. So we can try to link it directly:

<link rel="stylesheet" href="http://etherpad.fr/p/osp-css/export/txt" type="text/css" />

It still does not work. Examing the metadata from the request (the ‘headers’) from the command line tells us why:

curl -i http://etherpad.fr/p/osp-css/export/txt
HTTP/1.1 200 OK
X-Powered-By: Express
Server: Etherpad-Lite f478f99 (http://etherpad.org)
Access-Control-Allow-Origin: *
Content-Type: text/plain
Content-Disposition: attachment; filename="osp-css.txt"
Content-Length: 5980ETag: "-661067728"
Set-Cookie: express_sid=s%3AUqYrsj8ZbMvBr6HRmRTqIo1v.19jQ%2F8NhfN2SZTTJUCMl3qXsDRnQBZfHTKeUICIFRMg; Path=/; HttpOnly
Date: Thu, 09 May 2013 21:04:46 GMT
Connection: keep-alive

Every HTTP response contains information about what kind of data is being sent. The stylesheet is transmitted with the mime-type text/plain;. Browsers will only accept stylesheets transferred with the mime-type text/css. You need to set up a little proxy, that gets the stylesheet, and sends it out again with the changed mimetype.

Here is a little Ruby script that does just that:

require 'sinatra'
require 'net/http'

get '/osp-live.css' do css = Net::HTTP.get_response(URI.parse("http://etherpad.fr/p/osp-css/export/txt")).body content_type 'text/css' css end

What do you do with that script? Where does it go? Should I upload it to a server?

With PHP, there still exists some link between the urls of the web application and the files on the server. You put the PHP files in the same place where you put the HTML files and they can be accessed in much the same way: in/some/folder/lives/a-php-script.php. In Ruby and Python apps, you usually have the web server forward all the requests to a separate web-application. The Python or Ruby files that make up this web-application can live anywhere, and have no real link to the urls of the web page.

The application above is a ruby file, and could be called app.rb, or however you want. In the application it is written that any request for the url /osp-live.css will receive the designated response. The script uses the library Sinatra, that popularised this style of writing web apps, where you specify: for this url, send back this contents.

The question then is just how to do you tell the webserver to use this file as a web-application… With PHP, because you can put them in the same place as the HTML files, it ‘just works’. Configuring a Python or Ruby application is different for each hosting environment: and most cheap hosts don’t actually offer support for these languages.

There is weird paradox here: When learning programming with Python, I have found it much more easy and accessible than PHP. Ruby is more fun and straightforward as well. But getting these languages running on the web is much more difficult.

This also has implications for sharing tools, which for me is an important part of Open Source / Free Culture. Tools like Wordpress and Wikimedia have been wildly succesful because they have used this PHP platform which makes for extremely easy redistribution of the software.

With designers and developers moving on to other development platforms, there is a vital need to make these platforms accessible to amateurs and enthousiasts, not just to developers who can afford to set up a specialised working environment.

I have witnessed this first hand when trying to work with content creation tools created in Django (a Python web framework): getting someone elses Django project to set up is extremely daunting, and this is really detrimental to the dissemination of Open Source projects that use it.

In PHP, it would be something like this:

header("Content-type: text/css");

    $ch, array( 
    CURLOPT_URL => "http://etherpad.fr/p/osp-css/export/txt",
$output = curl_exec($ch);
echo $output;

Put it in a file called osp-live-css.php, or something, upload it on your webserver and link to it in the CSS declaration in your HTML.

Never mind, I have found a solution more easy still. I made a ‘plugin’ for the etherpad software, that allows export as CSS:

You can install it from Etherpad’s plugin admin panel, as ep_export_less_and_css. The source code is on Github.

There is weird paradox here: When learning programming with Python, I have found it much more easy and accessible than PHP. Ruby is more fun and straightforward as well. But getting these languages running on the web is much more difficult.

And how did you make the video?

You need to leave a computer one that will do the screenshots for you. If you’ve installed webkit2png 1 , the following line in the terminal will have you take a screenshot each 5 minutes:

while true; \
do webkit2png -F -W 1280 -H 720 http://osp.constantvzw.org/; \
sleep 300; \

The images are all cropped to 1280x720 pixels, already a standard HD movie size. Now we want to convert all the images we captured into a movie file.

The open source FFMPEG package is great for this, except it can only deal with file names that contain continuously incrementing numbers. You can’t skip one. This command will change all your images into filenames like 00000.png, 00001.png, 00002.png etcetera 3 :

c=0; for i in *.png; do mv "$i" "`printf %05d $c`.png"; c=$((c+1)); done

And run the conversion:

ffmpeg -r 3 -i %05d.png -f mov -vcodec qtrle -pix_fmt rgb24 osp.web.movie.mov

The compression, or codec, is lossless in this case. Popular video codecs like mp4 are optimised for camera footage like jpeg is optimised for photos—here we use the video equivalent of png, the Quicktime Animation codec 4 .

You set the framerate, the number of frames per second with the -r option, in this case 3 frames per second .

  1. Webkit2png is OS X only. PhantomJS runs on Linux (even on servers).
  2. Adapted from: http://thp.io/2007/12/creating-stopmotion-movies-with-ffmpeg.html
  3. Adapted from: http://superuser.com/questions/347433/how-to-create-an-uncompressed-avi-from-a-series-of-1000s-of-png-images-using-ff in the end the video will probably be transcoded into a lossy format when you upload it onto Youtube/Vimeo… but this way you avoid doing the lossy encoding twice, and you have a full fidelity version to archive.

CSS Sucks!


Leave a comment