New plugin hook: extra_body_script

pull/363/head
Simon Willison 2018-08-28 01:56:44 -07:00
rodzic 0a14a4846b
commit 5cf0c6c91c
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 17E2DEA2588B7F52
6 zmienionych plików z 88 dodań i 0 usunięć

Wyświetl plik

@ -25,6 +25,11 @@ def extra_js_urls():
"Extra JavaScript URLs added by this plugin"
@hookspec
def extra_body_script(template, database, table, datasette):
"Extra JavaScript code to be included in <script> at bottom of body"
@hookspec
def publish_subcommand(publish):
"Subcommands for 'datasette publish'"

Wyświetl plik

@ -35,6 +35,11 @@
{% endif %}
{% endif %}
</div>
{% for body_script in body_scripts %}
<script>{{ body_script }}</script>
{% endfor %}
{% if select_templates %}<!-- Templates considered: {{ select_templates|join(", ") }} -->{% endif %}
</body>
</html>

Wyświetl plik

@ -52,6 +52,14 @@ class RenderMixin(HTTPMethodView):
"{}{}".format("*" if template_name == template.name else "", template_name)
for template_name in templates
]
body_scripts = []
for script in pm.hook.extra_body_script(
template=template.name,
database=context.get("database"),
table=context.get("table"),
datasette=self.ds
):
body_scripts.append(jinja2.Markup(script))
return response.html(
template.render(
{
@ -60,6 +68,7 @@ class RenderMixin(HTTPMethodView):
"app_css_hash": self.ds.app_css_hash(),
"select_templates": select_templates,
"zip": zip,
"body_scripts": body_scripts,
}
}
)

Wyświetl plik

@ -385,3 +385,14 @@ If the value matches that pattern, the plugin returns an HTML link element:
href=jinja2.escape(data["href"]),
label=jinja2.escape(data["label"] or "") or "&nbsp;"
))
extra_body_script(template, database, table, datasette)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Extra JavaScript to be added to a ``<script>`` block at the end of the ``<body>`` element on the page.
The ``template``, ``database`` and ``table`` options can be used to return different code depending on which template is being rendered and which database or table are being processed.
The ``datasette`` instance is provided primarily so that you can consult any plugin configuration options that may have been set, using the ``datasette.plugin_config(plugin_name)`` method documented above.
The string that you return from this function will be treated as "safe" for inclusion in a ``<script>`` block directly in the page, so it is up to you to apply any necessary escaping.

Wyświetl plik

@ -222,6 +222,23 @@ def extra_js_urls():
'url': 'https://example.com/jquery.js',
'sri': 'SRIHASH',
}, 'https://example.com/plugin1.js']
@hookimpl
def extra_body_script(template, database, table, datasette):
import json
return 'var extra_body_script = {};'.format(
json.dumps({
"template": template,
"database": database,
"table": table,
"config": datasette.plugin_config(
"name-of-plugin",
database=database,
table=table,
)
})
)
'''
PLUGIN2 = '''

Wyświetl plik

@ -2,6 +2,8 @@ from bs4 import BeautifulSoup as Soup
from .fixtures import ( # noqa
app_client,
)
import json
import re
import pytest
import urllib
@ -102,3 +104,42 @@ def test_plugin_config(app_client):
)
assert {"depth": "root"} == app_client.ds.plugin_config("name-of-plugin")
assert None is app_client.ds.plugin_config("unknown-plugin")
@pytest.mark.parametrize(
"path,expected_extra_body_script",
[
(
"/",
{
"template": "index.html",
"database": None,
"table": None,
"config": {"depth": "root"},
},
),
(
"/fixtures/",
{
"template": "database.html",
"database": "fixtures",
"table": None,
"config": {"depth": "database"},
},
),
(
"/fixtures/sortable",
{
"template": "table.html",
"database": "fixtures",
"table": "sortable",
"config": {"depth": "table"},
},
),
],
)
def test_extra_body_script(app_client, path, expected_extra_body_script):
r = re.compile(r"<script>var extra_body_script = (.*?);</script>")
json_data = r.search(app_client.get(path).body.decode("utf8")).group(1)
actual_data = json.loads(json_data)
assert expected_extra_body_script == actual_data