kopia lustrzana https://github.com/simonw/datasette
rodzic
ca588b6a30
commit
1c36d07dd4
|
@ -12,6 +12,7 @@ import asyncio
|
|||
import os
|
||||
import threading
|
||||
import urllib.parse
|
||||
import itertools
|
||||
import json
|
||||
import jinja2
|
||||
import hashlib
|
||||
|
@ -1126,7 +1127,12 @@ class Datasette:
|
|||
}
|
||||
|
||||
def asset_urls(self, key):
|
||||
for url_or_dict in (self.metadata.get(key) or []):
|
||||
urls_or_dicts = (self.metadata.get(key) or [])
|
||||
# Flatten list-of-lists from plugins:
|
||||
urls_or_dicts += list(
|
||||
itertools.chain.from_iterable(getattr(pm.hook, key)())
|
||||
)
|
||||
for url_or_dict in urls_or_dicts:
|
||||
if isinstance(url_or_dict, dict):
|
||||
yield {
|
||||
'url': url_or_dict['url'],
|
||||
|
@ -1297,10 +1303,14 @@ class Datasette:
|
|||
app.static(path, dirname)
|
||||
# Mount any plugin static/ directories
|
||||
for plugin_module in pm.get_plugins():
|
||||
if pkg_resources.resource_isdir(plugin_module.__name__, 'static'):
|
||||
modpath = '/-/static-plugins/{}/'.format(plugin_module.__name__)
|
||||
dirpath = pkg_resources.resource_filename(plugin_module.__name__, 'static')
|
||||
app.static(modpath, dirpath)
|
||||
try:
|
||||
if pkg_resources.resource_isdir(plugin_module.__name__, 'static'):
|
||||
modpath = '/-/static-plugins/{}/'.format(plugin_module.__name__)
|
||||
dirpath = pkg_resources.resource_filename(plugin_module.__name__, 'static')
|
||||
app.static(modpath, dirpath)
|
||||
except ModuleNotFoundError:
|
||||
# Caused by --plugins_dir= plugins
|
||||
pass
|
||||
app.add_route(
|
||||
DatabaseView.as_view(self),
|
||||
'/<db_name:[^/\.]+?><as_json:(\.jsono?)?$>'
|
||||
|
|
|
@ -13,3 +13,13 @@ def prepare_connection(conn):
|
|||
@hookspec
|
||||
def prepare_jinja2_environment(env):
|
||||
"Modify Jinja2 template environment e.g. register custom template tags"
|
||||
|
||||
|
||||
@hookspec
|
||||
def extra_css_urls():
|
||||
"Extra CSS URLs added by this plugin"
|
||||
|
||||
|
||||
@hookspec
|
||||
def extra_js_urls():
|
||||
"Extra JavaScript URLs added by this plugin"
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
Customizing Datasette's appearance
|
||||
==================================
|
||||
.. _customization:
|
||||
|
||||
Customization
|
||||
=============
|
||||
|
||||
Datasette provides a number of ways of customizing the way data is displayed.
|
||||
|
||||
|
|
|
@ -169,3 +169,65 @@ example:
|
|||
You can now use this filter in your custom templates like so::
|
||||
|
||||
Table name: {{ table|uppercase }}
|
||||
|
||||
extra_css_urls()
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
Return a list of extra CSS URLs that should be included on every page. These can
|
||||
take advantage of the CSS class hooks described in :ref:`customization`.
|
||||
|
||||
This can be a list of URLs:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from datasette import hookimpl
|
||||
|
||||
@hookimpl
|
||||
def extra_css_urls():
|
||||
return [
|
||||
'https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css'
|
||||
]
|
||||
|
||||
Or a list of dictionaries defining both a URL and an
|
||||
`SRI hash <https://www.srihash.org/>`_:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from datasette import hookimpl
|
||||
|
||||
@hookimpl
|
||||
def extra_css_urls():
|
||||
return [{
|
||||
'url': 'https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css',
|
||||
'sri': 'sha384-9gVQ4dYFwwWSjIDZnLEWnxCjeSWFphJiwGPXr1jddIhOegiu1FwO5qRGvFXOdJZ4',
|
||||
}]
|
||||
|
||||
extra_js_urls()
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
This works in the same way as ``extra_css_urls()`` but for JavaScript. You can
|
||||
return either a list of URLs or a list of dictionaries:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from datasette import hookimpl
|
||||
|
||||
@hookimpl
|
||||
def extra_js_urls():
|
||||
return [{
|
||||
'url': 'https://code.jquery.com/jquery-3.3.1.slim.min.js',
|
||||
'sri': 'sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo',
|
||||
}]
|
||||
|
||||
You can also return URLs to files from your plugin's ``static/`` directory, if
|
||||
you have one:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from datasette import hookimpl
|
||||
|
||||
@hookimpl
|
||||
def extra_js_urls():
|
||||
return [
|
||||
'/-/static-plugins/your_plugin/app.js'
|
||||
]
|
||||
|
|
|
@ -113,6 +113,19 @@ def prepare_connection(conn):
|
|||
"select convert_units(100, 'm', 'ft');"
|
||||
return (amount * ureg(from_)).to(to_).to_tuple()[0]
|
||||
conn.create_function('convert_units', 3, convert_units)
|
||||
|
||||
|
||||
@hookimpl
|
||||
def extra_css_urls():
|
||||
return ['https://example.com/app.css']
|
||||
|
||||
|
||||
@hookimpl
|
||||
def extra_js_urls():
|
||||
return [{
|
||||
'url': 'https://example.com/app.js',
|
||||
'sri': 'SRIHASH',
|
||||
}]
|
||||
'''
|
||||
|
||||
TABLES = '''
|
||||
|
|
|
@ -333,6 +333,19 @@ def test_view_html(app_client):
|
|||
assert expected == [[str(td) for td in tr.select('td')] for tr in table.select('tbody tr')]
|
||||
|
||||
|
||||
def test_plugin_extra_css_urls(app_client):
|
||||
response = app_client.get('/', gather_request=False)
|
||||
assert b'<link rel="stylesheet" href="https://example.com/app.css">' in response.body
|
||||
|
||||
|
||||
def test_plugin_extra_js_urls(app_client):
|
||||
response = app_client.get('/', gather_request=False)
|
||||
assert (
|
||||
b'<script src="https://example.com/app.js" integrity="SRIHASH" crossorigin="anonymous"></script>'
|
||||
in response.body
|
||||
)
|
||||
|
||||
|
||||
def test_index_metadata(app_client):
|
||||
response = app_client.get('/', gather_request=False)
|
||||
assert response.status == 200
|
||||
|
|
Ładowanie…
Reference in New Issue