urls.static_plugins() method, closes #1033

Also documented how to package static assets and templates in plugins, closes #575
pull/1049/head
Simon Willison 2020-10-24 13:03:40 -07:00
rodzic 7f728d4a37
commit 10c35bd371
4 zmienionych plików z 67 dodań i 5 usunięć

Wyświetl plik

@ -1281,6 +1281,9 @@ class Urls:
def static(self, path):
return self.path("-/static/{}".format(path))
def static_plugins(self, plugin, path):
return self.path("-/static-plugins/{}/{}".format(plugin, path))
def logout(self):
return self.path("-/logout")

Wyświetl plik

@ -387,6 +387,14 @@ The ``datasette.urls`` object contains methods for building URLs to pages within
``datasette.urls.logout()``
Returns the URL to the logout page, usually ``"/-/logout"``.
``datasette.urls.static(path)``
Returns the URL of one of Datasette's default static assets, for example ``"/-/static/app.css"``.
``datasette.urls.static_plugins(plugin_name, path)``
Returns the URL of one of the static assets belonging to a plugin.
``datasette.url.static_plugins("datasette_cluster_map", "datasette-cluster-map.js")`` would return ``"/-/static-plugins/datasette_cluster_map/datasette-cluster-map.js"``.
``datasette.urls.database(database_name)``
Returns the URL to a database page, for example ``"/fixtures"``

Wyświetl plik

@ -115,7 +115,21 @@ If your plugin has a ``static/`` directory, Datasette will automatically configu
/-/static-plugins/NAME_OF_PLUGIN_PACKAGE/yourfile.js
See `the datasette-plugin-demos repository <https://github.com/simonw/datasette-plugin-demos/tree/0ccf9e6189e923046047acd7878d1d19a2cccbb1>`_ for an example of how to create a package that includes a static folder.
Use the ``datasette.urls.static_plugins(plugin_name, path)`` method to generate URLs to that asset that take the ``base_url`` setting into account, see :ref:`internals_datasette_urls`.
To bundle the static assets for a plugin in the package that you publish to PyPI, add the following to the plugin's ``setup.py``:
.. code-block:: python
package_data={
'datasette_plugin_name': [
'static/plugin.js',
],
},
Where ``datasette_plugin_name`` is the name of the plugin package (note that it uses underscores, not hyphens) and ``static/plugin.js`` is the path within that package to the static file.
`datasette-cluster-map <https://github.com/simonw/datasette-cluster-map>`__ is a useful example of a plugin that includes packaged static assets in this way.
.. _writing_plugins_custom_templates:
@ -132,6 +146,18 @@ The priority order for template loading is:
See :ref:`customization` for more details on how to write custom templates, including which filenames to use to customize which parts of the Datasette UI.
Templates should be bundled for distribution using the same ``package_data`` mechanism in ``setup.py`` described for static assets above, for example:
.. code-block:: python
package_data={
'datasette_plugin_name': [
'templates/my_template.html',
],
},
You can also use wildcards here such as ``templates/*.html``. See `datasette-edit-schema <https://github.com/simonw/datasette-edit-schema>`__ for an example of this pattern.
.. _writing_plugins_configuration:
Writing plugins that accept configuration

Wyświetl plik

@ -47,6 +47,28 @@ def test_static(ds, base_url, file, expected):
assert ds.urls.static(file) == expected
@pytest.mark.parametrize(
"base_url,plugin,file,expected",
[
(
"/",
"datasette_cluster_map",
"datasette-cluster-map.js",
"/-/static-plugins/datasette_cluster_map/datasette-cluster-map.js",
),
(
"/prefix/",
"datasette_cluster_map",
"datasette-cluster-map.js",
"/prefix/-/static-plugins/datasette_cluster_map/datasette-cluster-map.js",
),
],
)
def test_static_plugins(ds, base_url, plugin, file, expected):
ds._config["base_url"] = base_url
assert ds.urls.static_plugins(plugin, file) == expected
@pytest.mark.parametrize(
"base_url,expected",
[
@ -59,10 +81,13 @@ def test_logout(ds, base_url, expected):
assert ds.urls.logout() == expected
@pytest.mark.parametrize("base_url,expected", [
("/", "/:memory:"),
("/prefix/", "/prefix/:memory:"),
])
@pytest.mark.parametrize(
"base_url,expected",
[
("/", "/:memory:"),
("/prefix/", "/prefix/:memory:"),
],
)
def test_database(ds, base_url, expected):
ds._config["base_url"] = base_url
assert ds.urls.database(":memory:") == expected