Created
October 7, 2014 19:05
-
-
Save pleasetrythisathome/7adbdc9c8b7ab689df45 to your computer and use it in GitHub Desktop.
some code stripped out of a project showing use of silk for isomorphic routing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns router | |
#+cljs (:require-macros [cljs.core.match.macros :refer [match]]) | |
(:require [domkm.silk :as silk] | |
[clojure.string :as str] | |
#+clj [content :as content] | |
#+clj [drivers.email :as email] | |
#+clj [clojure.core.match :refer [match]] | |
#+clj [compojure.core :as compojure :refer [defroutes GET POST PUT DELETE]] | |
#+clj [compojure.route :as route] | |
#+clj [com.stuartsierra.component :as component] | |
#+clj [render :as render] | |
#+clj [ring.util.response :as response] | |
#+cljs [cljs.core.match] | |
#+cljs [utils.helpers :as h])) | |
(def app-routes | |
(silk/routes [[:home [[]]] | |
[:section [[:page]]] | |
[:news [["news" :post]]]])) | |
(defmulti route->section :domkm.silk/name) | |
(defmethod route->section :default | |
[_] | |
[:home]) | |
(defmethod route->section :section | |
[{:keys [page]}] | |
(-> page | |
keyword | |
vector)) | |
(defmethod route->section :news | |
[{:keys [post]}] | |
[:news post]) | |
(defn arrive | |
[{:keys [uri] :as req}] | |
(silk/arrive app-routes uri route->section)) | |
(defn section->state | |
[[page & args]] | |
(match [page args] | |
[:news (args :guard seq)] (let [[post] args] | |
[:news {:post (name post)}]) | |
[:home _] [:home {}] | |
[page _] [:section {:page (name page)}])) | |
(defn depart | |
[{:keys [section]}] | |
(let [[route params] (section->state section)] | |
(silk/depart app-routes route params))) | |
#+clj | |
(defn generate-response [type data & [status]] | |
{:status (or status 200) | |
:headers {"Content-Type" (condp = type | |
:html "text/html; charset=utf-8" | |
:edn "application/edn")} | |
:body (cond-> data | |
(= type :edn) pr-str)}) | |
#+clj | |
(defn- ring-routes | |
[render] | |
(compojure/routes | |
(route/resources "/") ;; Serve static resources | |
(GET "*" req | |
(let [section (arrive req) | |
;; content/get-state returns state for a section. | |
;; you can implement either websockets or http requests for this state from the frontend | |
;; you could also use a .cljx file that could submit the requests. many ways of dealing with updates | |
state (content/get-state section)] | |
;; render is a server renderer similar to the one in omelette | |
;; https://github.com/DomKM/omelette | |
(generate-response :html (render state)))) | |
(POST "/subscribe" {:keys [edn-params]} | |
(let [{:keys [code error]} (email/signup edn-params)] | |
(generate-response :edn {:success (= code 0)}))) | |
(route/not-found "Not Found"))) | |
#+clj | |
(defrecord Router [routes renderer] | |
component/Lifecycle | |
(start [this] | |
(assoc this | |
:routes (ring-routes (:render renderer)))) | |
(stop [this] | |
(dissoc this :routes))) | |
#+clj | |
(defn router [] | |
(map->Router {})) | |
;; used elsewhere | |
;; in root component did-mount | |
;; browser history management | |
;; go-aware is from https://gist.github.com/pleasetrythisathome/38717e93b09b257393a9 | |
(.go-aware owner (browser/listen-navigation history) | |
(fn [token] | |
(let [route (router/arrive {:uri token})] | |
(put! (:nav chans) route)))) | |
;; in tx-listen | |
(when (= :nav tag) | |
(let [route (router/depart new-state)] | |
(browser/navigate! history route))) | |
;; browser functions are https://gist.github.com/pleasetrythisathome/d1d9b1d74705b6771c20 | |
;; history above created by init-history |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment