johnke.me

Bring Her Back

Poster for Bring Her Back
Watched on July 5, 2025
Rating:

I enjoyed the Philippou’s previous film, Talk to Me. It was a simple premise effectively told by a bunch of genre sickos.

Their follow-up, Bring Her Back is a different beast. It’s still got plenty of the stuff that we want from a film like this - a lady learning how to summon a demon via a Russian VHS? Yes… ha ha ha… yes! - and when the film goes hard, it goes fucking hard with plenty of, uh, mouth destruction(?) with some top-class foley-work that is plenty squirm-inducing.

But this comes at a cost. I feel like the story, by virtue of being more complicated, kind of got away from them a little? At times the film is let down by some incredibly inelegant writing (e.g. Chekhov’s body-spray) with an inability to settle on a single tone they were going for and that made it less of a fun hang. It’s frustrating because the film is so close to being a lot better than it is.

But I’m begging of you, A24, can you please, please, please stop trying to make Hereditary again?

Fair play to Sally Hawkins though. Not so much playing against the Sally Hawkins type as much as weaponising the Sally Hawkins type by placing it in a more sinister context.

Movies as Topps Trading Cards

I’m trying to switch over to the Affinity design tools (designer, photo). The best way I’ve found to learn a new thing is to give yourself a specific project so you’re forced to poke at the uncomfortable bits. So I decided for this, I’d mock up some Topps trading cards for some rad movies that deserved some trading cards.

Mad Max: Fury Road

Freddy Got Fingered

Jurassic World: Rebirth

Poster for Jurassic World: Rebirth
Watched on July 2, 2025
Rating:

The first Jurassic Park film was a formative cinematic experience for me. The last Jurassic World film, Dominion was a firm DNF. A heck of a drop-off in a series.

So I’m happy to say that Jurassic World: Rebirth takes us back to the high highs of being about as good as Jurassic Park 3. Which is still objectively not great, but it’s infinitely better than movies 4-6. It story is about a world where people aren’t interested in dinosaurs any more and they’re dying around them and it’s hard not to read this as a meta-commentary on what happened to the franchise in the bombastic-but-dull Pratt years.

In fairness to Gareth Edwards, the film looks mostly gorgeous. A lot of the outdoor shots felt genuinely expansive. I can’t remember the last time a blockbuster hasn’t felt entirely volume-y or soundstage-y. A couple of times, Edwards even manages to capture some of the Spielberg magic. Even without the explicit callback of someone standing in the bow rail of a boat and shooting at a monstrous fish, there are parts here that nail the vibe of Jaws, which is an impressive feat. Another part of the film even captured the vibe of Aliens, of all films. People sometimes complain that Edwards makes films that are too cold and too clinical, but I feel like he’s finally proved them wrong here.

The real problem with Jurassic World: Rebirth that the script is total shite. We get an “objects in the mirror are closer than they appear” reference right after the cold open, which felt like a punch in the gut destroying whatever positive expectations I had. It’s when I realised this was going to be a film more about callbacks than anything new. Like buying a toaster from Amazon and then the algorithm constantly recommending you toasters. Remember the bit where they first see the brachiosaurus? Here it is again but with 100% more tail (and, somehow, not substantially better graphics? One of the exceptions I was thinking of when I said “mostly gorgeous”). Remember the “they do move in herds” bit? Here it is again but instead of 10 dinosaurs, the herd is 100 dinosaurs. Remember the flare bit? Remember? I understand there’s probably a lot of complicated franchise maintenance involved in a film like this and a certain amount of fan-service but the dial feels way, way off here. The original Jurassic Park had some absolute banger lines that have stuck with us for 30 years, like the entire “your scientists were so preoccupied with whether or not they could” speech. Rebirth gives us - and I’m not kidding here - “You don’t see that every day!” Absolutely atrocious work from David Koepp.

Thunderbolts

Poster for Thunderbolts
Watched on July 1, 2025
Rating:

Off the bat, it’s clear that Thunderbolts* is trying to do a little more than recent Marvel outings, and I appreciate that (I don’t log DNFs here but I haven’t managed to make it through any recent Marvel properties at all). And they’re injecting a hint of life into proceedings with some funny one-liners but that now-default Marvel tone where everything is incredibly serious but also not at all serious? I know it’s hard to let it go but I think I’m kind of done with it.

Anyway, it was nice to see a superhero film that doesn’t resolve itself by having enormous cgi monsters hitting each other. So kudos for that, I guess?

Also strict moratorium on bullshit filler like “that’s what I’m talking about” and “that just happened!” in any scripts going forward. You’re on a yellow card, Marvel.

MASH

Poster for MASH
Watched on July 1, 2025
Rating:

Jesus, this is one boomer-ass movie.

I’m a fan of Altman’s style and can only imagine how refreshing it must have been at the time. Once the movie starts, there’s barely five seconds where someone isn’t talking. Usually there are multiple people talking over each other. It’s relentless and chaotic, but in a good way.

But holy shit, watching this in 2025, it’s hard to see these counter-culture anti-heroes as anything other than a pack of sexist, racist, misogynistic, homophobic boomer assholes.

Importing Linkding bookmarks into Hugo

One of my goals for the second half of 2025 is to reduce the amount of duplication in my life. I have a half a dozen read/watch/listen-it-later services. My tasks are strewn across four different productivity systems. I’m too old for this kind of nonsense, and I’d like to get this down into something more manageable.

A nice easy starting point for decluttering: the links system on this site. I migrated from Pinboard to Raindrop to a Linkding instance at bookmarks.johnke.me. That’s where I store my bookmarks. But what about if I find something I want to share on this site? Well for that, I run a bash script (bin/newlink.sh) passing the URL and it will generate a Hugo post for that link. Last year, with version v0.126.0, Hugo introduced a new feature: content adapters. This allows Hugo, a static site generator, to dynamically generate content from another source. In their examples, they just use a dict but you can also use the output of an API. An API like the one provided by Linkding?

Setting this up was shockingly easy!

First, I put some Linkding config in Hugo’s top-level config.yaml:

params:
  ...
  linkding:
    url: "https://bookmarks.johnke.me/api/bookmarks/?q=%23johnke.me"
    token: "MY_API_TOKEN"
  ...

The ?q==%23johnke.me means that any bookmark I tag with johnke.me will be picked up by the content adapter.

Then I put a _content.gotmpl at the top-level of the section where I want my content created. So in my case, I have a content/link/_content.gotmpl that looks like this:

{{/* Fetch bookmarks from Linkding */}}
{{/* Set using HUGO_PARAMS_LINKDING_URL, HUGO_PARAMS_LINKDING_TOKEN or in Hugo config */}}
{{/* Full endpoint URL with any filters, e.g. "https://bookmarks.johnke.me/api/bookmarks/?q=%23dorkus" */}}
{{ $URL := .Site.Params.linkding.url }}
{{ $TOKEN := .Site.Params.linkding.token }}

{{/* Get remote data. */}}
{{ $data := dict }}
{{ $headers := dict "Authorization" (print "Token " $TOKEN) }}
{{ $opts := (dict "headers" $headers) }}
{{ with try (resources.GetRemote $URL $opts) }}
  {{ with .Err }}
    {{ errorf "Unable to get remote resource %s: %s" $URL . }}
  {{ else with .Value }}
    {{ $data = . | transform.Unmarshal }}
  {{ end }}
{{ else }}
  {{ errorf "Unable to get remote resource %s" $URL }}
{{ end }}

{{/* Add pages and page resources. */}}
{{ range $data.results }}
  {{/* Skip entries with empty titles */}}
  {{ if .title }}
    {{/* Add page. */}}
    {{ $content := dict "mediaType" "text/markdown" "value" .notes }}
  }}
    {{ $dates := dict
      "date" (time.AsTime .date_added)
      "lastmod" (time.AsTime .date_modified)
    }}

    {{/* For tags, remove `johnke.me` */}}
    {{ $tags := slice }}
    {{ range .tag_names }}
      {{ if ne . "johnke.me" }}
        {{/* Dashes to spaces */}}
        {{ $tag := replace . "-" " " }}
        {{ $tags = $tags | append $tag }}
      {{ end }}
    {{ end }}

    {{/* I use the 'link' parameter to point to the URL */}}
    {{ $params := dict
      "link" .url
      "tags" $tags
    }}

    {{/* Create a safe filename from the title */}}
    {{ $safePath := .title | urlize }}
    {{ if not $safePath }}
      {{ $safePath = printf "bookmark-%d" (time.AsTime .date_added).Unix }}
    {{ end }}

    {{ $page := dict
      "path" $safePath
      "kind" "page"
      "title" .title
      "dates" $dates
      "params" $params
      "content" $content
    }}
    {{ $.AddPage $page }}
  {{ else }}
    {{ warnf "Skipping bookmark with empty title: %s" .url }}
  {{ end }}
{{ end }}

Finally, since this whole thing is driven by github actions, I added a schedule to my action definition so twice a day, it will regenerate the site with any new links I’ve added:

on:
  ...
  schedule:
    # Runs every day at 2:00 AM and 2:00 PM UTC
    - cron: '0 2,14 * * *'
  ...

And that’s it! I have links coming directly in from Linkding and I have one canonical source of truth for all my bookmarks and one less point of redundancy!

Neat!