id,page,ref,title,content,breadcrumbs,references
plugin_hooks:plugin-hook-extra-body-script,plugin_hooks,plugin-hook-extra-body-script,"extra_body_script(template, database, table, columns, view_name, request, datasette)","Extra JavaScript to be added to a element:
@hookimpl
def extra_body_script():
return {
""module"": True,
""script"": ""console.log('Your JavaScript goes here...')"",
}
This will add the following to the end of your page:
Example: datasette-cluster-map","[""Plugin hooks"", ""Page extras""]","[{""href"": ""https://datasette.io/plugins/datasette-cluster-map"", ""label"": ""datasette-cluster-map""}]"
plugin_hooks:plugin-hook-extra-css-urls,plugin_hooks,plugin-hook-extra-css-urls,"extra_css_urls(template, database, table, columns, view_name, request, datasette)","This takes the same arguments as extra_template_vars(...)
Return a list of extra CSS URLs that should be included on the page. These can
take advantage of the CSS class hooks described in Custom pages and templates .
This can be a list of URLs:
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 :
@hookimpl
def extra_css_urls():
return [
{
""url"": ""https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css"",
""sri"": ""sha384-9gVQ4dYFwwWSjIDZnLEWnxCjeSWFphJiwGPXr1jddIhOegiu1FwO5qRGvFXOdJZ4"",
}
]
This function can also return an awaitable function, useful if it needs to run any async code:
@hookimpl
def extra_css_urls(datasette):
async def inner():
db = datasette.get_database()
results = await db.execute(
""select url from css_files""
)
return [r[0] for r in results]
return inner
Examples: datasette-cluster-map , datasette-vega","[""Plugin hooks"", ""Page extras""]","[{""href"": ""https://www.srihash.org/"", ""label"": ""SRI hash""}, {""href"": ""https://datasette.io/plugins/datasette-cluster-map"", ""label"": ""datasette-cluster-map""}, {""href"": ""https://datasette.io/plugins/datasette-vega"", ""label"": ""datasette-vega""}]"
plugin_hooks:plugin-hook-extra-js-urls,plugin_hooks,plugin-hook-extra-js-urls,"extra_js_urls(template, database, table, columns, view_name, request, datasette)","This takes the same arguments as extra_template_vars(...)
This works in the same way as extra_css_urls() but for JavaScript. You can
return a list of URLs, a list of dictionaries or an awaitable function that returns those things:
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:
@hookimpl
def extra_js_urls():
return [""/-/static-plugins/your-plugin/app.js""]
Note that your-plugin here should be the hyphenated plugin name - the name that is displayed in the list on the /-/plugins debug page.
If your code uses JavaScript modules you should include the ""module"": True key. See Custom CSS and JavaScript for more details.
@hookimpl
def extra_js_urls():
return [
{
""url"": ""/-/static-plugins/your-plugin/app.js"",
""module"": True,
}
]
Examples: datasette-cluster-map , datasette-vega","[""Plugin hooks"", ""Page extras""]","[{""href"": ""https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules"", ""label"": ""JavaScript modules""}, {""href"": ""https://datasette.io/plugins/datasette-cluster-map"", ""label"": ""datasette-cluster-map""}, {""href"": ""https://datasette.io/plugins/datasette-vega"", ""label"": ""datasette-vega""}]"
plugin_hooks:plugin-hook-extra-template-vars,plugin_hooks,plugin-hook-extra-template-vars,"extra_template_vars(template, database, table, columns, view_name, request, datasette)","Extra template variables that should be made available in the rendered template context.
template - string
The template that is being rendered, e.g. database.html
database - string or None
The name of the database, or None if the page does not correspond to a database (e.g. the root page)
table - string or None
The name of the table, or None if the page does not correct to a table
columns - list of strings or None
The names of the database columns that will be displayed on this page. None if the page does not contain a table.
view_name - string
The name of the view being displayed. ( index , database , table , and row are the most important ones.)
request - Request object or None
The current HTTP request. This can be None if the request object is not available.
datasette - Datasette class
You can use this to access plugin configuration options via datasette.plugin_config(your_plugin_name)
This hook can return one of three different types:
Dictionary
If you return a dictionary its keys and values will be merged into the template context.
Function that returns a dictionary
If you return a function it will be executed. If it returns a dictionary those values will will be merged into the template context.
Function that returns an awaitable function that returns a dictionary
You can also return a function which returns an awaitable function which returns a dictionary.
Datasette runs Jinja2 in async mode , which means you can add awaitable functions to the template scope and they will be automatically awaited when they are rendered by the template.
Be careful not to accidentally define a variable that conflicts with one that Datasette is already using for something else. Check the template context documentation to see the variables defined by Datasette core.
Here's an example plugin that adds a ""user_agent"" variable to the template context containing the current request's User-Agent header:
@hookimpl
def extra_template_vars(request):
return {""user_agent"": request.headers.get(""user-agent"")}
This example returns an awaitable function which adds a list of hidden_table_names to the context:
@hookimpl
def extra_template_vars(datasette, database):
async def hidden_table_names():
if database:
db = datasette.databases[database]
return {
""hidden_table_names"": await db.hidden_table_names()
}
else:
return {}
return hidden_table_names
And here's an example which adds a sql_first(sql_query) function which executes a SQL statement and returns the first column of the first row of results:
@hookimpl
def extra_template_vars(datasette, database):
async def sql_first(sql, dbname=None):
dbname = (
dbname
or database
or next(iter(datasette.databases.keys()))
)
result = await datasette.execute(dbname, sql)
return result.rows[0][0]
return {""sql_first"": sql_first}
You can then use the new function in a template like so:
SQLite version: {{ sql_first(""select sqlite_version()"") }}
Examples: datasette-search-all , datasette-template-sql","[""Plugin hooks"", ""Page extras""]","[{""href"": ""https://jinja.palletsprojects.com/en/2.10.x/api/#async-support"", ""label"": ""async mode""}, {""href"": ""https://datasette.io/plugins/datasette-search-all"", ""label"": ""datasette-search-all""}, {""href"": ""https://datasette.io/plugins/datasette-template-sql"", ""label"": ""datasette-template-sql""}]"