Todo Junto
Construyamos un gestor de marcadores — añade URLs con un título y véalos listados. Este tutorial une todo de esta pista: configuración del servidor, lecturas y escrituras en base de datos, formularios, componentes y listado de registros. Suficientemente pequeño para entender completamente, suficientemente real para ser útil.
El archivo servidor declara plugins, importa helpers y lista todas las rutas:
plugins:\n frame.server\n frame.data\n\nimport:\n "helpers.cln"\n\nendpoints server:\n GET "/" :\n return http.respond(200, "text/html", render_home())\n\n GET "/add" :\n return http.respond(200, "text/html", render_add_form())\n\n POST "/add" :\n string title = req.body("title")\n string url = req.body("url")\n if title == "" or url == ""\n return http.respond(400, "text/html", render_add_form())\n string params = "[\\"" + title + "\\", \\"" + url + "\\"]"\n db.query("INSERT INTO bookmarks (title, url) VALUES (?, ?)", params)\n return http.respond(200, "text/html", render_home())GET / → bookmarks list page\nGET /add → add bookmark form\nPOST /add → save and show updated listEl archivo servidor es liviano — solo rutas. Tres rutas cubren el ciclo completo: listar, mostrar formulario, guardar. Valida antes de insertar y devuelve el formulario con 400 en caso de error. Delega el renderizado a helpers.cln para mantener el archivo servidor legible.
La función render_home() en helpers.cln obtiene y muestra todos los marcadores:
functions:\n string bookmark_item(string title, string url)\n html:\n \n {title}\n \n\n string render_home()\n string cnt_res = db.query("SELECT CAST(COUNT(*) AS CHAR) as cnt FROM bookmarks", "[]")\n integer count = json.get(cnt_res, "data.rows.0.cnt").toInteger()\n string bm_res = db.query("SELECT title, url FROM bookmarks ORDER BY id DESC", "[]")\n string items = ""\n iterate i in 0 to count - 1\n string t = json.get(bm_res, "data.rows." + i.toString() + ".title")\n string u = json.get(bm_res, "data.rows." + i.toString() + ".url")\n items = items + bookmark_item(t, u)\n html:\n \n My Bookmarks
\n + Add Bookmark\n {!items}
\n Renders a page with all saved bookmarks as clickable linksrender_home() aplica el patrón de listado del tutorial anterior: contar, obtener, iterar, renderizar. El componente bookmark_item se llama una vez por fila. Separación de responsabilidades: server.cln maneja el enrutamiento, helpers.cln maneja el renderizado.
Resumen rápido
- Mantén server.cln ligero — solo rutas, delega el renderizado a helpers.cln
- Tres rutas cubren una característica completa: listar, mostrar formulario, guardar
- Valida la entrada del formulario antes de insertar — devuelve el formulario con 400 en caso de error
- Los mismos patrones se repiten en cada aplicación: consultar, contar, iterar, renderizar