GithubHelp home page GithubHelp logo

px0 / wisp-compiler Goto Github PK

View Code? Open in Web Editor NEW
11.0 3.0 0.0 112 KB

Compiles wisp expressions to Javascript in your Clojure project

License: Eclipse Public License 1.0

Clojure 2.17% Makefile 0.76% wisp 97.08%

wisp-compiler's Introduction

Wisp Compiler

This lets you compile wisp forms (or strings) into Javascript

Clojars Project

Why?

This allows you to embed Clojure-flavoured JavaScript into your hiccup, pages, e.g.:

(require '[wisp-compiler.core :as wisp])

(hiccup/html
  [:div
    [:button {:onclick (wisp/compile [] (hello-world))} "Hello!"]
    [:script (wisp-compile
      (defn hello-world []
        (alert (str :Hello " World!"))))]])

which will compile into

<div>
    <button onclick="helloWorld();">Hello!</button>
    <script>
        var helloWorld = function helloWorld() {
            return alert('' + 'Hello' + ' World!');
        };
    </script>
</div>

Okay, but show me something useful

Compiling sexps into JavaScript is neat by itself, but sometimes you want to generate JavaScript dynamically on the server (e.g. for Server-generated JavaScript Responses). In this case you may have held your nose and just concatenated a bunch of strings. Here is a snippet from one of my projects (don't judge):

(defn upvote-comment [commentid]
  (javascript-response (str "var newEl = document.createElement('span');"
                            "newEl.innerText = 'Upvoted!';"
                            "var el = document.getElementById(\"" commentid "\").querySelector(\"a.upvote\");"
                            "if(el) el.replaceWith(newEl);"))

With wisp, this can (and should!) be rewritten like this:

(defn upvote-comment [cid]
  (javascript-reponse
    (wisp/compile [commentid cid]
        (let [new-el (document.createElement "span")
              el     (document.getElementById commentid)
              upvote (.querySelector el "a.upvote")]
          (if el
            (el.replaceWith new-el))))))

Which will result in JavaScript like this:

// (upvote-comment "my-comment-id")

(function () {
    var newElø1 = document.createElement('span');
    var elø1 = document.getElementById('my-comment-id');
    var upvoteø1 = elø1.querySelector('a.upvote');
    return elø1 ? elø1.replaceWith(newElø1) : void 0;
}.call(this));

As you can see, the symbols referenced in the initial binding vector get automatically evaluated and inserted into the expression. This way you can not only write your JavaScript with sweet, sweet parentheses, you will also get the sexps syntax-highlighted, and you don't have to mess around with string manipulation!

Advanced usage

To use the more advanced Wisp features, you'll need to include the runtime, the sequence and string libraries into the page. This should be possible by including the resources/wisp/{runtime,sequence,string}.js files into the page (in this order).

For caching reasons, you should probably just copy them into your public folder, but for convenience I am also exposing them as wisp-runtime, wisp-sequence, wisp-string, and altogether as wisp-includes functions that return these files as strings

Gotchas

The symbol of the resolution of the compile macro is dumb and will replace the given symbol with its value no matter where in the source code it is. So if you expect to be able to shadow bindings in a nested scope somewhere, it will most likely break. This is for short snippets, and you are very much responsible for reading them after compilation and making sure they work. Don't blame me if your code reaks!

Compiling wisp

In the resources/wisp directory, run make compiler to re-compile the wisp compiler

Copyright © 2018 Maximilian Gerlach

Distributed under the Eclipse Public License either version 1.0 or (at your option) any later version.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.