Turn hiccup into html in a reagent application - clojure

This might sound a stupid question, but how do I turn a piece of hiccup into html in a ClojureScript reagent application?
I want something like this :
(html [:div [:p "hello world" ]])
that produces
<div><p>hello world</p></div>
This is what you can do in hiccup.core, but as far as I can see, that's in Clojure. Not ClojureScript in the browser.
OTOH, ClojureScript / Reagent clearly knows how to do it in the browser. It's doing it all the time. But I can't actually find a library call anywhere in reagent where I can do this explicitly, outside the reagent rendering process.

I'm not sure why you would want to do this, but it appears one answer is to use the function:
reagent.dom.server/render-to-string
Normally, your Reagent components only return Hiccup data, and you let reagent.dom/render do all the hard work of reactively "rendering" only the changed components into the DOM.
P.S. When in doubt, you can often find documentation at cljdoc.org. Most Clojure projects have a direct link there from their GitHub page (Reagent does, for example). Or, you can go to cljdoc.org directly and search there.

Related

How can I communicate with the backend using ClojureScript and Figwheel?

Note: I'm a moderately experienced programmer in general and using clojure but have never done serious web development.
I set up a basic ClojureScript project using Chestnut and walked through the "Hello World" steps just fine. However I would really like to talk to my backend as well. For this purpose I redefined the Reagent code to be
(defn greeting []
[:input {:type "button"
:value (:text #app-state)
:on-click #(http/get {})}])
Which gets a 404 response when clicked. So at least I'm talking to somebody. I can also see evidence of my get-requests in the server.log file. However at this point I'm struggling with a number of conceptual points.
First of all http/get is a function defined in clj-http.client, which wasn't part of the Chestnut setup. It feels like I'm already off track if I have to go hunting for libraries to send something as basic as a get-request.
Secondly the file for the user namespace has the following lines predefined by Chestnut:
(def http-handler
(wrap-reload #'mypage.server/http-handler))
(defn run []
(figwheel/start-figwheel!))
I can't see any place where the http-handler is ever used. So I don't understand what that definition even does.
Also the way I understand Figwheel, when I call "run" it'll spin up a new web server which then a) serves the index.html and b) connects to my browser via some TCP port and starts pumping new JavaScript through that connection. This second part is very speculative on my part. If this is actually what happens my next question would be if Figwheel also needs to sit on the other side of that connection or if browsers have some common API that allows code reloading from the outside.
Lastly I can kinda tell that the ring routes and http-handler defined in the mypage/server.clj file (below) are being called somehow, since modifying these changes the error from the get-request, however it's a complete mystery to me how this works. The way I understand it the get-request I'm sending from the browser is sent to the Figwheel-server, the origin of the site. I have no reason to believe that Figwheel knows anything about the http-handlers I've defined in the server file.
(defroutes routes
(GET "/" _
{:status 200
:headers {"Content-Type" "text/html; charset=utf-8"}
:body (io/input-stream (io/resource "public/index.html"))})
(resources "/"))
(def http-handler
(-> routes
(wrap-defaults api-defaults)
wrap-with-logger
wrap-gzip))
For a ClojureScript project (i.e. not Clojure), I believe you want this: https://github.com/r0man/cljs-http
I don't have a complete answer, but I do have a couple points that might help.
Clojurescript ultimately compiles down to JavaScript, and makes heavy use of (and has access to) the Google Closure library. So if you really want to, you can use JavaScript interop to just make an AJAX call from the client-side, just like you would in JS. The closure library provides a wrapper for this---see docs here https://developers.google.com/closure/library/docs/xhrio . But there are also several easy http and Ajax libraries for clojurescript, so why not use them? Another part of the joy and magic of clojurescript is that the Google closure optimizations that get applied do lovely things like strip out dead code, so I believe (and someone else can correct me if I'm wrong) that there is little (no?) production cost to putting some extra libraries in.
Figwheel is ultimately dev, not production, and doesn't depend on the http server that you set up for production use. Indeed, there are templates out there for front-end-only cljs projects that still use figwheel--- here's one example. Figwheel spins its own server to push changes to the browser, I'm not quite sure how it works.

Can I create a program in Clojure able to edit it's own code?

I am thinking of creating an educational program in Clojure that would show a console where the user could edit code in order to change a running code in another part of the screen (like a game, for instance). Would that be possible? If so, what should I study in order to be able to do this?
It is possible. See this Interactive programming Flappy Bird in ClojureScript . It uses clojurescript and figwheel as its development environment.
The awesome thing about figwheel is that you can change the flappybird running code in the browser by simply evaluating new code in the repl and then figwheel push the new code to the browser. The changes happened in real time.
You can start studying clojure and clojurescript.
Hm, changing code during runtime is one of the basic concepts behind clojure.
Watch this for more on this topic: https://www.youtube.com/watch?v=P76Vbsk_3J0
Otherwise every repl or form of a repl can do that.
To get started have a look at Lighttable: http://lighttable.com/ It has inline evaluation in the editor.

Hello World - Clojurescript

Beginner here.
Can I compile an existing Clojure script to run it on the web using ClojureScript?
Let's say that I have a script that prints Hello world in my terminal, and I want to print that text on the browser. Should I rewrite a whole script with ClojureScript syntax, or should I just compile it using another compiler?
(ns clojure-hello-world.core
(:gen-class))
(defn -main [& args]
(println "Hello World"))
(Long answer :P)
Even though Clojure and ClojureScript share a good amount of features, there are some that are specific to one or the other. For example there are no real classes in JavaScript so the :gen-class specification in the ns form doesn't make much sense.
One important fact is that the syntax of both Clojure and ClojureScript is exactly the same, differences have to do mostly with the host VM in which they run (Java VM in the case of Clojure and JavaScript VM in the case of ClojureScript).
There is a list of the differences between the two Clojure implementations here.
There's also a tool called cljx to "write a portable codebase targeting Clojure/ClojureScript". Recently there has been some discussion on the Clojure Dev group around finally implementing feature expressions which would on one hand deprecate the use of cljx but on the other complicate the work that tools have to do to extract information from Clojure source files.
I would start with lein-cljsbuild to get started. This will get you going with a nice edit eval and look at browser loop. It's well worth getting this setup first because it makes learning ClojureScript much more fun. I promise it's worth the hassle. If you need more interactive support the folks in #clojure on freenode are very kind and helpful.
Basically, the Browser executes JavaScript. You compile your ClojureScript code to JavaScript. The Browser loads your JavaScript via an HTML page. So, you have to create an HTML Page and point your Browser at it.
The simplest way I got started was to use Luminous (http://www.luminusweb.net/docs/clojurescript.md).
However, Chestnut (https://github.com/plexus/chestnut) looks promising.

Troubles Importing Clojure Libs in Paradise

I occasionally get this problem, and generally work around it, but it's rather frustrating.
I have all of Incanter (check it out if you don't know it: it's superb) on my classpath. I try to import it (through a Slime REPL) like this: user> (use 'incanter.core), but fail.
Doing this: user> (use 'clojure.contrib.def) works just fine, and this file is in the same place–on my classpath.
Regardless, the error isn't anything about classpath: it's this:
Don't know how to create ISeq from: clojure.lang.Symbol
[Thrown class java.lang.IllegalArgumentException]
You can see my entire terminal here (a screenshot.)
I don't know what's going on here, and it's really frustrating, as I really would like to use Incancter, and I can from the Incanter binary's REPL. I definitely don't want to develop from that–and this should work.
Any help would be much appreciated.
EDIT:
It appears as though Incanter requires Clojure 1.2, and lein swank gives me Clojure 1.1. This might be the cause of my problems: if so, is there a way to continue to use Swank & Lein with Clojure 1.2?
Thanks again!
EDIT:
Apparently if you start using Clojure-1.1 and lein swank, you're stuck with it unless you make a new project.
If future people have this problem, this article helped me out, but also, at least for me, you must start a new lein project if you had begun it using leink swank and Clojure-1.1. Simply changing your project.clj file and then lein swanking again doesn't work.
Yes, you can use Leiningen and swank-clojure with Clojure 1.2. You might need to use a recent version of Leiningen (I'm not sure if a certain old limitation affected lein repl only or was it lein swank as well; anyway, try the 1.2-RC2 which you'll find in the downloads section on GitHub). You will also need to use a recent-enough swank-clojure; I use a bleeding edge checkout myself, get yours here.
Other than that, simply use 1.2 jars for Clojure and contrib. (Lein uses it's own Clojure, separate from the one used for lein swank, for its internal workings and you never need to care about it; swank-clojure has no AOT'd namespaces and doesn't particularly care about the Clojure version, except once in a (long!) while something breaks, a patch is applied and joy is restored.)
I hope the above helps, but if it doesn't: your problem description is not entirely sufficient for me to get a clear picture of what is happening. Could you add information on what it means for "all of Incanter" to be on your classpath (do you mean the jars? sources? where do you get them? how do you set your classpath?). Without knowing this, it'll be hard to replicate your setup to try to track down the source of the problem.
Of course if bumping some versions fixes things, please disregard my current confusion. ;-)

webjure vs compojure?

I've heard of two Clojure based web application frameworks: Webjure and Compojure. Can someone let me know which is better?
Now you can add Ring to the list. All of these frameworks are very new and likely to evolve (or die) quickly, but Compojure does seem to be the most actively developed based on the past 6 months or so.
"Better" is too subjective a question to get a definitive answer to. Try them all and see what works.
Compojure has been working very well for me so far. I like the simplicity of the design, the flexibility and the fact that it encourages a nice idiomatic functional style.
Sample server:
(use 'compojure)
(defroutes my-app
(GET "/index.html"
(html
[:h1 "Hello World!!"]
[:body "This is some text"]))
(ANY "*"
[404 "Page not found"]))
(run-server {:port 80}
"/*" (servlet my-app))
Note that Compojure uses Ring internally.
I second Rayne's recommendation on Moustache.
Right now, we are using Ring (base layer, middleware), Moustache (routing), Hiccup (html generation). We just began using Compass for CSS (http://compass-style.org/). So far, I'm happy with this collection of small libraries rather than a big "complete stack" framework (Django, Rails, ect...).
Now, there is also a new one named Noir build on top of compojure. Really recommended, especially with Heroku.
Compojure seems to be getting the most buzz right now. Not necessarily indicative of quality, but the one with the most eyes will probably evolve the fastest.
There is also Moustache, which is what I use in TryClojure, along with Ring. It's pretty awesome.
Compojure is based on Ring, which is a low-level framework that doesn't attempt to hide much of HTTP. It's similar to WSGI (Python) or Rack (Ruby). Ring has a concept of middleware, small pieces of code that can do something meaningful with an HTTP request and/or response, such as dump header infos, manage cookies etc. Compojure is a higher-level framework, somewhat similar to Ruby's Sinatra. Its aim is to provide a convenient API (or DSL, if you prefer) for most tasks a Web app developer faces. It's usually used together with an HTML generation library, such as Hiccup.
I haven't heard much about Webjure in the last few months, I'm not sure it's in active development (but I'd be interested to find out more). It precedes Ring, AFAICT, which seems to have become somewhat of a standard for Clojure Web frameworks.
I've been building a project for my own use using Compojure and it has worked out great. It doesn't really get in the way very much and lets you focus on what's important, your problem domain. The project is about 1100 lines of clojure just to give you an idea of the size.