Skip to content

Tutorial 0.4 The Welcome Page

macourtney edited this page Sep 13, 2010 · 4 revisions

Start the server again and, in a browser, connect to http://localhost:8080/. The page you see is the Conjure welcome page.

To edit the contents of the welcome page, open the index.clj file in the app/views/home directory in your hello_world project.

Since this is a hello world app, let’s change page to say “Hello World!”. To add “Hello World!”, change the line:

[:p "This file, index.clj, can be found in app/views/home directory of your conjure project."]
to
[:p "Hello World!"]

Then, refresh your web browser and you should see “Hello World!” under the “Welcome to Conjure!” heading.

Note: Conjure loads views dynamically. If you change a view, you don’t have to restart the server to see the changes.

MVC

The file we changed is called a view and is called by your code to create the html for a given page. “How can that be? I didn’t write any code to call the view.” you say. The short answer is, Conjure wrote the code for you. The long answer will require an understanding of the model view controller pattern used by Conjure.

Conjure is a web framework which uses, among other things, the Model-View-Controller design pattern to organize code in the projects it creates. However, Conjure adds one more layer to the MVC pattern. That layer is the Binding layer.

From a high level view of Conjure, when a request comes in from a browser, Conjure passes the request to the associated controller. The controller determines if the request needs to be rerouted or if a model needs updating. Once done, the controller passes the request plus any other needed information on to a binding. The binding pulls data from one or more models, and passes the data to a view. The view renders the page, and returns the result back through the binding and controller to Conjure. Conjure then returns the result as a response to the browser.

Conjure → controller action → binding → model functions → view → Conjure

Conjure determines what controller and action to call based on the incoming request. Usually, the first part of the path is the name of the controller, the second is the name of the action and the third optional part is an ID for a record.

http://myapp.com/[controller]/[action]/[id]?[params]

If the id is not given it is ignored. However, if an action is not given, Conjure defaults to the action name “index”. If the controller is not given, Conjure defaults to the controller name “home”. You can change the defaults or completely change the way Conjure routes requests, but that is outside the scope of this tutorial.

When you create a brand new Conjure project, a home controller with an index action is created for you in the app/controllers directory.

The home controller, home.clj looks something like:

(ns controllers.home-controller
  (:use [conjure.controller.base
         helpers.home-helper]))

(defaction index
  (bind request-map))

(defaction list-records
  (redirect-to request-map { :action "index" }))

(defaction add
  (redirect-to request-map { :action "index" }))

(defaction error-404
  (bind request-map))

The above controller has 4 actions, index, list-records, add and error-404. The list-records and add actions simply redirect to the index action. The index and error-404 actions simply call their associated bindings.

The call to bind uses the request-map to call the appropriate binding. The binding it calls comes from the action and controller referenced in the request-map, which, in this case, is the same as the one used to find the name of the controller and action to call.

The error-404 action is a special action called when Conjure cannot find a corresponding controller and/or action for the request.

A corresponding binding by the name ‘index.clj’ is created in the app/bindings/home directory. The index binding looks like:

(ns bindings.home.index
  (:use conjure.binding.base
        helpers.home-helper))

(defbinding [request-map]
  (render-view (home-request-map request-map)))

The binding doesn’t do much but update the request-map to add some special “home” data and pass the resulting request-map to render-view. Render-view then calls the associated view using the controller and action from the request-map. Since the controller and view are the same as the request-map used to call this binding, the view rendered is called “index.clj” and can be found in the “views/home” directory.

You’ve already seen the view. It’s the file you updated to add “Hello World!” earlier in this tutorial. The full file should look like this:

(ns views.home.index
  (:use conjure.view.base)
  (:require [clj-html.core :as html]))

(defview []
  (html/html 
    [:div { :class "article" }
      [:h1 "Welcome to Conjure!"]
      [:p "Hello World!"]]))

The file defines a view with the defview macro. The view has no parameters and returns the result of calling the function html in clj-html.core. The library clj-html allows you to describe html code using Clojure data structures.

In the next tutorial we’ll learn how to pass parameters around your Conjure app.

PreviousTutorial IndexNext

Clone this wiki locally