metasoarous / toto

Static site generation in Clojure (with live code reloading!)
Eclipse Public License 1.0
111 stars 3 forks source link

improve live reloading of template functions and build specs #2

Open dantheobserver opened 3 years ago

dantheobserver commented 3 years ago

I have my test site set up similarly to how it's shown on the README, it doesn't mention where to put the templates or build function so I added my own to src/app/main.clj with the following

(ns app.main
  (:require [toto.core :as toto]
            [clojure.string :as str]))

(defn site-template
  [doc]
  [:div
   [:h1 "Test Site Template"]
   doc])

(defn blog-template
  [doc]
  ;; Here's where we get our metadata
  (let [{:as doc-meta :keys [title published-at tags]} (meta doc)]
    [site-template
     [:div
      [:h1 title]
      [:p "Published at: " published-at]
      [:p "Tags: " (str/join ", " tags)]
      [:br]
      doc]]))

(defn -main []
  (toto/build!
   [{:from "site-src/pages"
     :to "build/"
     :template-fn site-template}
    {:from "site-src/blog-posts"
     :to "build/blog"
     :template-fn blog-template}]))

I've added the --main opts to invoke that namespace, and when I run it loads properly and sees the changes to the markdown files, but when I change the template it does not reload.

metasoarous commented 3 years ago

Hi @dantheobserver. Thanks for submitting this issue.

Currently this is not supported, but I think it's a great idea. Probably doing something like #1 would suffice though, as you could simply have your build! specification watch for changes to the src/app/main.clj file itself. I'm curious to think through whether there's something even more slick we could come up with though.

For now, what I do to quickly re-render when I update my template functions is to run from a REPL process so that I simply re-evaluate the namespace. This does require a little more set up to make smooth when run as a main function like you're doing here, so I'll think about how that can be improved.

Thanks again!

dantheobserver commented 3 years ago

I have been going down the REPL workflow route, I noticed I get a runtime exception if I evaluate the buffer for the templates after the server is started. In order to re-evaluate the template defun to get it to run, I have to call start-server! again. Maybe I'm not doing the process correctly, could you outline how the workflow for a repl would allow for this, because doing mutliple evaluations of build! seems to cause a crash with the following stack trace

1. Unhandled java.lang.StackOverflowError
   (No message)

       transport.clj:  119  nrepl.transport/bencode/fn
       transport.clj:   28  nrepl.transport.FnTransport/send
       print.clj:  159  nrepl.middleware.print/send-nonstreamed
       print.clj:  138  nrepl.middleware.print/send-nonstreamed
       print.clj:  174  nrepl.middleware.print/printing-transport/reify
       caught.clj:   58  nrepl.middleware.caught/caught-transport/reify
       track_state.clj:  228  cider.nrepl.middleware.track-state/make-transport/reify
       print.clj:  115  nrepl.middleware.print/replying-PrintWriter/fn
       nil:   -1  nrepl.middleware.print.proxy$java.io.Writer$ff19274a/write
       BufferedWriter.java:  120  java.io.BufferedWriter/flushBuffer
       BufferedWriter.java:  256  java.io.BufferedWriter/flush
          PrintWriter.java:  396  java.io.PrintWriter/flush
                  core.clj: 3711  clojure.core/flush
                  core.clj: 3721  clojure.core/prn
                  core.clj: 3714  clojure.core/prn
               RestFn.java:  137  clojure.lang.RestFn/applyTo
                  core.clj:  665  clojure.core/apply
                  core.clj: 3733  clojure.core/println
               core.clj: 3733  clojure.core/println
               RestFn.java:  421  clojure.lang.RestFn/invoke
                  core.clj:  691  toto.core/eval41931/fn
              MultiFn.java:  234  clojure.lang.MultiFn/invoke
                  core.clj:  695  toto.core/eval41931/fn
              MultiFn.java:  234  clojure.lang.MultiFn/invoke
                  core.clj:  695  toto.core/eval41931/fn
              MultiFn.java:  234  clojure.lang.MultiFn/invoke
                  core.clj:  695  toto.core/eval41931/fn
...

repeated many times

metasoarous commented 3 years ago

Interesting. Thanks for the heads up. I do this all the time with Oz, but it's possible that this is an issue with the migration. I'll try to take a look soon. Thanks again!