Fork me on GitHub
Jacob O'Bryant02:08:23

did a bunch of work on platypub themes today. should have it pushed tomorrow. the default theme will be structured like a regular project (I.e. with a deps.edn file and all the code under src), which means custom themes can reuse the code via a git dependency rather than having to copy and paste. same goes for themes' config.edn file. I'll publish the updated theme for the Biff site too which will demonstrate a custom theme that reuses stuff from the default theme. (and once that's done I'll finally be able to publish stuff to the Biff site again haha... I never got around to updating it after the last theme breaking change, which is why I haven't published the recording of the last meetup yet) in the process of that I tried out bb tasks again and was really happy with it. at some point I'll replace the task in biff projects with that, which will make it easy to move task code into a library.

Jacob O'Bryant02:08:49

also I think we can use this for running theme code in a sandbox: basically we just need to give it a dockerfile that installs babashka and stuff. once that's figured out it shouldn't take too much work before I/anyone who wants to can run a public instance of platypub for anyone to use.

👍 1

Fly looks cool and cheap. Good idea

👌 1

BTW I haven't looked in depth but it looks like fly has a hosted postgres

Jacob O'Bryant13:08:53

they do. my main concern for fly as a deployment solution is how well it plays with a repl-driven workflow, especially develop in prod. it also has fewer instance sizes that digitalocean, eg an fly the shared cpu instances max out at 2gb of ram. so there may be cases on fly where you end up paying more than you would on DO. (not to mention that in general fly containers are a bit more expensive than the equivalent DO droplet)

Soe H13:08:41

Hi, another beginner question, how to refer to the value of anti-forgery-token? so I can use it without biff/form? I want to do, but I don't know how to add the csrf token.

Jacob O'Bryant16:08:51

You can use ring.middleware.anti-forgery/*anti-forgery-token* . e.g. I recently put this in an app I'm working on:

(ns com.yakread.ui
  (:require [ring.middleware.anti-forgery :as anti-forgery]
            [cheshire.core :as cheshire]

(defn app-page [sys & contents]
    {:hx-headers (cheshire/generate-string
                  {:x-csrf-token anti-forgery/*anti-forgery-token*})}
then any htmx requests that happen within an app-page will include the csrf token whether or not they're used within a biff/form

thanks3 1
Jacob O'Bryant16:08:01

(I might move that into biff/base-html at some point)

Soe H04:09:31

Thank you, I knew the moment I asked question I will get the answer the next day. You are awesome. Maybe we need a biff cookbook.

Jacob O'Bryant06:09:30

A cookbook is being planned ;) or at least a collection of how-to guides.

👍 1
Jacob O'Bryant16:08:56

Another Biff coding meetup this Thursday at 9:00 AM Pacific. I'm going to add password authentication to, which currently only has email link authentication. Zoom link: RSVP:

🙌 2

Good day, I'm attempting to create a simple biff app. Where the user can submit a title for a game which is then saved to the db. However, I'm getting a 405 (method not allowed), after submitting the form. app.clj

  (:require [com.biffweb :as biff]
            [ :as ui]
            [xtdb.api :as xt]))

(defn game-form [{:keys [value]}]
   {:hx-post "/app/set-game"
    :hx-swap "outerHTML"}
   [:label.block {:for "game"} "game: "]
    [:input.w-full#game {:type "text" :name "game" :value value}]
    [:button.btn {:type "submit"} "Save"]]))

(defn set-game [{:keys [params] :as req}]
  (biff/submit-tx req
                  [{:db/doc-type :game
                    :game/title (:game params)}])
  (biff/render (game-form {:value (:game params)})))

(defn app [_]
   [:div.text-blue-100.text-3xl "Games"]))

(def features
  {:routes ["/app"
            ["" {:get app}]
            ["/create/" {:get game-form}]
            ["/set-game/" {:post set-game}]]})
(def schema
  {:game/id :uuid
   :game/title :string
   :game [:map {:closed true}
           :xt/id :game/id

Jacob O'Bryant18:08:29

Does it work if you change the route from ["/set-game/" {:post set-game}] to ["/set-game" {:post set-game}] (i.e. remove the trailing slash)? either that or change the request to :hx-post "/app/set-game/" , so they match. Reitit can handle get requests that add/omit a trailing slash, but I'm not sure if it does the same for other request types.


I just tried these combos without success:

:hx-post "/app/set-game/" .....
["/set-game/" {:post set-game}]

:hx-post "/app/set-game" .....
["/set-game" {:post set-game}]

:hx-post "/app/set-game/" .....
["/set-game" {:post set-game}]


I also tried it as a form action without htmx which gives me a 500"internal Server Error"

{:action "/app/set-game/"} .....
["/set-game/" {:post set-game}]

Jacob O'Bryant20:08:44

I just noticed there is a problem with the schema. There should be a vector around :xt/id :game/id, i.e.

(def schema
  {:game/id :uuid
   :game/title :string
   :game [:map {:closed true}
          [:xt/id :game/id]
Did the terminal show an error message about invalid schema/transaction?


Good catch, Console:

clojure.lang.ExceptionInfo: :malli.core/invalid-schema {:schema :xt/id}
{:type :malli.core/invalid-schema, :message :malli.core/invalid-schema,
:data {:schema :xt/id}}
but even after wrapping in brackets I'm still getting the 405
[qtp282925789-23] INFO com.biffweb.impl.middleware -   1ms 405 post /app/create/

Jacob O'Bryant21:08:05

that log message shows that /app/create/ endpoint is being posted to instead of /app/set-game/. if you set both strings to /app/set-game and save the file, are there any other errors shown in the terminal? if there's an evaluation error, that could be preventing the changes from taking effect


yep , looks like that's the problem

(def features
  {:routes ["/app"
            ["" {:get app}]
            ["/set-game/" {:get game-form }]
            ["/set-game/"{:post set-game}]]}) 
Execution error (ExceptionInfo) at reitit.exception/exception (exception.cljc:19).
Router contains conflicting route paths:

-> /app/set-game/ 
-> /app/set-game/

Jacob O'Bryant01:08:04

ah yes, you can merge those and have a single map with :get and :post keys

🙌 1

Thanks, that was the problem in the end. BTW nice work on the site updates, the docs are much easier to navigate, and +1 on the new tagline.

Jacob O'Bryant18:08:18

(cc @U054219BT, this'll make reusing config from the default theme much less tedious 🙂 see for an example)

Jacob O'Bryant20:08:49

also just pushed another small commit that will further speed up site rendering

Jacob O'Bryant18:08:55

This is I think the last big update I need for my personal use, so going forward for platypub I'll try to write less code and more documentation. I think I said that last time I did a release, but this time I mean it ha ha

Jacob O'Bryant18:08:58

This is now imo the next most important issue to close: Basically we need a proof-of-concept for setting up a Machine (I think we basically just give it a dockerfile that sets up babashka?) that exposes a post endpoint. We want to pass a zipfile to the endpoint that includes the theme code + input.edn file, and have it return the rendered site. and see how quickly that can happen. I'll get to it eventually, but if anyone's looking for a weekend project, I think this would be fun 🙂


Came here and was about to ask if someone had already done a set up with biff, nice


Oh it seems to be something else

Jacob O'Bryant20:08:13

Yeah, this would be using just for a one-off feature. however I also am interested in deploying there: