Skip to content

Commit d5fa16e

Browse files
authored
Merge pull request #19 from octue/tidy-up
Update documentation and refactor settings
2 parents 2f877d3 + 69c91f6 commit d5fa16e

14 files changed

+342
-186
lines changed

.devcontainer/devcontainer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@
7979
},
8080

8181
// Use 'forwardPorts' to make a list of ports inside the container available locally.
82-
"forwardPorts": [80, 443, 5000, 7045, 7046, 7047, 7048, 7049, 8000, 8080],
82+
"forwardPorts": [80, 443, 5500, 8000],
8383

8484
// Use 'postCreateCommand' to run commands after the container is created.
8585
// Note: Reverting to use pip requirements until we can install private dependencies in GHA with poetry

.devcontainer/postcreate.sh

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,8 @@
33
# Install dependencies
44
poetry install
55

6+
# Allow precommit to install properly
7+
git config --global --add safe.directory /workspace
8+
69
# Install precommit hooks
710
pre-commit install && pre-commit install -t commit-msg

CONTRIBUTING.md

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
# Contributing
2+
3+
## Where to start
4+
5+
The best place to start is by raising an issue on this repository (or identifying an existing issue and commenting there that you'll be working on it). If you need we can help you get started and sanity-check your approach.
6+
7+
## Developers Getting Started
8+
9+
To get started with developing `django-svelte-jsoneditor`, fork the repo then open an environment in the devcontainer (the easiest way is to use GitHub codespaces or VSCode remote containers), then type:
10+
11+
```
12+
python manage.py migrate
13+
python manage.py createsuperuser
14+
# (then enter user details for yourself)
15+
python manage.py runserver
16+
# (then go to the localhost address in your browser)
17+
# (and in another terminal...)
18+
pytest
19+
# (this should run all tests and have them pass)
20+
```
21+
22+
You'll find this takes you to the django admin where you have several example models registered, each of which use slightly different options on the json field, so you can see how the widget behaves.
23+
24+
### About Svelte
25+
26+
**You don't need to know or care.** It's the JavaScript framework used to develop the widget - but the widget JS is all pre-built so there are no extra requirements.
27+
28+
## Commit messages
29+
30+
We use conventional commits, both to facilitate semantic version checking and to allow automatic generation of PR descriptions and release notes. This means:
31+
32+
- Your commit messages will be part of the release notes. Please keep your commit messages short (<72 characters) and descriptive of the change made in that commit.
33+
34+
- Please use the following [conventional commit codes](https://github.com/octue/conventional-commits#default-allowed-commit-codes)
35+
36+
- Breaking changes should be indicated by starting the body of the commit message with `BREAKING-CHANGE: <explain what users should do to migrate past the change`, eg you'd do:
37+
38+
```
39+
git commit the_file_you_changed.py -m "FEA: New feature to do XYZ
40+
41+
BREAKING-CHANGE: To implement XYZ, we had to remove setting ABC. To update, users should remove setting ABC and replace it with setting PQR"
42+
```
43+
44+
## Pre-Commit
45+
46+
We use [`pre-commit`](https://pre-commit.com/) to apply consistent code quality checks and linting to new code, commit messages, and documentation.
47+
48+
You need to install pre-commit to get the hooks working. Run:
49+
50+
```
51+
pip install pre-commit
52+
pre-commit install && pre-commit install -t commit-msg
53+
```
54+
55+
Once that's done, each time you make a commit, [a range of checks](/.pre-commit-config.yaml) are made.
56+
57+
Upon failure, the commit will halt. **Re-running the commit will automatically fix most issues** except:
58+
59+
- The `flake8` checks... hopefully over time `black` (which fixes most things automatically already) will remove the need for it
60+
- Docstrings - the error messages should explain how to fix these easily
61+
- You'll have to fix documentation yourself prior to a successful commit (there's no auto fix for that!!)
62+
- Commit messages - the error messages should explain how to fix these too
63+
64+
You can run pre-commit hooks without making a commit, too, like:
65+
66+
```
67+
pre-commit run black --all-files
68+
```
69+
70+
## Documentation
71+
72+
If you're unfamiliar with sphinx or reStructuredText, You can build html documentation using:
73+
74+
```
75+
pre-commit run --all-files build-docs -v
76+
```

README.md

Lines changed: 3 additions & 156 deletions
Original file line numberDiff line numberDiff line change
@@ -1,164 +1,11 @@
11
[![PyPI version](https://badge.fury.io/py/django-svelte-jsoneditor.svg)](https://badge.fury.io/py/django-svelte-jsoneditor)
2-
[![Documentation Status](https://readthedocs.org/projects/django-svelte-jsoneditor/badge/?version=latest)](https://django-svelte-jsoneditor.readthedocs.io/en/latest/?badge=latest)
2+
[![Documentation Status](https://readthedocs.org/projects/django-svelte-jsoneditor/badge/?version=latest)](https://django-svelte-jsoneditor.readthedocs.io/en/latest/)
33
[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
44
[![pre-commit](https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit&logoColor=white)](https://github.com/pre-commit/pre-commit)
5+
[![codeql](https://github.com/octue/django-svelte-jsoneditor/actions/workflows/codeql.yml/badge.svg)](https://github.com/octue/django-svelte-jsoneditor/actions/workflows/codeql.yml)
56

67
# django-svelte-jsoneditor
78

89
A plug in widget for django's JSONField that allows manipulation and display of JSON data. The widget is built using Jos deJong's new [svelte-jsoneditor](https://github.com/josdejong/svelte-jsoneditor).
910

10-
This app is a replacement for `django-jsoneditor` (which uses a deprecated version of the widget, `jsoneditor` - you can [see the differences here](https://github.com/josdejong/svelte-jsoneditor#differences-between-josdejongsvelte-jsoneditor-and-josdejongjsoneditor)). You can read about why we're not directly contributing to `django-jsoneditor` [here](https://github.com/nnseva/django-jsoneditor/issues/71), the two projects might merge in the future.
11-
12-
## Documentation
13-
14-
### Installation
15-
16-
To get an application installed in your project, you need to add `django_svelte_jsoneditor` into `INSTALLED_APPS` in `settings.py` file.
17-
18-
```python
19-
# settings.py
20-
21-
INSTALLED_APPS = [
22-
# Other Django applications
23-
"django_svelte_jsoneditor",
24-
]
25-
```
26-
27-
### Usage
28-
29-
The application contains new widget called `SvelteJSONEditorWidget` which adds editor capabilities to JSON fields in Django. Below you can see an example, of how to override the default widget for the JSON field (in this case textarea widget).
30-
31-
```python
32-
# admin.py
33-
34-
from django.contrib import admin
35-
from django_svelte_jsoneditor.widgets import SvelteJSONEditorWidget
36-
37-
from .models import MyModel
38-
39-
40-
@admin.register(MyModel)
41-
class MyModelAdmin(admin.ModelAdmin):
42-
formfield_overrides = {
43-
models.JSONField: {
44-
"widget": SvelteJSONEditorWidget,
45-
}
46-
}
47-
```
48-
49-
Another example is how to create a new Django form integrating `SvelteJSONEditorWidget` replacing `Textarea` widget.
50-
51-
```python
52-
# forms.py
53-
from django import forms
54-
from django_svelte_jsoneditor.widgets import SvelteJSONEditorWidget
55-
56-
57-
class MyJSONEditorForm(forms.Form):
58-
json = forms.JSONField(widgets=SvelteJSONEditorWidget())
59-
```
60-
61-
### Global settings
62-
63-
The application allows modifying some properties of svelte-jsoneditor inside the settings.py configuration file in Django. Official documentation is available on [svelte-jsoneditor](https://github.com/josdejong/svelte-jsoneditor#properties) GitHub page. **Note:** Not all options are configurable which are provided by svelte-jsoneditor.
64-
65-
```python
66-
# settings.py
67-
68-
SVELTE_JSONEDITOR = {
69-
"mode": "tree",
70-
"mainMenuBar": True,
71-
"navigationBar": True,
72-
"statusBar": True,
73-
"askToFormat": True,
74-
"readOnly": False,
75-
"indentations": 4,
76-
"tabSize": 4,
77-
"escapeControlCharacters": False,
78-
"flattenColumns": True,
79-
}
80-
```
81-
82-
#### Available properties
83-
84-
| Property | Type | Default |
85-
| ----------------------- | --------------------------- | ------- |
86-
| mode | 'tree' or 'text' or 'table' | 'tree' |
87-
| mainMenuBar | boolean | True |
88-
| navigationBar | boolean | True |
89-
| statusBar | boolean | True |
90-
| askToFormat | boolean | True |
91-
| readOnly | boolean | False |
92-
| indentations | number or string | 4 |
93-
| tabSize | number | 4 |
94-
| escapeControlCharacters | boolean | False |
95-
| flattenColumns | boolean | True |
96-
97-
### Widget properties
98-
99-
`SvelteJSONEditorWidget` has additional argument called `props` which allows to override `SVELTE_JSONEDITOR` settings from settings.py.
100-
101-
```python
102-
# forms.py
103-
104-
from django import forms
105-
106-
107-
class SvelteJsonEditorForm(forms.Form):
108-
my_json = forms.JSONField(widget=SvelteJSONEditorWidget(props={
109-
"readOnly": True
110-
}))
111-
```
112-
113-
#### Custom widget properties in admin form
114-
115-
```python
116-
# admin.py
117-
118-
from django import forms
119-
from django.contrib import admin
120-
121-
from .models import ExampleModel
122-
123-
class CustomForm(forms.ModelForm):
124-
class Meta:
125-
model = ExampleModel
126-
fields = "__all__"
127-
128-
def __init__(self, *args, **kwargs):
129-
super().__init__(*args, **kwargs)
130-
self.fields["some_json_field"].widget = SvelteJSONEditorWidget(props={"readOnly": True})
131-
132-
133-
@admin.register(ExampleModel, ExampleModelAdmin)
134-
class ExampleModelAdmin(admin.ModelAdmin):
135-
form = CustomForm
136-
formfield_overrides = {
137-
models.JSONField: {
138-
"widget": SvelteJSONEditorWidget,
139-
}
140-
}
141-
```
142-
143-
## About Svelte
144-
145-
**You don't need to know or care.** It's the JavaScript framework used to develop the widget - but the widget JS is all pre-built so there are no extra requirements.
146-
147-
### Developing
148-
149-
To get started with developing `django-svelte-jsoneditor`, fork the repo then open an environment in the devcontainer (the easiest way is to use GitHub codespaces or VSCode remote containers), then type:
150-
151-
```
152-
python manage.py migrate
153-
python manage.py createsuperuser
154-
# (then enter user details for yourself)
155-
python manage.py runserver
156-
# (then go to the localhost address in your browser)
157-
# (and in another terminal...)
158-
pytest
159-
# (this should run all tests and have them pass)
160-
```
161-
162-
You'll find this takes you to the django admin where you have several example models registered, each of which use slightly different options on the json field, so you can see how the widget behaves.
163-
164-
**On the subject of commit messages**. It's helpful if you use the following [conventional commit codes](https://github.com/octue/conventional-commits#default-allowed-commit-codes) because then the PR and release notes get generated automatically!
11+
[**Read the documentation here.**](https://django-svelte-jsoneditor.readthedocs.io/en/latest/)
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
class ExampleError(Exception):
2-
"""Example for custom exception definition"""
1+
class InvalidPropError(ValueError):
2+
"""Raised when props are incorrectly configured"""

django_svelte_jsoneditor/settings.py

Lines changed: 33 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,40 @@
11
from django.conf import settings
22

3+
from .exceptions import InvalidPropError
34

4-
CONFIG_DEFAULTS = {
5-
"PROPS": {
6-
"mode": "tree",
7-
"mainMenuBar": True,
8-
"navigationBar": True,
9-
"statusBar": True,
10-
"askToFormat": True,
11-
"readOnly": False,
12-
"indentations": 4,
13-
"tabSize": 4,
14-
"escapeControlCharacters": False,
15-
"flattenColumns": True,
16-
}
5+
6+
DEFAULT_SVELTE_JSONEDITOR_PROPS = {
7+
"mode": "tree",
8+
"mainMenuBar": True,
9+
"navigationBar": True,
10+
"statusBar": True,
11+
"askToFormat": True,
12+
"readOnly": False,
13+
"indentation": 4,
14+
"tabSize": 4,
15+
"escapeControlCharacters": False,
16+
"escapeUnicodeCharacters": False,
17+
"flattenColumns": True,
1718
}
1819

1920

20-
def get_config():
21-
return {
22-
"PROPS": {
23-
**CONFIG_DEFAULTS["PROPS"],
24-
**getattr(settings, "SVELTE_JSONEDITOR", {}).get("PROPS", {}),
21+
_AVAILABLE_PROPS = set(DEFAULT_SVELTE_JSONEDITOR_PROPS.keys())
22+
23+
24+
def check_props(props):
25+
"""Check that props given to the widget are valid"""
26+
for key in props:
27+
if key not in _AVAILABLE_PROPS:
28+
raise InvalidPropError(f"Invalid prop '{key}'")
29+
30+
return props
31+
32+
33+
def get_props():
34+
"""Get default props overridden by any props set in the SVELTE_JSONEDITOR_PROPS setting"""
35+
return check_props(
36+
{
37+
**DEFAULT_SVELTE_JSONEDITOR_PROPS,
38+
**getattr(settings, "SVELTE_JSONEDITOR_PROPS", {}),
2539
}
26-
}
40+
)

django_svelte_jsoneditor/widgets.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import json
22
from django.forms import Textarea
33

4-
from .settings import get_config
4+
from .settings import check_props, get_props
55

66

77
class SvelteJSONEditorWidget(Textarea):
@@ -12,13 +12,14 @@ def __init__(self, props=None, attrs=None):
1212
attrs = {}
1313

1414
self.props = {} if props is None else props.copy()
15+
check_props(self.props)
1516
attrs.update({"class": "hidden"})
1617

1718
super().__init__(attrs)
1819

1920
def get_context(self, name, value, attrs):
2021
context = super().get_context(name, value, attrs)
21-
context["widget"].update({"props": json.dumps({**get_config()["PROPS"], **self.props})})
22+
context["widget"].update({"props": json.dumps({**get_props(), **self.props})})
2223
return context
2324

2425
class Media:

docs/source/contributing.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
.. _contributing:
2+
3+
============
4+
Contributing
5+
============
6+
7+
If you'd like to contribute to ``django_svelte_jsoneditor``, you'll be most welcome! Please `start by reading our contributing guidelines `<https://github.com/octue/django-svelte-jsoneditor/blob/main/CONTRIBUTING.md>`_.

0 commit comments

Comments
 (0)