Build a guestbook in ten minutes

One page, five steps. By the end, visitors can sign a book and their entries are saved. It is the core of the guestbook demo, which adds a length check and shows the newest 50 entries.

Before you start: three habits

Almost every mistake a beginner makes is one of these. Read them once and the steps below will make sense.

  1. Text goes in quotes, names do not. set city to "Paris" stores text in a name. show city shows it. To put a name inside text, use brackets: show "Hello, [city]". Numbers and yes/no never take quotes.
  2. Blocks end with end. Anything that owns lines (if, for each, repeat, to, a bare show) runs until a line that says end. Forget it and Common tells you which block is open.
  3. to stores, is compares. There is no =. set total to 10 then if total is 10. For text joining there is no + either; + is for numbers.
set city to "Paris"
set visitors to 3
if visitors is more than 2
  show "Hello from [city], visitor number [visitors + 1]!"
end

Step 1. A page with a form

A Common page is an HTML file. Make guestbook.html with a form that posts back to itself. The hidden sent field tells us the form was submitted, not merely shown.

<form method="post" action="/guestbook">
  <input type="hidden" name="sent" value="yes">
  <input name="name" placeholder="Your name">
  <input name="message" placeholder="Say something">
  <button>Sign the book</button>
</form>

Step 2. Read what was typed

At the top of the page, read the two fields. form gives you what the visitor typed, and trim of drops stray spaces.

<cl>
  set name to trim of form "name"
  set message to trim of form "message"
</cl>

Step 3. Check it

Only do anything when the form was actually sent, and only accept entries that make sense. Notice the shape: if, otherwise if, otherwise, end.

set problem to ""
if form "sent" is "yes"
  if name is empty
    set problem to "Please tell us your name."
  otherwise if count of message is less than 3
    set problem to "Say a little more than that."
  end
end

Step 4. Save it, then move on

Make a database once, with the sqlite3 command, next to your page:

sqlite3 site.db "create table guestbook (id integer primary key, name text, message text, posted text)"

Then, when there is no problem, write one row and send the visitor back to the page. The go to matters: it means a refresh will not sign the book twice.

open database "site.db"
if form "sent" is "yes" and problem is empty
  tell database "insert into guestbook (name, message, posted) values (?, ?, ?)" with name, message, now
  go to "/guestbook?thanks=yes"
end

Each ? takes the next value after with. The values never touch the SQL, so a visitor cannot break it, whatever they type.

Step 5. Show the book

Ask for the rows, newest first, and show each one. Text from the database is made safe before it is shown, so you never think about it.

set entries to ask database "select name, message, posted from guestbook order by id desc"
show "<h2>[count of entries] entries</h2>"
for each entry in entries
  show "<p><strong>[name of entry]</strong> <small>[posted of entry]</small><br>[message of entry]</p>"
end

The whole page

Put together, with a thank-you line and the problem shown when there is one. Twenty-five lines of Common.

<cl>
  open database "site.db"
  set name to trim of form "name"
  set message to trim of form "message"
  set problem to ""

  if form "sent" is "yes"
    if name is empty
      set problem to "Please tell us your name."
    otherwise if count of message is less than 3
      set problem to "Say a little more than that."
    otherwise
      tell database "insert into guestbook (name, message, posted) values (?, ?, ?)" with name, message, now
      go to "/guestbook?thanks=yes"
    end
  end

  set entries to ask database "select name, message, posted from guestbook order by id desc"
</cl>

<h1>Guestbook</h1>
<cl>
  if query "thanks" is "yes"
    show "<p>Thanks for signing!</p>"
  end
  if problem is not empty
    show "<p style='color:red'>[problem]</p>"
  end
</cl>

<form method="post" action="/guestbook">
  <input type="hidden" name="sent" value="yes">
  <input name="name" placeholder="Your name">
  <input name="message" placeholder="Say something">
  <button>Sign the book</button>
</form>

<cl>
  show "<h2>[count of entries] entries</h2>"
  for each entry in entries
    show "<p><strong>[name of entry]</strong> <small>[posted of entry]</small><br>[message of entry]</p>"
  end
</cl>

Run it

cl serve 8000

Open localhost:8000/guestbook. Sign it. Refresh. It stays. That is a working website.

If it does not run

Common stops at the first line it cannot follow and says what it expected. The usual suspects, in order:

Every one of these has its own card in the flash cards (sections 0 and 12) and a worked example on the errors page.

Words used: set, form, trim of, if, count of, open database, tell database, go to, ask database, for each, show, brackets. Every one of them is on the cards.