{"id": "plugin_hooks:plugin-actions", "page": "plugin_hooks", "ref": "plugin-actions", "title": "Action hooks", "content": "Action hooks can be used to add items to the action menus that appear at the top of different pages within Datasette. Unlike menu_links() , actions which are displayed on every page, actions should only be relevant to the page the user is currently viewing. \n Each of these hooks should return return a list of {\"href\": \"...\", \"label\": \"...\"} menu items, with optional \"description\": \"...\" keys describing each action in more detail. \n They can alternatively return an async def awaitable function which, when called, returns a list of those menu items.", "breadcrumbs": "[\"Plugin hooks\"]", "references": "[]"} {"id": "plugin_hooks:plugin-event-tracking", "page": "plugin_hooks", "ref": "plugin-event-tracking", "title": "Event tracking", "content": "Datasette includes an internal mechanism for tracking notable events. This can be used for analytics, but can also be used by plugins that want to listen out for when key events occur (such as a table being created) and take action in response. \n Plugins can register to receive events using the track_event plugin hook. \n They can also define their own events for other plugins to receive using the register_events() plugin hook , combined with calls to the datasette.track_event() internal method .", "breadcrumbs": "[\"Plugin hooks\"]", "references": "[]"} {"id": "plugin_hooks:plugin-page-extras", "page": "plugin_hooks", "ref": "plugin-page-extras", "title": "Page extras", "content": "These plugin hooks can be used to affect the way HTML pages for different Datasette interfaces are rendered.", "breadcrumbs": "[\"Plugin hooks\"]", "references": "[]"} {"id": "plugin_hooks:id1", "page": "plugin_hooks", "ref": "id1", "title": "Plugin hooks", "content": "Datasette plugins use plugin hooks to customize Datasette's behavior. These hooks are powered by the pluggy plugin system. \n Each plugin can implement one or more hooks using the @hookimpl decorator against a function named that matches one of the hooks documented on this page. \n When you implement a plugin hook you can accept any or all of the parameters that are documented as being passed to that hook. \n For example, you can implement the render_cell plugin hook like this even though the full documented hook signature is render_cell(row, value, column, table, database, datasette) : \n @hookimpl\ndef render_cell(value, column):\n if column == \"stars\":\n return \"*\" * int(value) \n \n List of plugin hooks \n \n \n prepare_connection(conn, database, datasette) \n \n \n prepare_jinja2_environment(env, datasette) \n \n \n Page extras \n \n \n extra_template_vars(template, database, table, columns, view_name, request, datasette) \n \n \n extra_css_urls(template, database, table, columns, view_name, request, datasette) \n \n \n extra_js_urls(template, database, table, columns, view_name, request, datasette) \n \n \n extra_body_script(template, database, table, columns, view_name, request, datasette) \n \n \n \n \n publish_subcommand(publish) \n \n \n render_cell(row, value, column, table, database, datasette, request) \n \n \n register_output_renderer(datasette) \n \n \n register_routes(datasette) \n \n \n register_commands(cli) \n \n \n register_facet_classes() \n \n \n register_permissions(datasette) \n \n \n asgi_wrapper(datasette) \n \n \n startup(datasette) \n \n \n canned_queries(datasette, database, actor) \n \n \n actor_from_request(datasette, request) \n \n \n actors_from_ids(datasette, actor_ids) \n \n \n jinja2_environment_from_request(datasette, request, env) \n \n \n filters_from_request(request, database, table, datasette) \n \n \n permission_allowed(datasette, actor, action, resource) \n \n \n register_magic_parameters(datasette) \n \n \n forbidden(datasette, request, message) \n \n \n handle_exception(datasette, request, exception) \n \n \n skip_csrf(datasette, scope) \n \n \n get_metadata(datasette, key, database, table) \n \n \n menu_links(datasette, actor, request) \n \n \n Action hooks \n \n \n table_actions(datasette, actor, database, table, request) \n \n \n view_actions(datasette, actor, database, view, request) \n \n \n query_actions(datasette, actor, database, query_name, request, sql, params) \n \n \n row_actions(datasette, actor, request, database, table, row) \n \n \n database_actions(datasette, actor, database, request) \n \n \n homepage_actions(datasette, actor, request) \n \n \n \n \n Template slots \n \n \n top_homepage(datasette, request) \n \n \n top_database(datasette, request, database) \n \n \n top_table(datasette, request, database, table) \n \n \n top_row(datasette, request, database, table, row) \n \n \n top_query(datasette, request, database, sql) \n \n \n top_canned_query(datasette, request, database, query_name) \n \n \n \n \n Event tracking \n \n \n track_event(datasette, event) \n \n \n register_events(datasette)", "breadcrumbs": "[]", "references": "[{\"href\": \"https://pluggy.readthedocs.io/\", \"label\": \"pluggy\"}]"} {"id": "plugin_hooks:plugin-hook-slots", "page": "plugin_hooks", "ref": "plugin-hook-slots", "title": "Template slots", "content": "The following set of plugin hooks can be used to return extra HTML content that will be inserted into the corresponding page, directly below the