Skip to content

Cookbook ​

Short recipes for one task each. Every recipe is a small app in examples/cookbook/ with its own quantum test suite: the code on its page is imported from the tested files, and what it shows as a result was produced by running it.

Basics ​

  • A first page, and a second — Each file in components/ is a page at its own URL; a URL with no file is 404.
  • Variables and expressions — q:set stores a value, braces compute with it, and default fills in what is missing.
  • Loops — q:loop over a list (with its position), a range of numbers and comma-separated text.
  • Conditionals — q:if, q:elseif and q:else, with conditions that are expressions.
  • Functions — A q:function with typed, checked params, called from q:set and from the HTML.
  • A page per URL — components/product/[id].q answers /product/1, /product/2...; the segment is a variable.
  • Read the query string — query.name reads ?name= from the address; default covers a missing one; urlencode builds a link.
  • Reusable components — A component with props and a slot, imported from a _ folder that is never served.

Screens ​

  • A layout that fits the screen — ui:hbox side by side on a wide screen, stacked on a narrow one, with grow, width and hide-below.
  • A table you edit in place — ui:table edit= turns each cell into a small form checked against the table's schema; no action to write.
  • Tabs — ui:tabpanel with one ui:tab per section of a page.
  • Cards — ui:card with a header, a body and a footer, in a ui:grid; or a card with just a title.
  • Every kind of field — ui:form with ui:formitem labels: text, number, a select with options, a switch, radios and a multi-line field.
  • The same page in a terminal — One ui:* page, served to the browser by quantum start and drawn in a terminal by quantum console.

Testing the app ​

Files & mail ​

  • Mail in development — Send mail from an action without a mail server while you develop — host: log writes each message to the log.
  • When the mail server says no — Keep an order even when its confirmation e-mail cannot be sent — onerror=continue, and tell the visitor.

Login & permissions ​

  • Log in with a hashed password — Check a password against its bcrypt hash with verifyPassword, open the session, and keep a page for signed-in users.
  • Sign up and store a password hash — Create an account with hashPassword, so the database never holds the password, with rules on each field.
  • A page for one role only — require_role keeps a page to the admins: a member gets 403, and a visitor who is not signed in is sent to sign in.
  • A guard that redirects — A top-level q:if with q:redirect protects a page and every action on it: a post without a session writes nothing.
  • Sign out — A logout page that clears the session and redirects; the protected pages are closed again.

Forms & actions ​

  • Show each error on its field — Write the rules once on the action's q:param; the form reads them and shows every refusal next to its field.
  • A refused form keeps what was typed — After a refusal, the form comes back filled with the values sent, once, so nobody types a long message twice.
  • Redirect and say what happened — End an action with q:redirect and a flash; q:flash for a warning; the message shows once on the next page.
  • Several forms on one page — Each form and button posts the name of its action; a name the page does not have answers 400.
  • A form from the table — q:action table= takes its params from the schema; a ui:form with no fields draws one field per column.
  • Edit a row — A page per row with [id].q, a form opened with the row's values, and the table's rules on save.
  • Confirm before deleting — A page that asks first, reached by a link, and the delete as a POST from its button; no JavaScript.
  • Numbers and dates — type=integer, decimal and date on q:param: the action gets checked numbers and real dates, with min and max.
  • A choice from a list — enum on q:param gives ui:select and ui:radio their options and refuses anything else; a box is a boolean.

Data & SQL ​

  • A query with parameters — Filter by a value from the URL, bound as a q:param — the value never becomes SQL.
  • A paginated list — One page of a long list at a time, with ui:pager drawing the links to the others.
  • Search as you type — A field that refreshes the results after each pause in typing — the page's own query does the search.
  • Filter and sort a table — Links that filter the rows and headers that sort them — both in SQL, both in the URL.
  • Writes that happen together — A q:transaction: the debit, the credit and the log line commit together, or none of them does.
  • Change history — history: true records who changed which row, and how; ui:history shows it on the page.
  • Add a column with a migration — Change the schema with a new migration file; the old one stays as it was.
  • Read a CSV file — q:data turns a CSV file into typed records, filtered and sorted — no database needed.
  • Load a CSV file into a table — Insert every row of a file in one transaction — a row that fails leaves nothing behind.
  • Read a JSON file — A JSON array as a list of records, with a computed field on each.
  • Totals from one query — SQL over a query's result, in memory — the database is asked once.

AI ​

  • Answers with their sources — Answer questions from your own documents with q:knowledge and q:llm knowledge=, and list the sources.
  • When the documents do not know — minRelevance keeps unrelated chunks out; with nothing left, the model is not asked and the page says so.
  • Stream an answer — A streamed q:llm and ui:stream: the page renders at once, the answer appears as it is written.
  • An agent over your database — q:agent with a read-only query tool: the model picks the tool and its arguments, never the SQL.
  • When the model fails — onerror on q:llm: a model that is down or too slow does not take the page down with it.
  • Sort messages with JSON answers — responseFormat json: the model's answer is an object whose fields you check and store.
  • Answers from a table — A q:knowledge source that is a query: the rows of your FAQ table, retrieved like documents.

MIT Licensed · Built with VitePress