taoensso / tower

i18n & L10n library for Clojure/Script
https://www.taoensso.com/tower
Eclipse Public License 1.0
278 stars 24 forks source link

using figwheel in translation #70

Open keerts opened 8 years ago

keerts commented 8 years ago

We are used to the rapid feedback cycle that figwheel gives us in development. So we tried to make translation fit in nicely, but can't seem to get it to work. Any idea what could cause this?

We are trying to achieve this by adding figwheel-always to the metadata (see below). What we expect is that the dictionary reloads for every cljs file that we save. But it doesn't. When I eval the complete namespace (emacs cider-eval-buffer) the dictionary does reload. Especially that last fact puzzles me.

(ns ^:figwheel-always relations-for-jira.localization
  (:require [taoensso.tower :as tower :include-macros true]))

(def ^:private tconfig
  {:fallback-locale :en-US
   :dev-mode? true
   :compiled-dictionary (tower/dict-compile* "i18n/dictionary.clj")})

(def t (tower/make-t tconfig))
maciejka commented 7 years ago

@keerts: Have you managed to solve the problem?

keerts commented 7 years ago

Unfortunately not. We have moved to boot in the meanwhile.

ai212983 commented 7 years ago

In case someone is still interested.

To use tower with figwheel, you have to trigger rebuilding of namespace containing tconfig each time your dictionary.clj changes. It can be done via figwheel scripting.

Here's my figwheel.clj:

(import org.apache.commons.io.filefilter.WildcardFileFilter)
(require
  '[figwheel-sidecar.config :as conf]
  '[leiningen.core.project :as lein]

  '[figwheel-sidecar.components.file-system-watcher :as fsw]
  '[figwheel-sidecar.system :as sys]
  '[com.stuartsierra.component :as component])

; read lein project and extracting config with figwheel internal machinery
(def lein-config (conf/->lein-project-config-source (lein/read)))
(def figwheel-config (-> lein-config
                         conf/config-source->prepped-figwheel-internal
                         (get :data)))

(defn touch [file-path]
  (-> file-path clojure.java.io/file (.setLastModified(System/currentTimeMillis))))

(defn create-notification-handler [file-pattern touch-file]
  (let [f (WildcardFileFilter. (str file-pattern))]
    (fn [_watcher files]
      (when (not-empty (filter #(.accept f nil %) (map str files)))
        (touch touch-file)))))

(def system
  (atom
    (component/system-map
      :figwheel-server (sys/figwheel-system figwheel-config)
      ; sidecar do not have css watcher by default, so we have to add it manually
      ; see https://github.com/bhauman/lein-figwheel/blob/4a34663097cae43865e6008ada062500ebe65102/sidecar/README.md
      :css-watcher (component/using
                     (sys/css-watcher {:watch-paths (get-in figwheel-config [:figwheel-options :css-dirs])})
                     [:figwheel-server])
      :custom-watcher (let [{:keys [dir file-pattern touch-file]} (get-in lein-config [:data :figwheel-watch])]
                        (component/using
                         (fsw/file-system-watcher {:watcher-name         "Custom Watcher"
                                                   :watch-paths          [dir]
                                                   :notification-handler (create-notification-handler file-pattern touch-file)})
                         [:figwheel-server])))))

(defn start []
  (println (prn-str (get-in lein-config [:data :figwheel-watch])))
  (swap! system component/start))

(defn stop []
  (swap! system component/stop))

(defn reload []
  (stop)
  (start))

(defn repl []
  (sys/cljs-repl (:figwheel-server @system)))

;; Start the components and the repl
(start)
(repl)

Figwheel is started with rlwrap lein run -m clojure.main --init script/figwheel.clj -r, and project.clj contains an entry in the root:

 :figwheel-watch {:dir          "resources"
                  :file-pattern "*.clj"
                  :touch-file   "src/cljs/my.project/dictionary.cljs"}

Whenever file matching *.clj is edited in resources directory, dictionary.cljs will be touched and project rebuilt.

You can go fancy, add multiple files/directories support for watching, or rebuild that particular namespace only and notify your application whenever change occur, but that will require some tinkering.