{"html_url": "https://github.com/simonw/datasette/issues/577#issuecomment-568276310", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/577", "id": 568276310, "node_id": "MDEyOklzc3VlQ29tbWVudDU2ODI3NjMxMA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2019-12-22T16:10:31Z", "updated_at": "2019-12-22T16:10:31Z", "author_association": "OWNER", "body": "The code in question currently lives in `BaseView.render()`:\r\n\r\nhttps://github.com/simonw/datasette/blob/d54318fc7f2565e6121920ce1ea9cb8b700e629a/datasette/views/base.py#L106-L163\r\n\r\nShould `datasette.render_template()` do exactly this, or should it be slightly different?\r\n\r\nPlugins need the option to not pass a `request` object - so maybe that parameter becomes optional.\r\n\r\nPerhaps plugins should be able to render templates without other plugins getting to inject their own variables?\r\n\r\nDoes it always make sense to dump in all of those extra template context variables?", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 497171390, "label": "Utility mechanism for plugins to render templates"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/651#issuecomment-568268746", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/651", "id": 568268746, "node_id": "MDEyOklzc3VlQ29tbWVudDU2ODI2ODc0Ng==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2019-12-22T14:37:37Z", "updated_at": "2019-12-22T14:37:37Z", "author_association": "OWNER", "body": "I've not yet been able to figure out what the escaping rule are for FTS5 queries.\r\n\r\nIf we figure out how those work maybe we can bundle them as a custom function?\r\n\r\n select ... where docs_fts match fts_escape(:search)\r\n", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 539590148, "label": "fts5 syntax error when using punctuation"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/651#issuecomment-568269476", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/651", "id": 568269476, "node_id": "MDEyOklzc3VlQ29tbWVudDU2ODI2OTQ3Ng==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2019-12-22T14:46:37Z", "updated_at": "2019-12-22T14:47:03Z", "author_association": "OWNER", "body": "https://stackoverflow.com/a/43756146 says that an escaping mechanism that works is this one:\r\n\r\n select * from blah where term match '\"bacon\" \"and\" \"eggs\"'\r\n\r\nSo split on whitespace and then encapsulate each search term in double quotes.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 539590148, "label": "fts5 syntax error when using punctuation"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/654#issuecomment-568274520", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/654", "id": 568274520, "node_id": "MDEyOklzc3VlQ29tbWVudDU2ODI3NDUyMA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2019-12-22T15:51:58Z", "updated_at": "2019-12-22T15:51:58Z", "author_association": "OWNER", "body": "Proof of concept:\r\n```diff\r\ndiff --git a/datasette/views/base.py b/datasette/views/base.py\r\nindex 5182479..39d1f77 100644\r\n--- a/datasette/views/base.py\r\n+++ b/datasette/views/base.py\r\n@@ -1,6 +1,7 @@\r\n import asyncio\r\n import csv\r\n import itertools\r\n+import json\r\n import re\r\n import time\r\n import urllib\r\n@@ -138,28 +139,31 @@ class BaseView(AsgiView):\r\n )\r\n extra_template_vars.update(extra_vars)\r\n \r\n+ template_context = {\r\n+ **context,\r\n+ **{\r\n+ \"app_css_hash\": self.ds.app_css_hash(),\r\n+ \"select_templates\": select_templates,\r\n+ \"zip\": zip,\r\n+ \"body_scripts\": body_scripts,\r\n+ \"extra_css_urls\": self._asset_urls(\r\n+ \"extra_css_urls\", template, context\r\n+ ),\r\n+ \"extra_js_urls\": self._asset_urls(\r\n+ \"extra_js_urls\", template, context\r\n+ ),\r\n+ \"format_bytes\": format_bytes,\r\n+ \"database_url\": self.database_url,\r\n+ \"database_color\": self.database_color,\r\n+ },\r\n+ **extra_template_vars,\r\n+ }\r\n+ if request.args.get(\"_context\"):\r\n+ return Response.html(\"
{}
\".format(\r\n+ escape(json.dumps(template_context, default=repr, indent=4))\r\n+ ))\r\n return Response.html(\r\n- await template.render_async(\r\n- {\r\n- **context,\r\n- **{\r\n- \"app_css_hash\": self.ds.app_css_hash(),\r\n- \"select_templates\": select_templates,\r\n- \"zip\": zip,\r\n- \"body_scripts\": body_scripts,\r\n- \"extra_css_urls\": self._asset_urls(\r\n- \"extra_css_urls\", template, context\r\n- ),\r\n- \"extra_js_urls\": self._asset_urls(\r\n- \"extra_js_urls\", template, context\r\n- ),\r\n- \"format_bytes\": format_bytes,\r\n- \"database_url\": self.database_url,\r\n- \"database_color\": self.database_color,\r\n- },\r\n- **extra_template_vars,\r\n- }\r\n- )\r\n+ await template.render_async(template_context)\r\n )\r\n ```", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 541467590, "label": "Template debug mode that outputs template context"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/654#issuecomment-568274570", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/654", "id": 568274570, "node_id": "MDEyOklzc3VlQ29tbWVudDU2ODI3NDU3MA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2019-12-22T15:52:43Z", "updated_at": "2019-12-22T15:52:43Z", "author_association": "OWNER", "body": "One problem with this: what if secrets end up being dumped out in this debug view?\r\n\r\nThis won't happen with default Datasette but could potentially happen with a plugin.\r\n\r\nThis feature should be opt-in - maybe a `template_debug:1` config setting.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 541467590, "label": "Template debug mode that outputs template context"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/654#issuecomment-568276548", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/654", "id": 568276548, "node_id": "MDEyOklzc3VlQ29tbWVudDU2ODI3NjU0OA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2019-12-22T16:13:11Z", "updated_at": "2019-12-22T16:13:11Z", "author_association": "OWNER", "body": "Documentation: https://datasette.readthedocs.io/en/latest/config.html#template-debug\r\n\r\nDemos:\r\n* https://latest.datasette.io/?_context=1\r\n* https://latest.datasette.io/fixtures?_context=1\r\n* https://latest.datasette.io/fixtures/roadside_attractions?_context=1\r\n", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 541467590, "label": "Template debug mode that outputs template context"}, "performed_via_github_app": null}