Skip to content

Commit

Permalink
urls.static_plugins() method, closes #1033
Browse files Browse the repository at this point in the history
Also documented how to package static assets and templates in plugins, closes #575
  • Loading branch information
simonw committed Oct 24, 2020
1 parent 7f728d4 commit 10c35bd
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 5 deletions.
3 changes: 3 additions & 0 deletions datasette/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -1281,6 +1281,9 @@ def instance(self):
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")

Expand Down
8 changes: 8 additions & 0 deletions docs/internals.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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"``

Expand Down
28 changes: 27 additions & 1 deletion docs/writing_plugins.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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:

Expand All @@ -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
Expand Down
33 changes: 29 additions & 4 deletions tests/test_internals_urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -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",
[
Expand All @@ -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
Expand Down

0 comments on commit 10c35bd

Please sign in to comment.