Introduction
       ------------------------------------------------------------
       
       goophi is a Gopher implementation written in Clojure. It
       comes with the following features:
       
         * self-explanatory & powerful routing syntax
         * built-in filesystem module
         * built-in HTTP redirection module
         * Aleph[1] compatibility
       
       
       Installation
       ------------------------------------------------------------
       
       This library can be installed from Clojars [2].
       
       Leiningen/Boot
       --------------
       
       [de.dixieflatline/goophi "0.2.0"]
       
       
       Quick overview
       ------------------------------------------------------------
       
       Routing & entities
       ------------------
       
       A Gopher request is represented as a map. It has the
       following keys:
       
         * path: selector
         * query: search string
         * params: parameters found in selector
         * remote-addr: remote ip address (added by the Aleph handler)
       
       The routing module checks whether a path from the request map
       matches a pattern and evaluates the corresponding body upon success. The
       routing module converts a Gopher request to a map & evaluates a function
       returning an entity.
       
         (use 'goophi.core)
         (use 'goophi.routing)
         (use 'goophi.response)
       
         ;; construct request map for testing purposes
         (defn- ->request
           [path]
           {:path path})
       
         (def hello-world
           (route
            "*"
            []
            (menu-entity (info "hello world"))))
       
         (print-text-stream (hello-world (->request "/")))
       
         -> ihello world
         -> .
       
       Placeholders can also be used, which are bound to vars.
       
         (def route-with-vars
           (route
            "/blog/articles/:category"
            [category]
            (menu-entity (info (str "Articles from category " category)))))
       
         (print-text-stream (route-with-vars (->request "/blog/articles/programming")))
       
         -> iArticles from category programming
         -> .
       
       
       filesystem module
       -----------------
       
       goophi has a built-in filesystem module with gophermap
       support.
       
         (use 'goophi.fs)
       
         (def fs-example
           (route
            "*"
            [:as req]
            (get-contents "./example-pub" (:path req))))
       
         (print-text-stream (fs-example (->request "docs/hello.txt")))
       
         ->   |\__/,|   (`\
         ->  _.|o o  |_   ) )
         -> -(((---(((--------
         -> .)
       
       
       redirection module
       ------------------
       
       URLs are displayed on an HTML redirection page.
       
         (def redirect-example
           (route
            "URL\\:*"
            [:as req]
            (if-let [url (selector->url (:path req))]
              (redirect url)
              (menu-entity (info "Not found.")))))
       
         (print-text-stream
          (redirect-example (->request "URL:https://dixieflatline.de")))
       
         -> <!DOCTYPE html> ...
       
       
       TCP
       ---
       
       Build Aleph compatible request handlers with the tcp module.
       
         (require '[aleph.tcp :as tcp]
                  '[goophi.tcp :refer [aleph-handler]])
       
         (def my-routes
           (routes
            ("*"
             [:as req]
             (or (get-contents "./example-pub" (:path req))
                 (menu-entity (info "Not found."))))))
       
         (tcp/start-server
          (aleph-handler my-routes)
          {:port 70})
       
       
       Middleware
       ----------
       
       Read or change the request map by composing a custom request handler.
       
         (defn log-request
           [handler]
           (fn [req]
             (printf "address: %s, path: %s\n"
                     (:remote-addr req)
                     (:path req))
             (flush)
             (handler req)))
       
         (def my-app
           (-> my-routes
               log-request))
       
         (def s (tcp/start-server
                 (aleph-handler my-app)
                 {:port 70}))
       
       
       References
       ------------------------------------------------------------
 (HTM) [1]: Aleph
 (HTM) [2]: Clojars
       
       
       WWW
       ------------------------------------------------------------
 (BIN) main.zip
 (HTM) GitHub