kopia lustrzana https://github.com/simonw/datasette
Added plugin_config() method
rodzic
1905c03364
commit
0a14a4846b
|
@ -170,7 +170,7 @@ class Datasette:
|
||||||
def metadata(self, key=None, database=None, table=None, fallback=True):
|
def metadata(self, key=None, database=None, table=None, fallback=True):
|
||||||
"""
|
"""
|
||||||
Looks up metadata, cascading backwards from specified level.
|
Looks up metadata, cascading backwards from specified level.
|
||||||
Returns None if metadata value is not foundself.
|
Returns None if metadata value is not found.
|
||||||
"""
|
"""
|
||||||
assert not (database is None and table is not None), \
|
assert not (database is None and table is not None), \
|
||||||
"Cannot call metadata() with table= specified but not database="
|
"Cannot call metadata() with table= specified but not database="
|
||||||
|
@ -199,6 +199,17 @@ class Datasette:
|
||||||
m.update(item)
|
m.update(item)
|
||||||
return m
|
return m
|
||||||
|
|
||||||
|
def plugin_config(
|
||||||
|
self, plugin_name, database=None, table=None, fallback=True
|
||||||
|
):
|
||||||
|
"Return config for plugin, falling back from specified database/table"
|
||||||
|
plugins = self.metadata(
|
||||||
|
"plugins", database=database, table=table, fallback=fallback
|
||||||
|
)
|
||||||
|
if plugins is None:
|
||||||
|
return None
|
||||||
|
return plugins.get(plugin_name)
|
||||||
|
|
||||||
def app_css_hash(self):
|
def app_css_hash(self):
|
||||||
if not hasattr(self, "_app_css_hash"):
|
if not hasattr(self, "_app_css_hash"):
|
||||||
self._app_css_hash = hashlib.sha1(
|
self._app_css_hash = hashlib.sha1(
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
from pluggy import HookimplMarker
|
from pluggy import HookimplMarker
|
||||||
from pluggy import HookspecMarker
|
from pluggy import HookspecMarker
|
||||||
|
|
||||||
hookspec = HookspecMarker('datasette')
|
hookspec = HookspecMarker("datasette")
|
||||||
hookimpl = HookimplMarker('datasette')
|
hookimpl = HookimplMarker("datasette")
|
||||||
|
|
||||||
|
|
||||||
@hookspec
|
@hookspec
|
||||||
|
|
|
@ -149,6 +149,71 @@ The priority order for template loading is:
|
||||||
See :ref:`customization` for more details on how to write custom templates,
|
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.
|
including which filenames to use to customize which parts of the Datasette UI.
|
||||||
|
|
||||||
|
Plugin configuration
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
Plugins can have their own configuration, embedded in a :ref:`metadata` file. Configuration options for plugins live within a ``"plugins"`` key in that file, which can be included at the root, database or table level.
|
||||||
|
|
||||||
|
Here is an example of some plugin configuration for a specific table::
|
||||||
|
|
||||||
|
{
|
||||||
|
"databases: {
|
||||||
|
"sf-trees": {
|
||||||
|
"tables": {
|
||||||
|
"Street_Tree_List": {
|
||||||
|
"plugins": {
|
||||||
|
"datasette-cluster-map": {
|
||||||
|
"latitude_column": "lat",
|
||||||
|
"longitude_column": "lng"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
This tells the ``datasette-cluster-map`` column which latitude and longitude columns should be used for a table called ``Street_Tree_List`` inside a database file called ``sf-trees.db``.
|
||||||
|
|
||||||
|
When you are writing plugins, you can access plugin configuration like this using the ``datasette.plugin_config()`` method. If you know you need plugin configuration for a specific table, you can access it like this::
|
||||||
|
|
||||||
|
plugin_config = datasette.plugin_config(
|
||||||
|
"datasette-cluster-map", database="sf-trees", table="Street_Tree_List"
|
||||||
|
)
|
||||||
|
|
||||||
|
This will return the ``{"latitude_column": "lat", "longitude_column": "lng"}`` in the above example.
|
||||||
|
|
||||||
|
If it cannot find the requested configuration at the table layer, it will fall back to the database layer and then the root layer. For example, a user may have set the plugin configuration option like so::
|
||||||
|
|
||||||
|
{
|
||||||
|
"databases: {
|
||||||
|
"sf-trees": {
|
||||||
|
"plugins": {
|
||||||
|
"datasette-cluster-map": {
|
||||||
|
"latitude_column": "xlat",
|
||||||
|
"longitude_column": "xlng"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
In this case, the above code would return that configuration for ANY table within the ``sf-trees`` database.
|
||||||
|
|
||||||
|
The plugin configuration could also be set at the top level of ``metadata.json``::
|
||||||
|
|
||||||
|
{
|
||||||
|
"title": "This is the top-level title in metadata.json",
|
||||||
|
"plugins": {
|
||||||
|
"datasette-cluster-map": {
|
||||||
|
"latitude_column": "xlat",
|
||||||
|
"longitude_column": "xlng"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Now that ``datasette-cluster-map`` plugin configuration will apply to every table in every database.
|
||||||
|
|
||||||
Plugin hooks
|
Plugin hooks
|
||||||
------------
|
------------
|
||||||
|
|
||||||
|
|
|
@ -129,9 +129,19 @@ METADATA = {
|
||||||
'license_url': 'https://github.com/simonw/datasette/blob/master/LICENSE',
|
'license_url': 'https://github.com/simonw/datasette/blob/master/LICENSE',
|
||||||
'source': 'tests/fixtures.py',
|
'source': 'tests/fixtures.py',
|
||||||
'source_url': 'https://github.com/simonw/datasette/blob/master/tests/fixtures.py',
|
'source_url': 'https://github.com/simonw/datasette/blob/master/tests/fixtures.py',
|
||||||
|
"plugins": {
|
||||||
|
"name-of-plugin": {
|
||||||
|
"depth": "root"
|
||||||
|
}
|
||||||
|
},
|
||||||
'databases': {
|
'databases': {
|
||||||
'fixtures': {
|
'fixtures': {
|
||||||
'description': 'Test tables description',
|
'description': 'Test tables description',
|
||||||
|
"plugins": {
|
||||||
|
"name-of-plugin": {
|
||||||
|
"depth": "database"
|
||||||
|
}
|
||||||
|
},
|
||||||
'tables': {
|
'tables': {
|
||||||
'simple_primary_key': {
|
'simple_primary_key': {
|
||||||
'description_html': 'Simple <em>primary</em> key',
|
'description_html': 'Simple <em>primary</em> key',
|
||||||
|
@ -143,7 +153,12 @@ METADATA = {
|
||||||
'sortable_with_nulls',
|
'sortable_with_nulls',
|
||||||
'sortable_with_nulls_2',
|
'sortable_with_nulls_2',
|
||||||
'text',
|
'text',
|
||||||
]
|
],
|
||||||
|
"plugins": {
|
||||||
|
"name-of-plugin": {
|
||||||
|
"depth": "table"
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
'no_primary_key': {
|
'no_primary_key': {
|
||||||
'sortable_columns': [],
|
'sortable_columns': [],
|
||||||
|
|
|
@ -14,8 +14,8 @@ label_re = re.compile(r'\.\. _([^\s:]+):')
|
||||||
|
|
||||||
def get_headings(filename, underline="-"):
|
def get_headings(filename, underline="-"):
|
||||||
content = (docs_path / filename).open().read()
|
content = (docs_path / filename).open().read()
|
||||||
heading_re = re.compile(r'(\S+)\n\{}+\n'.format(underline))
|
heading_re = re.compile(r'(\w+)(\([^)]*\))?\n\{}+\n'.format(underline))
|
||||||
return set(heading_re.findall(content))
|
return set(h[0] for h in heading_re.findall(content))
|
||||||
|
|
||||||
|
|
||||||
def get_labels(filename):
|
def get_labels(filename):
|
||||||
|
|
|
@ -85,3 +85,20 @@ def test_plugins_render_cell(app_client):
|
||||||
assert a is not None, str(a)
|
assert a is not None, str(a)
|
||||||
assert a.attrs["href"] == "http://example.com/"
|
assert a.attrs["href"] == "http://example.com/"
|
||||||
assert a.text == "Example"
|
assert a.text == "Example"
|
||||||
|
|
||||||
|
|
||||||
|
def test_plugin_config(app_client):
|
||||||
|
assert {"depth": "table"} == app_client.ds.plugin_config(
|
||||||
|
"name-of-plugin", database="fixtures", table="sortable"
|
||||||
|
)
|
||||||
|
assert {"depth": "database"} == app_client.ds.plugin_config(
|
||||||
|
"name-of-plugin", database="fixtures", table="unknown_table"
|
||||||
|
)
|
||||||
|
assert {"depth": "database"} == app_client.ds.plugin_config(
|
||||||
|
"name-of-plugin", database="fixtures"
|
||||||
|
)
|
||||||
|
assert {"depth": "root"} == app_client.ds.plugin_config(
|
||||||
|
"name-of-plugin", database="unknown_database"
|
||||||
|
)
|
||||||
|
assert {"depth": "root"} == app_client.ds.plugin_config("name-of-plugin")
|
||||||
|
assert None is app_client.ds.plugin_config("unknown-plugin")
|
||||||
|
|
Ładowanie…
Reference in New Issue