Profile picture Schedule a Meeting
c a n d l a n d . n e t

Clojure Duct setup with MongoDB, Foundation, and Buddy - Part 2

Dusty Candland | | clojure, duct, sass, webjars

Zurb Foundation && SASS

Add Zurb Foundation or whatever webjars you want to use.

[org.webjars/foundation "6.2.0"] [org.webjars/font-awesome "4.6.2"]

Setup a SASS file

I put these in src/sass/. You can import from webjars like this.

@import 'foundation/scss/foundation'; @import 'foundation/scss/util/mixins'; @import 'font-awesome/scss/font-awesome';

Watching SASS files in dev

Need to add SASS support. Checked out sass4clj. There is a lein plugin, but that didn't play well with figwheel. I did end up using some ideas from that and the sass4clj project to integrate with figwheel.

I started with this SASS Watcher which was a good starting point, but didn't load in the webjars. So the next step is replace with sass4clj which does reference webjars.

in dev.clj require these

[sass4clj.core :refer [sass-compile-to-file]]
[watchtower.core :refer :all]

Next create a new component to watch the SASS files and recompile on changes. A lot of these came from the lein-sass4clj project.

(defn- main-file? [file]
  (and (or (.endsWith (.getName file) ".scss")
           (.endsWith (.getName file) ".sass") )
       (not (.startsWith (.getName file) "_"))))

(defn- find-main-files [source-paths]
  (mapcat (fn [source-path]
            (let [file (io/file source-path)]
              (->> (file-seq file)
                   (filter main-file?)
                   (map (fn [x] [(.getPath x) (.toString (.relativize (.toURI file) (.toURI x)))])))))
          source-paths))

(defn watch-sass
  ""
  [input-dir output-dir options]
  (prn (format "Watching: %s -> %s" input-dir output-dir))
  (let [source-paths (vec (find-main-files [input-dir]))
        sass-fn
        (fn compile-sass [& _]
          (doseq [[path relative-path] source-paths
                  :let [output-rel-path (clojure.string/replace relative-path #"\.(sass|scss)$" ".css")
                        output-path     (.getPath (io/file output-dir output-rel-path))]]
            (println (format "Compiling {sass}... %s -> %s" relative-path output-rel-path))
            (sass4clj.core/sass-compile-to-file
              path
              output-path
              (-> options
                  (update-in [:output-style] (fn [x] (if x (keyword x))))
                  (update-in [:verbosity] (fn [x] (or x 1)))))))
        ]
    (watchtower.core/watcher
       [input-dir]
       (watchtower.core/rate 100)
       (watchtower.core/file-filter watchtower.core/ignore-dotfiles)
       (watchtower.core/file-filter (watchtower.core/extensions :scss :sass))
       (watchtower.core/on-change sass-fn))
    )
  )

(defrecord SassWatcher [input-dir output-dir options]
  component/Lifecycle
  (start [this]
    (prn "Starting SassWatcher Component.")
    (if (not (:sass-watcher-process this))
      (do
        (println "Figwheel: Starting SASS watch process:" input-dir output-dir)
        (assoc this :sass-watcher-process (watch-sass input-dir output-dir options))
        )
      this))
  (stop [this]
    (when-let [process (:sass-watcher-process this)]
      (println "Figwheel: Stopping SASS watch process")
      (future-cancel process))
    this))

Next setup a config for compilation and add the compoent to the dev system.

(def sass-config
  {:input-dir "src/sass" ;location of the sass/scss files
   :output-dir "resources/nspkt/ui/public/css"
   :options
   {:source-map true
    ;:output-style :nested, :compact, :expanded and :compressed
    ;:verbosity 1, 2
    }
   })

(defn new-system []
  (into (system/new-system config)
        {:figwheel (figwheel/server (:figwheel config))
         :sass (map->SassWatcher sass-config)}
        ))

Now we're watching the files and updating on change. I think figwheel should pick up those changes and push an reload, but something doesn't seem to be working there.

Webmentions

These are webmentions via the IndieWeb and webmention.io. Mention this post from your site: