What You’ll Build
A fully functional todo application with:- List view showing all todos
- Add new todo items
- Edit existing todos
- Delete todos with confirmation
- Consistent layout across all pages
Database Setup
First, create the database schema. SQLPage uses migrations stored insqlpage/migrations/ to set up your database automatically.
sqlpage/migrations/0000_init.sql
Creating the Shell Layout
Create a reusable shell component that provides consistent navigation across all pages.shell.sql
- Uses the shell component to create the page header
- Dynamically shows the count of todos in the title
- Adds a menu item linking to the timeline view
Building the Main Page
Load the Shell
Use the dynamic component to include the shell on every page:
Display the Todo List
Use the list component to show all todos:
index.sql
Creating the Todo Form
The form handles both creating new todos and editing existing ones.todo_form.sql
How It Works
Order of Operations
Order of Operations
- Insert/Update Query Runs First: When the form is submitted,
:todois not null, so the insert executes and returns a redirect - Redirect Happens: If a row is returned, SQLPage redirects immediately and stops processing
- Form Displays: If
:todois null (initial page load), nothing is inserted, no redirect occurs, and the form displays
URL Parameters vs Form Data
URL Parameters vs Form Data
$todo_id: URL parameter (e.g.,?todo_id=5) - prefixed with$:todo: Form POST data - prefixed with:- When editing,
$todo_idretrieves the existing todo’s data - When creating,
$todo_idis null, so a new record is inserted
Implementing Delete with Confirmation
The delete functionality uses a two-step process for safety.delete.sql
Delete Flow
Show Confirmation
$confirmis null (not in URL yet)- Delete query runs but WHERE condition is false, nothing deleted
- Alert component displays confirmation message
Project Structure
Key Concepts
Component Chaining
Each SELECT statement renders a component. Chain multiple components by using multiple SELECT statements in sequence.
URL Parameters
Access URL query parameters with
$ prefix (e.g., $todo_id for ?todo_id=5)Form Data
Access POST form data with
: prefix (e.g., :todo for a field named “todo”)RETURNING Clause
Use RETURNING to render components from INSERT/UPDATE/DELETE queries, enabling immediate redirects after mutations
Running the Example
Download SQLPage
Get the latest release from GitHub
Next Steps
Add User Authentication
Learn how to add login and signup to your app
CRUD Operations
Explore more complex CRUD patterns
Components Reference
Browse all available SQLPage components
Functions Reference
Explore SQLPage built-in functions