In the last two lessons we saw a few Clojure functions provided by "clojure.core" and "clojure.contrib" libraries. In this lesson we will roll out our own function in Clojure.
(use 'clojure.contrib.prxml)
(spit
"hello.html"
(with-out-str
(binding [*prxml-indent* 4]
(prxml
[:html
[:body
[:h1 "My Home Page"]]]))))
Type the above code into a file lesson3.clj and run it. By now you would have figured what the code does. It generates an html file called hello.html. Open the file in your browser. And view its source code in your browser. As you can see, each vector represents an XML element (in this case html element). A keyword element represents the tag name, and the second element represents the content of the parent element.
Now change the last line to read as follows
[:h1 {:style "color:red"} "My Home Page"]]]))))
Now run the program and reload hello.html in the browser and look at the source code. Here we have added an attribute to the h1 element. In prxml, element attributes are represented by maps. A map is a structure in which the keyword and value are wrapped in curly braces. You can have multiple keyword values in a map.
Let us add a content part to the page.
(use 'clojure.contrib.prxml)
(spit
"hello.html"
(with-out-str
(binding [*prxml-indent* 4]
(prxml
[:html
[:body
[:h1 {:style "color:red"} "My Home Page"]
[:div "This is the content of my page"]]]))))
Run the program and view source again, to make sure everything is as expected. Now let us say we want to generate more pages for our shiny new little website. Some parts of the page will remain consistent in all the pages we generate. The only parts that change will be the file name, title and content of each page. Right! So instead of copying the code for each page we can write a function to generate every page given the variable parameters for each page.
(use 'clojure.contrib.prxml)
(defn generate-page [filename title content]
(spit
filename
(with-out-str
(binding [*prxml-indent* 4]
(prxml
[:html
[:body
[:h1 {:style "color:red"} title]
[:div content]]])))))
(generate-page "about.html" "About Me page" "This content is about Me")
Now run this program, open "about.html" in your browser and view the source. Congratulations! You have done your first Clojure user defined function. You define functions in Clojure using defn. defn takes a function name, a set of params in a vector, and a function body as its arguments. defn also takes two more optional arguments doc-string? and attr-map?, which we will cover in another lesson. In the last line we called the generate-page function passing it the three required parameters.
These are good lessons in general, but they would benefit (a lot, IMO) from some syntax highlighting. Especially for someone new to Closer / Lisp dialects, with all the nesting brackets etc., a bit of colour would help understanding things quicker
ReplyDelete