Skip to content

Commit e73b5c7

Browse files
damwaingamesAJ Griffithsalxbridge
authored
Update to Support Wagtail 7.1 (#84)
* Update tox.ini * Streamfields don't need use_json_field. * All supported version now fit in the main code flow. * Update for changed Tab components * Update classifiers and supported version * Update CHANGELOG * Keep pre 7.1 tabbed component attributes * Fix test script to work with coverage >= 7.8.0 Breakage caused by coverage fixing its PYTHONSAFEPATH behaviour: coveragepy/coveragepy#1696 * Update tox matrix * Fix missed old version checks. --------- Co-authored-by: AJ Griffiths <alyssa.griffths@torchbox.com> Co-authored-by: Alex Bridge <alex.bridge@torchbox.com>
1 parent e8a799c commit e73b5c7

File tree

9 files changed

+77
-108
lines changed

9 files changed

+77
-108
lines changed

CHANGELOG.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@
22

33
## Unreleased
44

5-
- Update tox testing to include Wagtail 6.3 and 6.4
6-
- Add tox testing for Django 5.1
5+
- Remove support for Wagtail <6.3
6+
- Update tox testing to include Wagtail 6.3, 7.0 and 7.1
7+
- Add tox testing for Django 5.1 and 5.2, remove testing for Django 5.0 (EOL)
78
- Drop testing around python 3.8
89

910
## 0.13.0

pyproject.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,17 +24,17 @@ classifiers = [
2424
"Programming Language :: Python :: 3.13",
2525
"Framework :: Django",
2626
"Framework :: Django :: 4.2",
27-
"Framework :: Django :: 5.0",
2827
"Framework :: Django :: 5.1",
28+
"Framework :: Django :: 5.2",
2929
"Framework :: Wagtail",
30-
"Framework :: Wagtail :: 5",
3130
"Framework :: Wagtail :: 6",
31+
"Framework :: Wagtail :: 7",
3232
]
3333

3434
dynamic = ["version"] # will read __version__ from wagtail_footnotes/__init__.py
3535
requires-python = ">=3.9"
3636
dependencies = [
37-
"Wagtail>=5.2",
37+
"Wagtail>=6.3",
3838
"Django>=4.2",
3939
]
4040

testmanage.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,13 @@
66
import sys
77
import warnings
88

9+
10+
# The current directory isn't on the path when GitHub Actions / tox run this
11+
# with 'python -Im coverage run', due to PYTHONSAFEPATH protection.
12+
# We explicitly add it here as otherwise we can't reach the tests.
13+
if "." not in sys.path:
14+
sys.path.insert(0, ".")
15+
916
from django.core.management import execute_from_command_line
1017

1118

tests/models.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
class TestPageStreamField(Page):
99
template = "test/test_page_stream_field.html"
1010

11-
body = StreamField(CustomBlock(), use_json_field=True)
11+
body = StreamField(CustomBlock())
1212

1313
content_panels = Page.content_panels + [
1414
FieldPanel("body"),

tests/test/test_widgets.py

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
from django import forms
22
from django.test import TestCase
3-
from wagtail import VERSION as WAGTAIL_VERSION
43

54
from wagtail_footnotes.widgets import ReadonlyUUIDInput
65

@@ -10,17 +9,7 @@ def test_read_only_uuid_input(self):
109
form = forms.Form()
1110
form.fields["uuid"] = forms.CharField(widget=ReadonlyUUIDInput)
1211

13-
if WAGTAIL_VERSION >= (6, 0):
14-
self.assertInHTML(
15-
'<input type="hidden" name="uuid" id="id_uuid" data-controller="read-only-uuid">',
16-
form.as_p(),
17-
)
18-
else:
19-
self.assertInHTML(
20-
'<input type="hidden" name="uuid" id="id_uuid">',
21-
form.as_p(),
22-
)
23-
self.assertInHTML(
24-
'<script>setUUID("id_uuid");</script>',
25-
form.as_p(),
26-
)
12+
self.assertInHTML(
13+
'<input type="hidden" name="uuid" id="id_uuid" data-controller="read-only-uuid">',
14+
form.as_p(),
15+
)

tox.ini

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22
min_version = 4.22
33

44
envlist =
5-
python{3.9,3.10,3.11}-django4.2-wagtail{5.2,6.3,6.4}
6-
python{3.10,3.11,3.12}-django5.0-wagtail{5.2,6.3,6.4}
7-
python{3.12,3.13}-django5.1-wagtail{6.3,6.4}
5+
python{3.9,3.10}-django4.2-wagtail{6.3}
6+
python{3.10,3.11}-django5.1-wagtail{7.0,7.1}
7+
python{3.12,3.13}-django5.2-wagtail{7.0,7.1}
88

99
[gh-actions]
1010
python =
@@ -30,12 +30,12 @@ set_env =
3030

3131
deps =
3232
django4.2: Django>=4.2,<4.3
33-
django5.0: Django>=5.0,<5.1
3433
django5.1: Django>=5.1,<5.2
34+
django5.2: Django>=5.2,<5.3
3535

36-
wagtail5.2: wagtail>=5.2,<5.3
3736
wagtail6.3: wagtail>=6.3,<6.4
38-
wagtail6.4: wagtail>=6.4,<6.5
37+
wagtail7.0: wagtail>=7.0,<7.1
38+
wagtail7.1: wagtail>=7.1,<7.2
3939

4040

4141
extras = testing

wagtail_footnotes/migrations/0006_alter_footnote_locale.py

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
import django.db.models.deletion
33

44
from django.db import migrations, models
5-
from wagtail import VERSION as WAGTAIL_VERSION
65

76

87
class Migration(migrations.Migration):
@@ -14,19 +13,16 @@ class Migration(migrations.Migration):
1413
),
1514
]
1615

17-
operations = []
18-
19-
if WAGTAIL_VERSION >= (6, 2):
20-
operations.append(
21-
migrations.AlterField(
22-
model_name="footnote",
23-
name="locale",
24-
field=models.ForeignKey(
25-
editable=False,
26-
on_delete=django.db.models.deletion.PROTECT,
27-
related_name="+",
28-
to="wagtailcore.locale",
29-
verbose_name="locale",
30-
),
31-
)
16+
operations = [
17+
migrations.AlterField(
18+
model_name="footnote",
19+
name="locale",
20+
field=models.ForeignKey(
21+
editable=False,
22+
on_delete=django.db.models.deletion.PROTECT,
23+
related_name="+",
24+
to="wagtailcore.locale",
25+
verbose_name="locale",
26+
),
3227
)
28+
]

wagtail_footnotes/templates/wagtail_footnotes/admin/footnotes_modal.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ <h1 class="header-title w-header__title">{% translate "Choose a footnote" %}</h1
1919
</div>
2020
</header>
2121

22-
<div class="w-tabs" data-tabs="" data-tabs-disable-url="">
22+
<div class="w-tabs" data-controller="w-tabs" data-tabs="" data-tabs-disable-url="">
2323
<div class="w-tabs__wrapper"></div>
2424
<div class="tab-content">
2525
<div class="w-tabs__panel">

wagtail_footnotes/widgets.py

Lines changed: 40 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1,64 +1,40 @@
1-
from django.forms import HiddenInput
2-
from wagtail import VERSION as WAGTAIL_VERSION
3-
4-
5-
if WAGTAIL_VERSION >= (6, 0):
6-
from django.forms import Media
7-
from django.utils.safestring import mark_safe
8-
9-
class ReadonlyUUIDInput(HiddenInput):
10-
"""
11-
This isn't really read-only. It's a hidden input with an an adjacent div
12-
showing the current value; that way we can set the value in JavaScript, but
13-
the user can't easily change it.
14-
"""
15-
16-
def render(self, name, value, attrs=None, renderer=None):
17-
# no point trying to come up with sensible semantics for when 'id' is missing from attrs,
18-
# so let's make sure it fails early in the process
19-
try:
20-
attrs["id"]
21-
except (KeyError, TypeError) as exc:
22-
raise TypeError(
23-
"ReadonlyUUIDInput cannot be rendered without an 'id' attribute"
24-
) from exc
25-
26-
widget_html = self.render_html(name, value, attrs)
27-
28-
return mark_safe(widget_html) # noqa: S308
29-
30-
def render_html(self, name, value, attrs):
31-
"""Render the HTML (non-JS) portion of the field markup"""
32-
hidden = super().render(name, value, attrs)
33-
display_value = value[:6] if value is not None else value
34-
shown = f'<div id="{attrs["id"]}_display-value" style="padding-top: 1.2em;">{display_value}</div>'
35-
return shown + hidden
36-
37-
def build_attrs(self, *args, **kwargs):
38-
attrs = super().build_attrs(*args, **kwargs)
39-
attrs["data-controller"] = "read-only-uuid"
40-
return attrs
41-
42-
@property
43-
def media(self):
44-
return Media(js=["footnotes/js/read-only-uuid-controller.js"])
45-
46-
else:
47-
from wagtail.utils.widgets import WidgetWithScript
48-
49-
class ReadonlyUUIDInput(WidgetWithScript, HiddenInput):
50-
"""
51-
This isn't really read-only. It's a hidden input with an an adjacent div
52-
showing the current value; that way we can set the value in JavaScript, but
53-
the user can't easily change it.
54-
"""
55-
56-
def render_html(self, name, value, attrs):
57-
"""Render the HTML (non-JS) portion of the field markup"""
58-
hidden = super(WidgetWithScript, self).render(name, value, attrs)
59-
display_value = value[:6] if value is not None else value
60-
shown = f'<div id="{attrs["id"]}_display-value" style="padding-top: 1.2em;">{display_value}</div>'
61-
return shown + hidden
62-
63-
def render_js_init(self, id_, name, value):
64-
return f'setUUID("{id_}");'
1+
from django.forms import HiddenInput, Media
2+
from django.utils.safestring import mark_safe
3+
4+
5+
class ReadonlyUUIDInput(HiddenInput):
6+
"""
7+
This isn't really read-only. It's a hidden input with an an adjacent div
8+
showing the current value; that way we can set the value in JavaScript, but
9+
the user can't easily change it.
10+
"""
11+
12+
def render(self, name, value, attrs=None, renderer=None):
13+
# no point trying to come up with sensible semantics for when 'id' is missing from attrs,
14+
# so let's make sure it fails early in the process
15+
try:
16+
attrs["id"]
17+
except (KeyError, TypeError) as exc:
18+
raise TypeError(
19+
"ReadonlyUUIDInput cannot be rendered without an 'id' attribute"
20+
) from exc
21+
22+
widget_html = self.render_html(name, value, attrs)
23+
24+
return mark_safe(widget_html) # noqa: S308
25+
26+
def render_html(self, name, value, attrs):
27+
"""Render the HTML (non-JS) portion of the field markup"""
28+
hidden = super().render(name, value, attrs)
29+
display_value = value[:6] if value is not None else value
30+
shown = f'<div id="{attrs["id"]}_display-value" style="padding-top: 1.2em;">{display_value}</div>'
31+
return shown + hidden
32+
33+
def build_attrs(self, *args, **kwargs):
34+
attrs = super().build_attrs(*args, **kwargs)
35+
attrs["data-controller"] = "read-only-uuid"
36+
return attrs
37+
38+
@property
39+
def media(self):
40+
return Media(js=["footnotes/js/read-only-uuid-controller.js"])

0 commit comments

Comments
 (0)