Backen (VOR WUT) – Losstopshow 39

Ein Jahr Berlin. Wow. In diesem Video gibt es keine Highlights, aber dafür … anderes.

Lesetagebuch 5

Die neue Lesetagebuch-Version wurde letzte Nacht auf den Server geschubst. Aus meinem hervorragenden Blogpost darüber:

Weise Programmierer sagen immer »Was auch immer du machst, mach auf keinen Fall einen kompletten Rewrite«, und darum bin ich Anfang des Jahres losgezogen um einen kompletten Rewrite zu machen. Wie ein echter Profi.

In den bisherigen Versionen hatte ich meine Datenbankanbindung selbst geschrieben. Das bewegte sich zwischen »Alle Objekte sind Dictionaries und enthalten nur, was die Datenbank enthält« und »Alle Objekte haben eigene Klassen, die auf verschiedene Weisen mit der Datenbank sprechen, bis auf die ›Später Lesen‹-Einträge, weil ich dafür zu faul bin«.

Natürlich war das kein dauerhaft haltbarer Zustand. Darum fing ich an, die Seite komplett neu zu schreiben, diesmal nicht nur auf Basis von Flask und Jinja2, sondern mit Hilfe von Peewee und WTForms. Peewee ist ein wunderbarer, leichter ORM, der subclassing sehr einfach macht, und WTForms geht mir manchmal auf die Nerven, erspart es mir aber, Formularvalidierung selber schreiben zu müssen.

»Und warum hat das dann so lange gedauert?«, fragt ihr euch jetzt vielleicht, »Du bekamst doch quasi alles geschenkt?«. Tja. John Lennon hat es ja schon gesagt: Das Leben ist, was passiert, während man versucht, einen Rewrite einer Bücherleseplattform zu schreiben.

Fix your life (and your URLs to static files in your Jinja templates)

Whenever you want to link to a static file in Jinja templates, you probably use url_for('static', filename=your_file). That’s great, but it may cause problems with your users, who may keep using a cached version of your kickass CSS file. But it doesn’t have to be that way. Cachebust your URLs for maximum convenience!

import app

app.create_jinja_environment()

def url_for_buster(endpoint, **values):
    if endpoint == 'static':
        filename = values.get('filename', None)
        if filename:
            file_path = os.path.join(app.root_path,
                                     endpoint, filename)
            values['q'] = int(os.stat(file_path).st_mtime)
    return url_for(endpoint, **values)

app.jinja_env.globals.update(url_for=url_for_buster)

Daniel, what are you doing?

Great question! I’m overwriting Jinja’s regular url_for function with a custom function that adds a parameter q to all URLs that link to the static endpoint, but that doesn’t change other URLs. The value of q is the timestamp of the linked file. That way, whenever you update the file, the parameter is changed and the browser thinks it’s a different file.

So, instead of linking /static/style.css, you’ll link to /static/style.css?q=1407762775. Nice.

R: [Irgendwas über Mozart und Wien]. Mozart wohnte doch mal in Wien?

D: Zumindest behauptet Falco das.

R: Wer ist Falco?

D: Das ist dieser Sänger? Der »Rock Me Amadeus« gesungen hat? Falco? Der Österreicher? Falco? Der King of Pop? Falco?

R: Der mit der Sonnenbrille und der roten Jacke?

D: DAS IST HEINO. WAS IST FALSCH MIT DIR.