This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2021-11-17
Channels
- # aleph (4)
- # announcements (2)
- # babashka (85)
- # beginners (136)
- # calva (72)
- # clj-commons (32)
- # clj-kondo (7)
- # cljs-dev (3)
- # clojure (117)
- # clojure-europe (38)
- # clojure-nl (3)
- # clojure-norway (1)
- # clojure-uk (4)
- # clojurescript (19)
- # conjure (38)
- # core-logic (2)
- # cursive (10)
- # datalevin (1)
- # datalog (1)
- # datomic (6)
- # events (2)
- # fulcro (16)
- # google-cloud (5)
- # graphql (10)
- # gratitude (3)
- # hugsql (3)
- # luminus (5)
- # membrane-term (12)
- # missionary (2)
- # nextjournal (5)
- # off-topic (3)
- # pedestal (2)
- # polylith (7)
- # portal (3)
- # re-frame (6)
- # reagent (26)
- # reclojure (8)
- # releases (3)
- # reveal (5)
- # shadow-cljs (14)
- # spacemacs (20)
- # sql (3)
- # tools-build (3)
- # web-security (9)
So, curiously, even though the documentation kinda lets on that you can reuse negotiate-content
for other kinds of negotiation, e.g. language, in practice it is completely hardcoded to content-type. I ended up making my own interceptor and reusing the parsing functions:
(defn ->language-negotiation-ic
"Make a language negotiation interceptor from a coll of `supported-languages`.
The interceptor reuses Pedestal's content-negotiation logic, but unlike the
included content negotiation interceptor this one does not create a 406
response if no match is found."
[supported-languages]
(let [match-fn (conneg/best-match-fn supported-languages)
lang-paths [[:request :headers "accept-language"]
[:request :headers :accept-language]]]
{:name ::negotiate-language
:enter (fn [ctx]
(if-let [accept-param (loop [[path & paths] lang-paths]
(if-let [param (get-in ctx path)]
param
(when (not-empty paths)
(recur paths))))]
(if-let [language (->> (conneg/parse-accept-* accept-param)
(conneg/best-match match-fn))]
(assoc-in ctx [:request :accept-language] language)
ctx)
ctx))}))