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 hash
Several 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
&lt;h1&gt;Hello, <cl>show name</cl>!&lt;/h1&gt;
Show code instead of running it
&lt;cl-code&gt;show "shown, not run"&lt;/cl-code&gt;

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.