Comments (30)
Ok - well reload is working fine for me on Windows, at least if I execute the following code to monkey-patch enlive's broken url-to-path conversion:
(require 'net.cgrand.reload)
(defmethod watch-url "file" [^java.net.URL url ns]
(let [fs (java.nio.file.FileSystems/getDefault)
path (.getPath fs (.getAbsolutePath (java.io.File. (.toURI url))) no-strings)
ws (watch-service ns)]
(ws path)))
Additionally in my startup namespace, which doesn't contain any deftemplate/defsnippet code, I execute:
(net.cgrand.reload/auto-reload (find-ns 'com.example.namespace1))
for each namespace with templates.
Alternatively, you could automate that with something like:
(doseq [n (->> (loaded-libs)
(filter #(.startsWith (name %) "com.example.mytemplates."))
(map find-ns)
(filter #(:net.cgrand.reload/deps (meta %))))]
(net.cgrand.reload/auto-reload n))
This works for me with [enlive "1.1.5"]
from enlive.
Is this already possible but not documented somewhere?
from enlive.
Usually one achieve auto-reloading through http://mmcgrana.github.com/ring/middleware.reload-api.html
from enlive.
Ring's middleware.reload was recently changed so that namespaces are only reloaded if their source files or dependencies change, so now templates don't automatically get reloaded by middleware.reload.
I'm not sure how best to handle this? Perhaps there is some way that enlive could expose the set of files and namespace mappings so that an enlive reloader middleware could reload the namespaces if any of the related templates change?
from enlive.
Any developments on this? djpowell is correct in pointing out that the Ring reload middleware doesn't solve the issue.
To clarify, if mytemplates.clj defines some Enlive templates using html resource files foo.html and bar.html and ring-reload-modified is loaded:
Changes to mytemplates.clj will trigger a reload of mytemplates.clj.
Changes to foo.html or bar.html will not trigger a reload of mytemplates.clj.
This isn't a major issue, but it'd be nice if we could figure out a way of handing dependency reloading automatically.
Christophe, any thoughts on David's experiment? https://gist.github.com/1396481
from enlive.
Hey guys, what was the resolution for this ticket? I'm very interested in the case where editing and saving an HTML template file will trigger a reload. I'd be happy to try another approach to this and submit a pull request, if the above weren't suitable for some reason.
Thanks!
Sam
from enlive.
Ping
from enlive.
Since there is no official solution for this I solved it using guard. Basically I just use the guard-shell (https://github.com/guard/guard-shell) plugin to monitor my template files and if they change I use touch to update the correspoding clojure file. Works like a charm for my use case.
My guard file:
guard 'shell' do
watch(%r{^resources/public/templates/(.*)/(.*)\.html$}) {|m| `touch src/workoutbook/templates/#{m[1]}.clj` }
end
from enlive.
Configurable auto-reloading of templates would indeed be awesome. In the meantime, I've used the relatively simple fix of creating a custom middleware for my projects based on the old "brute-force" version of ring.middleware.reload prior to this commit: mmcgrana/ring@f39e24d#ring-devel/src/ring/middleware/reload.clj
from enlive.
Reloading everything is quite an expensive operation.
So far the best solution I could come up with is similar to guard one. I only use https://github.com/ibdknox/watchtower instead of guard. I watch resources directory, and as we have dirs structured in a similar way to the enlive template namespaces, it's basically a require :reload call.
from enlive.
How does the auto reload functionality work? I've added (net.cgrand.reload/auto-reload *ns*)
at the bottom of the file which defines my templates & snippets, but changing them does not result in the changes being picked up. I have java 7.
Also, if java 7 is required for this, it's worth documenting in the readme.
from enlive.
Same here. I don't really understand how auto reload actually works. Can you explain how ?
from enlive.
See touchme: a leiningen plugin to touch clj files when html are modified.
from enlive.
Touching files isn't ideal, because it can confuse your editor (triggering a prompt to revert to the file on disk, for instance). I've been using this approach in my projects. It leverages watchtower.
(defn- handle-template-file-change [files]
(require 'my-project.handler :reload))
(defn init []
; Reload this namespace and its templates when one of the templates changes.
(when-not (= (System/getenv "RING_ENV") "production")
(watcher/watcher ["resources"]
(watcher/rate 50) ; poll every 50ms
(watcher/file-filter (watcher/extensions :html))
(watcher/on-change handle-template-file-change)))
This init function is called by Ring on startup. See Ring's :init setting for project.clj.
from enlive.
@cgrand Given your recent changes, what is the proper way to setup reloading?
Is this a correct way to explain it? "Put this line in every Clojure file that uses deftemplate
or defsnippet
?"
(net.cgrand.reload/auto-reload *ns*)
If so, perhaps a few clarifying words in the README would help?
from enlive.
@philc
Right. But I prefer having this type of feature outside my code. And a lein plugin is good for that. I don't really like having my reloading code inside init method (or other), this is just a development helper, not my software's code.
from enlive.
@xpe auto-reloading is, to me, first and foremost a dev-time feature so I wouldn't put
(net.cgrand.reload/auto-reload *ns*)
in my main source files. Rather in a bunck of helper files I source in the repl.
from enlive.
Adding
(net.cgrand.reload/auto-reload *ns*)
to my Clojure file that uses deftemplate
doesn't seem to help much.
I occationally get Reloading what-the-emacsd.core
in the terminal process running the app, but it seems to have nothing to do with when I touch a template file - and it doesn't update the defined template.
Am I using it wrong?
from enlive.
Yeah, this does not do what it says on the tin. It should be removed from the README in order to cut down on confusion. Don't pretend to have features you don't!
from enlive.
Any update on this?
from enlive.
Are you running Windows? I had to use this patch to get things running on
Windows:
#106
Then I also only got it to work by putting the calls to auto-reload
external to the namespace that I was trying to make reload.
On Wed, Jul 2, 2014 at 5:55 PM, Limbo Peng [email protected] wrote:
Any update on this?
—
Reply to this email directly or view it on GitHub
#6 (comment).
from enlive.
@djpowell It's on Linux. Where should (net.cgrand.reload/auto-reload *ns*)
be placed?
from enlive.
I have a app.core namespace that starts up ring etc, and then the various
bits of the app have there own namespaces with code + deftemplates. I had
think I had some problems when I put auto-reload together with the
deftemplates, but it worked fine when I put it in app.core.
In fact, I put a loop in, to find all namespaces in (loaded-libs) and
called auto-reload on everything in my packages that
had :net.cgrand.reload/deps defined. Bit of a hack, but it saves me
listing each one.
On Thu, Jul 3, 2014 at 5:05 PM, Limbo Peng [email protected] wrote:
@djpowell https://github.com/djpowell It's on Linux. Where should (net.cgrand.reload/auto-reload
ns) be placed?—
Reply to this email directly or view it on GitHub
#6 (comment).
from enlive.
@djpowell thx :) I'd try it later
from enlive.
@djpowell Still not working.
Here's my setup:
- dev server is started via
lein ring server-headless
- I've put the line
(net.cgrand.reload/auto-reload *ns*)
insideviews.clj
(in which the template is defined)
Expected: modify the HTML file, refresh browser, and see modification in effect.
Actually got: refreshed and nothing happened. But if I touch views.clj
(which triggers reloading done bylein-ring
) and refresh, the modification is applied.
from enlive.
Hey guys,
Just my 2c, this might be considered a slightly grotesque approach - but in my project, I simply introduced my own deftemplate and defsnippet macro's that add the namespace and the resource file to a watchlist, then simply polled for changes and fired off an ns reload based on the changes..
Code below, hope this helps someone..
(ns server.web.enlive
(:use [server.util])
(:require [net.cgrand.enlive-html :as en]
[clojure.java.io :as io]))
(defonce template-list (atom {}))
(defn last-modified [source]
(-> (clojure.lang.RT/baseLoader) (.getResource source) (clojure.lang.RT/lastModified source)))
(defn update-source-time [source]
(swap! template-list assoc-in [source :time] (last-modified source)))
(defn register-template [source namespace]
(swap! template-list update-in [source :ns] assoc namespace true)
(update-source-time source))
(defmacro defsnippet [nm source selector args & forms]
`(do
(register-template ~source ~*ns*)
(en/defsnippet ~nm ~source ~selector ~args ~@forms)))
(defmacro deftemplate [nm source args & forms]
`(do
(register-template ~source ~*ns*)
(en/deftemplate ~nm ~source ~args ~@forms)))
(defn get-changes [tlist]
(for [source (keys tlist)
:let [entry (get tlist source)
time (:time entry)
newtime (last-modified source)]
:when (< time newtime)]
(assoc entry :source source)))
(defn reload-changed []
(doseq [{:keys [source ns]} (get-changes @template-list)]
(info source " changed")
(update-source-time source)
(doseq [n (keys ns)]
(require (ns-name n) :reload))))
from enlive.
I guess the problem here is that "auto-reloading templates" has two sides - auto-reloading the Clojure source when the Clojure source changes and auto-reloading the Clojure source when the HTML source files changes. The (net.cgrand.reload/auto-reload ns) achieves the former and my code snippet earlier achieves the latter.
from enlive.
Ah that is true. I just embed an nrepl that gets turned on in a development environment, and use that to reload code changes.
from enlive.
On my Macbook detecting a file change with the watch service used by net.cgrand.reload takes up to 8 seconds, so I came up with alternative polling solution (ring middleware), see https://github.com/kolov/enlive-reload. I've used it extensively on Mac OS Yosemite, no experience whatsoever on other platforms.
from enlive.
Reload fixed in 1.1.6.
8 sec reload on Mac not experienced, rather in the order of 1 sec.
Closing for now, thankies!
from enlive.
Related Issues (20)
- hiccup-style adapter doesn't cope well with transformation results HOT 2
- Automated CSS selector translation to vector form HOT 5
- [org.jsoup/jsoup "1.8.3"] exists HOT 1
- Make JSoup the default for enlive 1.2 HOT 1
- StackOverflowError when parsing certain html HOT 4
- Composable selector/transform in snippet HOT 1
- Simple variable substitution (with example) in meta tag throwing NullPointerException HOT 2
- Less obscure error messages
- first-child
- End tag for <col> violates the specs
- javax.net.ssl.SSLHandshakeException while trying to reach some resources HOT 1
- attribute matching inside at-form HOT 1
- "safe write" "feature" in IntelliJ prevents auto-reloading of namespace depending on changed HTML
- Removing element cleanly HOT 2
- Is this project dead? HOT 1
- Update jsoup dependency to v1.11.3+
- Setting HTTP headers HOT 1
- Broken wiki link in project description
- HTML resource not found
- Any interest in CSS-style selector syntax option? HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from enlive.