{"id":19261914,"url":"https://github.com/hacksu/flask-guestbook","last_synced_at":"2026-02-16T01:05:58.847Z","repository":{"id":234860799,"uuid":"789272805","full_name":"hacksu/flask-guestbook","owner":"hacksu","description":"Something silly I whipped up as a KHE workshop","archived":false,"fork":false,"pushed_at":"2024-04-20T05:09:22.000Z","size":2,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-01-05T10:12:18.611Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"HTML","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hacksu.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-04-20T05:07:09.000Z","updated_at":"2024-04-21T05:06:19.000Z","dependencies_parsed_at":null,"dependency_job_id":"9cd882ea-7688-48ca-822d-222173a5a1c5","html_url":"https://github.com/hacksu/flask-guestbook","commit_stats":null,"previous_names":["hacksu/flask-guestbook"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hacksu%2Fflask-guestbook","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hacksu%2Fflask-guestbook/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hacksu%2Fflask-guestbook/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hacksu%2Fflask-guestbook/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hacksu","download_url":"https://codeload.github.com/hacksu/flask-guestbook/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240364294,"owners_count":19789756,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-09T19:28:56.908Z","updated_at":"2025-09-29T07:08:22.045Z","avatar_url":"https://github.com/hacksu.png","language":"HTML","funding_links":[],"categories":[],"sub_categories":[],"readme":"# flask-guestbook\n\nThere is an excellent [HacKSU lesson](https://github.com/hacksu/express-guestbook) that I basically re-implemented in Flask for this workshop.\n\n### What is this?\n\nI wanted to give a simple example in Flask of how you would pass data to the backend with a form...... so let's do that.\n\n### HTML\n\nLet's start with the HTML. We need to be able to take some input from the user and send that to the backend. The best way to do this in HTML5 is with forms.\n\nFirst, we create a `templates/` folder in the root directory of our project. This is where all of our HTML will go (this is where Flask will recognize it).\n\nI made `book.html`, which looks like this:\n\n```HTML\n\u003c!-- Explain this code --\u003e\n\u003c!doctype html\u003e\n\u003ctitle\u003eGuestbook\u003c/title\u003e\n\n\u003ch1\u003eWelcome to the epic Guestbook!\u003c/h1\u003e\n\n\u003cform method=\"post\"\u003e\n  \u003cinput type=\"text\" placeholder=\"write a message...\" name=\"entryText\" /\u003e\n  \u003cbutton type=\"submit\"\u003eAdd Guestbook Entry\u003c/button\u003e\n\u003c/form\u003e\n```\n\n\nThat's wonderful. That's all the HTML we're going to need for now.\n\n### Flask\n\nFlask requires a little bit of boilerplate and by a little bit, I mean relatively none compared to other frameworks.\n\n```Python\n# Explain this code\nfrom flask import Flask, render_template\n\napp = Flask(__name__)\n\n@app.route(\"/\")\ndef home():\n    return render_template(\"book.html\", entries=entries)\n```\n\nWow. Wonderful. 6 lines of beautiful Python and it just.. works.\nIf we run the `flask --app app run` command, we get a \"nice\" result.\n\n### Let's go crazy\n\nNow, we need to make it interactive. Currently if we type some text in the input box and click submit, it does absolutely nothing.\n\nWe need to update our Flask code with a new couple more lines:\n```Python\n# Explain changes\nfrom flask import Flask, render_template, request, redirect, url_for\n\napp = Flask(__name__)\n\n@app.route(\"/\")\ndef home():\n    return render_template(\"book.html\", entries=entries)\n\nentries = []\n\n@app.route(\"/add\", methods=[\"POST\"])\ndef add_entry():\n    entries.append(request.form[\"entryText\"])\n    return redirect(url_for('home'))\n```\n\nWe also have to update our HTML:\n```HTML\n\u003c!-- Explain this new HTML --\u003e\n\u003c!doctype html\u003e\n\u003ctitle\u003eGuestbook\u003c/title\u003e\n\n\u003ch1\u003eWelcome to the epic Guestbook!\u003c/h1\u003e\n\n\u003cp\u003ePrevious entries:\u003c/p\u003e\n\u003cdiv\u003e\n  {% for entry in entries %}\n    \u003cp\u003e{{ entry }}\u003c/p\u003e\n  {% endfor %}\n\u003c/div\u003e\n\n\u003cform method=\"post\" action=\"/add\"\u003e\n  \u003cinput type=\"text\" placeholder=\"write a message...\" name=\"entryText\" /\u003e\n  \u003cbutton type=\"submit\"\u003eAdd Guestbook Entry\u003c/button\u003e\n\u003c/form\u003e\n```\n\nNow if we type in the box and click the add button, we should see the entry appear on the page.\n\n### Where to go from here?\n\nWell currently, if one user adds something to the page and the other user's don't refresh,\nthey won't see the changes.\n\nWhy don't we fix this problem? Let's change up how our endpoint works:\n```Python\nfrom flask import Flask, render_template, request, redirect, url_for\nfrom markupsafe import Markup\n\napp = Flask(__name__)\nentries = []\n\n@app.route(\"/\")\ndef home():\n    return render_template(\"book.html\", entries=entries)\n\n@app.route(\"/add\", methods=[\"POST\"])\ndef add_entry():\n    entries.append(request.form[\"entryText\"])\n    return redirect(url_for('home'))\n\n# Explain what we are doing here\n@app.route(\"/entries\")\ndef get_all_entries():\n    return [Markup.escape(x) for x in entries]\n```\n\nAnd then let's add some JavaScript to our template:\n```HTML\n\n\u003c!doctype html\u003e\n\u003ctitle\u003eGuestbook\u003c/title\u003e\n\n\u003ch1\u003eWelcome to the epic Guestbook!\u003c/h1\u003e\n\n\u003cp\u003ePrevious entries:\u003c/p\u003e\n\u003cdiv id=\"entries\"\u003e\n\u003c/div\u003e\n\n\u003cform method=\"post\" action=\"/add\"\u003e\n  \u003cinput type=\"text\" placeholder=\"write a message...\" name=\"entryText\" /\u003e\n  \u003cbutton type=\"submit\"\u003eAdd Guestbook Entry\u003c/button\u003e\n\u003c/form\u003e\n\n\u003c!-- REALLY EXPLAIN THIS --\u003e\n\u003cscript\u003e\nconst entries = document.getElementById(\"entries\");\n\nfunction update() {\n\n  for (const child of entries.children) {\n    entries.innerHTML = '';\n  }\n\n  (async () =\u003e {\n    const response = await fetch(\"/entries\").then(x =\u003e x.json()).catch(_ =\u003e null);\n    if (response) {\n      for (const entry of response) {\n        const element = document.createElement(\"p\");\n        element.innerHTML = entry;\n        entries.appendChild(element);\n      }\n    }\n  })();\n\n}\n\nsetInterval(update, 5000);\nupdate();\n\n\u003c/script\u003e\n```\n\nAnd there we go, if we spin up multiple sessions, we can see the page is correctly updating on both pages.\n\n### That's really ugly\n\nYeah. I know it is. This is why we use frameworks like React or Vue to manage our page state instead of doing it by ourselves with raw JavaScript. While it is possible, it is unpleasant to do along with the added fact that my version above adds some page flicker.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhacksu%2Fflask-guestbook","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhacksu%2Fflask-guestbook","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhacksu%2Fflask-guestbook/lists"}