mirror of
https://github.com/bunkerity/bunkerweb
synced 2026-05-24 09:28:37 +00:00
update docs plugins
This commit is contained in:
parent
febc3ed226
commit
822fa7db6b
1 changed files with 83 additions and 36 deletions
119
docs/plugins.md
119
docs/plugins.md
|
|
@ -544,59 +544,97 @@ BunkerWeb uses an internal job scheduler for periodic tasks like renewing certif
|
|||
|
||||
### Plugin page
|
||||
|
||||
Everything related to the web UI is located inside the subfolder **ui** as we seen in the [previous structure section.](#structure)
|
||||
Everything related to the web UI is located inside the subfolder **ui** as we seen in the [previous structure section.](#structure).
|
||||
|
||||
#### Prerequisites
|
||||
|
||||
When you want to create a plugin page, you need two files :
|
||||
|
||||
- **template.html** that will be accessible with a **GET /plugins/<*plugin_id*>**.
|
||||
|
||||
- **actions.py** where you can add some scripting and logic with a **POST /plugins/<*plugin_id*>**. Notice that this file **need a function with the same name as the plugin** to work. This file is needed even if the function is empty.
|
||||
|
||||
#### Basic example
|
||||
|
||||
!!! info "Jinja 2 template"
|
||||
The **template.html** file is a Jinja2 template, please refer to the [Jinja2 documentation](https://jinja.palletsprojects.com) if needed.
|
||||
|
||||
A plugin page can have a form that is used to submit data to the plugin. To get the values of the form, you need to put a **actions.py** file in the **ui** folder. Inside the file, **you must define a function that has the same name as the plugin**. This function will be called when the form is submitted. You can then use the **request** object (from the [Flask library](https://flask.palletsprojects.com)) to get the values of the form. The form's action must finish with **/plugins/<*plugin_id*>**. The helper function `url_for` will generate for you the prefix of the URL : `{{ url_for('plugins') }}/plugin_id`.
|
||||
We can put aside the **actions.py** file and start **only using the template on a GET situation**. The template can access app context and libs, so you can use Jinja, request or flask utils.
|
||||
|
||||
If you want to display variables generated from your **actions.py** in your template file, you can return a dictionary with variables name as keys and variables value as values. Here is dummy example where we return a single variable :
|
||||
For example, you can get the request arguments in your template like this :
|
||||
|
||||
```python
|
||||
def myplugin() :
|
||||
return {"foo": "bar"}
|
||||
```
|
||||
|
||||
And we display it in the **template.html** file :
|
||||
```html
|
||||
{% if foo %}
|
||||
Content of foo is : {{ foo }}.
|
||||
{% endif %}
|
||||
<p>request args : {{ request.args.get() }}.</p>
|
||||
```
|
||||
|
||||
Please note that every form submission is protected via a CSRF token, you will need to include the following snippet into your forms :
|
||||
```html
|
||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
|
||||
```
|
||||
|
||||
Retrieving user submitted data is pretty simple, thanks to the request module provided by Flask :
|
||||
|
||||
```python
|
||||
from flask import request
|
||||
|
||||
def myplugin() :
|
||||
my_form_value = request.form["my_form_input"]
|
||||
```
|
||||
#### Actions.py
|
||||
|
||||
!!! info "Python libraries"
|
||||
You can use Python libraries that are already available like :
|
||||
`Flask`, `Flask-Login`, `Flask-WTF`, `beautifulsoup4`, `docker`, `Jinja2`, `python-magic` and `requests`. To see the full list, you can have a look at the Web UI [requirements.txt](https://github.com/bunkerity/bunkerweb/blobsrc/ui/requirements.txt). If you need external libraries, you can install them inside the **ui** folder of your plugin and then use the classical **import** directive.
|
||||
|
||||
#### Utils
|
||||
!!! warning "CSRF Token"
|
||||
|
||||
To easily update the content of a template inside the UI with JSON, a **SetupPlugin class** is available in `src/ui/static/js/plugins/setup.js` and will be executed when the plugin template is load.
|
||||
Please note that every form submission is protected via a CSRF token, you will need to include the following snippet into your forms :
|
||||
```html
|
||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
|
||||
```
|
||||
|
||||
|
||||
You can power-up your plugin page with additionnal scripting with the **actions.py** file when sending a **POST /plugins/<*plugin_id*>**.
|
||||
|
||||
Here is what is send to the function :
|
||||
|
||||
For example, in case **actions.py** return this JSON :
|
||||
```python
|
||||
def plugin():
|
||||
return {"message": "ok", "data": {"name": "test"}}
|
||||
function(app=app, args=request.args.to_dict() or request.json or None)
|
||||
```
|
||||
|
||||
I need to add this on my **template.html** :
|
||||
Some examples of what you can do :
|
||||
|
||||
- Retrieve form submitted data
|
||||
|
||||
```python
|
||||
from flask import request
|
||||
|
||||
def myplugin(**kwargs) :
|
||||
my_form_value = request.form["my_form_input"]
|
||||
```
|
||||
|
||||
- Access app methods
|
||||
|
||||
```python
|
||||
from flask import request
|
||||
|
||||
def myplugin(**kwargs) :
|
||||
config = kwargs['app'].config["CONFIG"].get_config(methods=False)
|
||||
```
|
||||
|
||||
**You need to retrieve JSON compatible data from this function**, app will return this as response :
|
||||
|
||||
```python
|
||||
return jsonify({"message": "ok", "data": <function_output>}), 200
|
||||
```
|
||||
|
||||
#### Updating template
|
||||
|
||||
To easily update the content of a template inside the UI with JSON, a **SetupPlugin class** is available in `src/ui/static/js/plugins/setup.js`.
|
||||
|
||||
!!! info "Check core plugins"
|
||||
|
||||
Core plugins are using this class. Feel free to look at them in order to see in details how it works.
|
||||
|
||||
For example, in case **actions.py** return this :
|
||||
|
||||
```python
|
||||
def myplugin(**kwargs):
|
||||
return {"name": "My awesome plugin"}
|
||||
```
|
||||
|
||||
I can add this on my **template.html** :
|
||||
|
||||
```html
|
||||
<p data-name></p>
|
||||
|
||||
<script>
|
||||
new SetupPlugin({
|
||||
name: {
|
||||
|
|
@ -608,16 +646,25 @@ I need to add this on my **template.html** :
|
|||
</script>
|
||||
```
|
||||
|
||||
!!! info "Check core plugins"
|
||||
**This class will send a POST request, and will try to match the dict key to a JSON key and update your template**.
|
||||
|
||||
Core plugins are using this utils. Feel free to look at them in order to see in details how each `key` is working.
|
||||
|
||||
Here it will look for a `name` key in the JSON response, and will set the `data` on the defined `el`.
|
||||
In case there is no `data` matching, this will keep or set the `value` key data.
|
||||
|
||||
This class has two arguments `SetupPlugin(setup, url)` :
|
||||
|
||||
- `url`(optional) : current endpoint by default. You can define another url or add arguments.
|
||||
|
||||
- `setup` : a dict of dict with needed data to update properly the template with the incoming data.
|
||||
|
||||
**setup details**
|
||||
|
||||
| key | Type | Description |
|
||||
| :--------: | :----: | :------------------------------------------------------------------------------------------- |
|
||||
| `name ` | string | Replace `name` by the JSON key to extract the related value. |
|
||||
| `el` | element| Select element you want the value to be updated. |
|
||||
| `dict name` | string | Replace `dict name` by the JSON key to extract the related value. |
|
||||
| `el` | DOM element| Select element you want the value to be updated. |
|
||||
| `value` | any | Default value on template load or in case retrieving JSON failed. |
|
||||
| `type` | string | Define the script behavior with the incoming value. Available : `text`, `list` and `status`. |
|
||||
| `textEl` | element| Optional additional text content when type is `status`. |
|
||||
| `textEl` | DOM element| Optional additional text content when type is `status`. |
|
||||
| `listNames`| string | List of data keys when type is `list`. |
|
||||
|
|
|
|||
Loading…
Reference in a new issue