Flash cards
Read the question, say the answer out loud, click to check. 84 cards cover the whole language, starting with when to use quotes.
0. Quotes or not?
When do I use quotes?
# text in quotes, names bare set city to "Paris" show city
Does a number need quotes?
# no. "30" would be text set age to 30 show "[age + 1]"
Do yes and no need quotes?
# no. They are values, not text set published to yes if published
Why did it print Hello, city?
# a name inside quotes is just letters. # Put it in brackets show "Hello, [city]"
Can brackets go outside quotes?
# no. Outside quotes, write the name show city show "[city]"
How do I show a real quote or bracket?
show "She said \"hi\"" show "Press \[Enter]"
Does the key after query and form need quotes?
# yes, it is text set id to query "id" set name to form "name"
Column after of: quotes or not?
# a column is a name, so bare show price of lamp # the same, if you prefer show item "price" of lamp
In ask database, what is quoted?
# the SQL is text. The values after with are names ask database "select * from posts where slug = ?" with slug
1. Showing and remembering
Show a value on the page
show "Hello, world!"
Remember a value
set planet to "Earth" set moons to 1
Put a value inside text
show "Welcome to [planet], home of [moons] moon."
Math inside text
show "Half price: $[price / 2]"
Show HTML you wrote, unescaped
show raw "<b>bold</b>" # plain show already keeps your own HTML; raw is for visitor text
Leave a note for yourself
# comments start with a hashSeveral lines of HTML, no quotes
show <div class="card"> <h5>[title]</h5> </div> end
Write it like a sentence
set total to the count of fruits. show "[total] fruits".
2. Deciding
Do something only if
if age is at least 18 show "Welcome" end
Either this or that
if score is more than 50 show "Pass" otherwise show "Try again" end
Three or more cases
if size is "small" show "S" otherwise if size is "medium" show "M" otherwise show "L" end
All the comparisons
is is not is more than is less than is at least is at most is between 1 and 10 is empty is not empty
Combine conditions
if name is not empty and age is more than 12 if paid or member if not done
The two answers
set done to yes set paid to no
3. Lists and loops
Make a list
set fruits to "apple", "banana", "cherry"
Start with nothing, then add
set names to empty list add "Ada" to names
How many, first, last, by position
count of fruits first of fruits last of fruits item 2 of fruits
Do something for every item
for each fruit in fruits show "<li>[fruit]</li>" end
Do something N times
repeat 5 times show "★" end
Count as you go
set position to 0 for each name in names set position to position + 1 show "[position]. [name]" end
4. Text
Capitals, small letters, no edge spaces
uppercase of name lowercase of name trim of name
Cut text into pieces
set parts to split path by "/" show "[last of parts]"
Swap one thing for another
set slug to replace " " with "-" in lowercase of title
Text into paragraphs
for each paragraph in paragraphs of body show "<p>[paragraph]</p>" end
Text into a number
set page to number of query "page" show "[page * 10]"
A quote or bracket inside text
show "She said \"hi\" and \[this] is not a hole"
5. The visitor
Something from the URL, ?name=Ada
set name to query "name"
Something from a submitted form
set message to trim of form "message"
A default when nothing was given
set name to query "name" if name is empty set name to "friend" end
Which page is this
show path # /blog/hello-world
Send the visitor somewhere else
go to "/thanks"
Today's date and the time
show "[today]" show "[now]"
6. Pages
Share a header or footer
include "header.html"
A value in the middle of HTML
<h1>Hello, <cl>show name</cl>!</h1>
Show code instead of running it
<cl-code>show "shown, not run"</cl-code>
7. The database
Open it
open database "site.db"
Read rows
set posts to ask database "select * from posts order by posted desc"
Read rows safely with a visitor's value
set posts to ask database "select * from posts where slug = ?" with slug
One column of one row
set post to first of posts show "[title of post]"
Write a row
tell database "insert into guestbook (name, message, posted) values (?, ?, ?)" with name, message, now
The guestbook in five lines
set name to trim of form "name" if name is not empty tell database "insert into guestbook (name, posted) values (?, ?)" with name, now go to "/guestbook?thanks=yes" end
8. Visitors who sign in
Keep something for this visitor
remember "user" as name
Read it back later
show "Signed in as [remembered "user"]"
Sign out
forget everything
Store a password safely
tell database "insert into users (name, password) values (?, ?)" with name, hash of form "password"
Check a typed password
if form "password" matches password of first of users remember "user" as name end
A page only for signed-in people
if remembered "user" is empty go to "/login" end
8b. Email
Email yourself a message from a form
send email to "you@example.com" subject: "Message from [name]" reply to: email from: "website@example.com" body: message end
Check a visitor typed a real email address
if form "email" is not an email set problem to "Please check your email." end
Can a visitor choose who gets the email?
# No. send email to refuses a visitor's value. # Their address goes in reply to: instead.
9. More text and dates
The first 100 letters
show "[first 100 of body]…"
Is a piece inside?
if email contains "@" if tags contains "new"
In order, or backwards
sort of names reverse of posts
A date written out
show "[date of today]" # 24 October 2026
Parts of a date
year of today month of today day of today
Last three in a list
for each post in last 3 of posts show "[title of post]" end
10. Your own words
Define a command of your own
to greet someone show "<p>Hello, [someone]!</p>" end greet "Ada"
A verb that gives a value back
to slug_of heading give replace " " with "-" in lowercase of heading end show "[slug_of title]"
Make a record of your own
set lamp to record name: "Desk lamp" price: 19 end show "[name of lamp]"
Change one column
set price of lamp to 15
Repeat until something is true
repeat 100 times until done … end
Share verbs across pages
# in verbs.html, then on every page: include "verbs.html"
11. Things to unlearn
How do I join text with +?
# you don't. Put the value in brackets show "Hello, [name]!"
Where is else? print? ==? >?
otherwise show is is more than
Do I need to escape visitor text?
# no. query, form and database text are made safe show "<p>[message]</p>"
12. Gotchas
I wrote if and nothing ran. Why?
# every block needs an end line if age is at least 18 show "Welcome" end
Where is =?
# nowhere. to stores, is compares set total to 10 if total is 10
Why does "1" + 2 fail?
# + is for numbers only show "[number of "1" + 2]" # to join text, use brackets
Why does Show fail but show works?
# Common words are always lowercase show "hi"
Why can't I call something open or page?
# a few words belong to Common. Prefix yours set my_page to 1 set open_hours to 9
Does the matter?
# no. the is silent, write it or not set the price to 5 set price to 5
The visitor left a field blank. What do I get?
# empty text, never an error if form "name" is empty show "Please tell us your name." end
What does count of count?
# letters of text, items of a list count of "hello" # 5 count of fruits # how many fruits
Why is my list never equal to one item?
# a list is many things. Ask if it holds one set status to "Working", "At Desk" if status contains "At Desk"
Is one line one command?
# yes. A full stop at the end is fine set city to "Paris". show city
Every word on these cards is explained in the wiki and in docs/dictionary.md, and cl words prints the list. If a card's answer surprises you, the errors page shows what Common says when you guess wrong.