Skip to content

Commit

Permalink
Merge pull request #361 from cljdoc/html-coercion
Browse files Browse the repository at this point in the history
Refactor how HTML body is created in coerce-body helpers
  • Loading branch information
Jakub Holy committed Nov 3, 2019
2 parents cdaa9be + 4c1799a commit 48363ef
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 35 deletions.
20 changes: 10 additions & 10 deletions src/cljdoc/server/pedestal.clj
Expand Up @@ -90,13 +90,13 @@
`route-name` can be either `:artifact/index`, `:group/index` or `:cljdoc/index`."
[store route-name]
[(pu/coerce-body-conf
(fn html [{:keys [path-params]} content-type body]
(if (= content-type "text/html")
(fn html-render-fn [ctx]
(let [artifact-ent (-> ctx :request :path-params)
versions-data (-> ctx :response :body)]
(case route-name
:artifact/index (index-pages/artifact-index path-params body)
:group/index (index-pages/group-index path-params body)
:cljdoc/index (index-pages/full-index body))
body)))
:artifact/index (index-pages/artifact-index artifact-ent versions-data)
:group/index (index-pages/group-index artifact-ent versions-data)
:cljdoc/index (index-pages/full-index versions-data)))))
(pu/negotiate-content #{"text/html" "application/edn" "application/json"})
(interceptor/interceptor
{:name ::releases-loader
Expand Down Expand Up @@ -257,9 +257,7 @@
:enter (fn build-show-render [ctx]
(if-let [build-info (->> ctx :request :path-params :id
(build-log/get-build build-tracker))]
(if (= "text/html" (pu/accepted-type ctx))
(pu/ok ctx (cljdoc.render.build-log/build-page build-info))
(pu/ok ctx build-info))
(pu/ok ctx build-info)
;; Not setting :response implies 404 response
ctx))}))

Expand Down Expand Up @@ -409,7 +407,9 @@
:search [(interceptor/interceptor {:name ::search :enter #(pu/ok-html % (render-search/search-page %))})]
:shortcuts [(interceptor/interceptor {:name ::shortcuts :enter #(pu/ok-html % (render-meta/shortcuts))})]
:sitemap [(sitemap-interceptor storage)]
:show-build [pu/coerce-body
:show-build [(pu/coerce-body-conf
(fn html-render [ctx]
(cljdoc.render.build-log/build-page (-> ctx :response :body))))
(pu/negotiate-content #{"text/html" "application/edn" "application/json"})
(show-build build-tracker)]
:all-builds [(all-builds build-tracker)]
Expand Down
53 changes: 28 additions & 25 deletions src/cljdoc/server/pedestal_util.clj
Expand Up @@ -10,37 +10,40 @@
[context]
(get-in context [:request :accept :field] "text/html"))

(defn transform-content
([body content-type] transform-content body content-type nil)
([body content-type transformer]
(let [body' ((or transformer identity) body)]
(case content-type
"text/html" (str body')
"application/edn" (pr-str body')
"application/json" (json/generate-string body')
"application/x-suggestions+json" (json/generate-string body')))))
(defn- render-body
[body content-type]
(case content-type
"text/html" (str body)
"application/edn" (pr-str body)
"application/json" (json/generate-string body)
"application/x-suggestions+json" (json/generate-string body)))

(defn coerce-to
([response content-type] (coerce-to response content-type nil))
([response content-type transformer]
(-> response
(update :body transform-content content-type transformer)
(assoc-in [:headers "Content-Type"] content-type))))
(defn- coerce-to
[response content-type]
(-> response
(update :body render-body content-type)
(assoc-in [:headers "Content-Type"] content-type)))

(defn coerce-body-conf
"Coerce the `:response :body` to the `accepted-type`, optionally passing it
through the `transformer`, a `(fn [request content-type body] (modify body))`
See [[transform-content]]."
[transformer]
"Coerce the `:response :body` to the `accepted-type`, passing it through `html-render-fn`
if the resulting content type should be `text/html`. `html-render-fn` will receive the request
`context` as its only argument.
Maybe HTML rendering could also be handled in a separate interceptor that uses [[accepted-type]]
to conditionally convert the data provided via `:body` to it's HTML representation."
[html-render-fn]
(interceptor/interceptor
{:name ::coerce-body
:leave (fn [context]
(let [content-type (accepted-type context)
transformer' (when transformer
(partial transformer (:request context) content-type))]
(cond-> context
(nil? (get-in context [:response :headers "Content-Type"]))
(update-in [:response] coerce-to content-type transformer'))))}))
(if (get-in context [:response :headers "Content-Type"])
context
(let [content-type (accepted-type context)
rendered-body (if (= content-type "text/html")
(html-render-fn context)
(-> context :response :body))]
(-> context
(assoc-in [:response :body] rendered-body)
(update :response coerce-to content-type)))))}))

(def coerce-body
(coerce-body-conf nil))
Expand Down

0 comments on commit 48363ef

Please sign in to comment.