Register configuration page
One of the admin panel feature is the ability to easily create a configuration page for your extension.
The ckanext-admin-panel
introduces a generic view that can be used to create a configuration page for your extension. This gives us the following benefits:
- The configuration form is generated based on the schema you define. It's fast and easy to create a configuration page.
- The values submitted in the form are stored in the database with
ckanext-editable-config
, so you don't have to worry about handling the configuration values yourself. - It's easy to change and maintain the configuration schema.
- The configuration depends on config declaration - a native CKAN feature. You decide if the configuration option could be edited in a runtime or not.
- You can use regular CKAN validators in your config declaration to validate the configuration values.
- You can reset the configuration to the default values (if the default value is specified in the config declaration).
Note
You define the URL where the configuration page will be available. We suggest to use a /admin-panel/example
prefix for your bluepritn, where example
is a name of your plugin. E.g. /admin-panel/example/config
.
Note
The configuration form will be generated based on the schema you defined in the config_schema.yaml
file.
Warning
The values submitted in the form will be stored in the editable_config_option
table in the database. Make sure to use the ckanext-editable-config
extension.
Registering a configuration page
Defining the config declaration
The configuration declaration is a yaml
file that defines the configuration fields for your extension. This allows to validate the current configuration against the declaration, or check which config options in the CKAN config file are not declared (and might have no effect). Refer to the CKAN documentation for more information, as we're not going to describe it in detail here.
Register a config_declaration.yaml
file in your extension directory. See the example below:
version: 1
groups:
- annotation: Admin panel example
options:
- key: ckanext.ap_example.footer_html
editable: true
validators: ignore_empty unicode_safe wysiwyg_sanitize_html
- key: ckanext.ap_example.header_html
editable: true
- key: ckanext.ap_example.summernote
editable: true
validators: ignore_empty unicode_safe wysiwyg_sanitize_html
- key: ckanext.ap_example.drupal_url
editable: true
validators: ignore_empty unicode_safe url_validator
- key: ckanext.ap_example.cache.duration
type: int
default: 3600
editable: true
- key: ckanext.ap_example.timeout
type: int
default: 5
editable: true
- key: ckanext.ap_example.request.user
editable: true
- key: ckanext.ap_example.request.pass
editable: true
- key: ckanext.ap_example.api_version
default: core
editable: true
- key: ckanext.ap_example.core.menu_export_endpoint
editable: true
default: "/resource/layout/export"
Defining the configuration schema
The configuration schema is a YAML file that defines the configuration fields for your extension. The schema follows the same format as the ckanext-scheming
schema.
Create a config_schema.yaml
file in your extension directory. See the example below, where we use the configuration key as a field_name
:
scheming_version: 2
schema_id: admin_panel_example_config
about: An example how to use scheming for config page
fields:
- field_name: ckanext.ap_example.footer_html
label: CKEditor 5
form_snippet: wysiwyg_ckeditor5.html
display_snippet: wysiwyg_ckeditor5.html
- field_name: ckanext.ap_example.summernote
label: Summernote
form_snippet: wysiwyg_summernote.html
display_snippet: wysiwyg_summernote.html
- field_name: ckanext.ap_example.cache.duration
label: Cache TTL
form_placeholder: 600
input_type: number
- field_name: ckanext.ap_example.drupal_url
label: Drupal base URL
required: true
display_snippet: link.html
- field_name: ckanext.ap_example.api_version
label: API version
preset: select
required: true
choices:
- value: json
label: JSON API
- value: core
label: Core REST API
- field_name: ckanext.ap_example.core.menu_export_endpoint
label: Menu export API endpoint
required: true
help_text: If you are using the core API version, you might face the situation when your endpoint differ from the default one
- field_name: ckanext.ap_example.timeout
label: API request timeout
input_type: number
- field_name: ckanext.ap_example.request.user
label: HTTP auth user
- field_name: ckanext.ap_example.request.pass
label: HTTP auth password
input_type: password
Register the config section and your schema
We're using the ISignal
interface to register the configuration section and the schema file.
# ISignal
def get_signal_subscriptions(self) -> SignalMapping:
return {
tk.signals.ckanext.signal("ap_main:collect_config_sections"): [
self.collect_config_sections_subscriber,
],
tk.signals.ckanext.signal("ap_main:collect_config_schemas"): [
self.collect_config_schemas_subs
],
}
@staticmethod
def collect_config_sections_subscriber(sender: None):
return ap_types.SectionConfig(
name="Admin panel example",
configs=[
ap_types.ConfigurationItem(
name="Example settings",
blueprint="ap_example.config",
info="An example of schema-generated configuration form",
),
ap_types.ConfigurationItem(
name="Example display",
blueprint="ap_example.display",
info="Example of displaying values submitted from a form",
),
],
)
@staticmethod
def collect_config_schemas_subs(sender: None):
return ["ckanext.ap_example:config_schema.yaml"]
Register the blueprint
Refer to the CKAN documentation if you have any problems with registering a blueprint.
-
Implement the
IBlueprint
interface in your extension or use theblanket
for a shortcut (CKAN 2.10+).class AdminPanelExamplePlugin(p.SingletonPlugin): p.implements(p.IBlueprint) def get_blueprint(self): return ...
or
@tk.blanket.blueprints class AdminPanelExamplePlugin(p.SingletonPlugin): ...
-
Create
views.py
file in your extension's directory and define the views for your configuration page. See example below, where we use theschema_id
from the config schema we defined.from flask import Blueprint from ckanext.ap_main.utils import ap_before_request from ckanext.ap_main.views.generics import ApConfigurationPageView log = logging.getLogger(__name__) ap_example = Blueprint("ap_example", __name__, url_prefix="/admin-panel/example") ap_example.before_request(ap_before_request) ... ap_example.add_url_rule( "/config", view_func=ApConfigurationPageView.as_view("config", "admin_panel_example_config"), )
-
This will generate a configuration page for your extension in the admin panel.