Skip to content

Commit 4dad4d8

Browse files
authored
Merge pull request #100 from LandRegistry/govuk-frontend-50
GOV.UK Frontend v5.0
2 parents 0e3d330 + 240f5f3 commit 4dad4d8

20 files changed

+254
-152
lines changed
Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,39 @@
11
# Dependency Review Action
22
#
3-
# This Action will scan dependency manifest files that change as part of a Pull Request, surfacing known-vulnerable versions of the packages declared or updated in the PR. Once installed, if the workflow run is marked as required, PRs introducing known-vulnerable packages will be blocked from merging.
3+
# This Action will scan dependency manifest files that change as part of a Pull Request,
4+
# surfacing known-vulnerable versions of the packages declared or updated in the PR.
5+
# Once installed, if the workflow run is marked as required, PRs introducing known-vulnerable
6+
# packages will be blocked from merging.
47
#
58
# Source repository: https://github.com/actions/dependency-review-action
69
# Public documentation: https://docs.github.com/en/code-security/supply-chain-security/understanding-your-software-supply-chain/about-dependency-review#dependency-review-enforcement
7-
name: 'Dependency Review'
8-
on: [pull_request]
10+
name: 'Dependency review'
11+
on:
12+
pull_request:
13+
branches: [ "main" ]
914

15+
# If using a dependency submission action in this workflow this permission will need to be set to:
16+
#
17+
# permissions:
18+
# contents: write
19+
#
20+
# https://docs.github.com/en/enterprise-cloud@latest/code-security/supply-chain-security/understanding-your-software-supply-chain/using-the-dependency-submission-api
1021
permissions:
1122
contents: read
23+
# Write permissions for pull-requests are required for using the `comment-summary-in-pr` option, comment out if you aren't using this option
24+
pull-requests: write
1225

1326
jobs:
1427
dependency-review:
1528
runs-on: ubuntu-latest
1629
steps:
17-
- name: 'Checkout Repository'
18-
uses: actions/checkout@v3
30+
- name: 'Checkout repository'
31+
uses: actions/checkout@v4
1932
- name: 'Dependency Review'
20-
uses: actions/dependency-review-action@v3
33+
uses: actions/dependency-review-action@v4
34+
# Commonly enabled options, see https://github.com/actions/dependency-review-action#configuration-options for all available options.
35+
with:
36+
comment-summary-in-pr: always
37+
# fail-on-severity: moderate
38+
# deny-licenses: GPL-1.0-or-later, LGPL-2.0-or-later
39+
# retry-on-snapshot-warnings: true

.github/workflows/python-app.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,10 @@ jobs:
1717
runs-on: ubuntu-latest
1818
steps:
1919
- uses: actions/checkout@v3
20-
- name: Set up Python 3.11
20+
- name: Set up Python 3.12
2121
uses: actions/setup-python@v4
2222
with:
23-
python-version: 3.11
23+
python-version: 3.12
2424
- name: Install dependencies
2525
run: |
2626
python -m pip install --upgrade pip
@@ -32,7 +32,7 @@ jobs:
3232
run: bandit -r . -x /tests
3333
- name: Check code formatting
3434
run: |
35-
black . -t py311 -l 120 --check
35+
black . -t py312 -l 120 --check
3636
isort . -c
3737
- name: Lint with flake8
3838
run: |

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ app/static/fonts*
66
app/static/govuk-frontend*
77
app/static/images*
88
app/static/VERSION.txt
9+
app/static/manifest.json
910
govuk_components*
1011

1112
### certificates ###

.python-version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
3.11
1+
3.12

Dockerfile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
FROM python:3.11-slim
1+
FROM python:3.12-slim
22

33
RUN useradd containeruser
44

@@ -17,5 +17,5 @@ ENV FLASK_APP=govuk-frontend-flask.py \
1717

1818
USER containeruser
1919

20-
EXPOSE 8000
20+
EXPOSE 9876
2121
ENTRYPOINT ["./docker-entrypoint.sh"]

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# GOV.UK Frontend Flask
22

3-
![govuk-frontend 4.7.0](https://img.shields.io/badge/govuk--frontend%20version-4.7.0-005EA5?logo=gov.uk&style=flat)
3+
![govuk-frontend 5.1.0](https://img.shields.io/badge/govuk--frontend%20version-5.1.0-005EA5?logo=gov.uk&style=flat)
44

55
**GOV.UK Frontend Flask is a [community tool](https://design-system.service.gov.uk/community/resources-and-tools/) of the [GOV.UK Design System](https://design-system.service.gov.uk/). The Design System team is not responsible for it and cannot support you with using it. Contact the [maintainers](#contributors) directly if you need [help](#support) or you want to request a feature.**
66

@@ -53,7 +53,7 @@ python -c 'import secrets; print(secrets.token_hex())'
5353
docker compose up --build
5454
```
5555

56-
You should now have the app running on <https://localhost:8000/>. Accept the browsers security warning due to the self-signed HTTPS certificate to continue.
56+
You should now have the app running on <https://localhost:9876/>. Accept the browsers security warning due to the self-signed HTTPS certificate to continue.
5757

5858
## Demos
5959

app/__init__.py

Lines changed: 49 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,17 +39,63 @@ def create_app(config_class=Config):
3939
"default-src": "'self'",
4040
"script-src": [
4141
"'self'",
42-
"'sha256-+6WnXIl4mbFTCARd8N3COQmT3bJJmo32N8q8ZSQAIcU='",
43-
"'sha256-l1eTVSK8DTnK8+yloud7wZUqFrI0atVo6VlC6PJvYaQ='",
42+
"'sha256-GUQ5ad8JK5KmEWmROf3LZd9ge94daqNvd8xy9YS1iDw='",
43+
"'sha256-EOlYC7YurunqHZxQoZ/zL5TKc/rPajg45h85KVyb5So='",
4444
],
4545
}
4646

47+
# Set permissions policy
48+
permissions_policy = {
49+
"accelerometer": "()",
50+
"ambient-light-sensor": "()",
51+
"autoplay": "()",
52+
"battery": "()",
53+
"camera": "()",
54+
"cross-origin-isolated": "()",
55+
"display-capture": "()",
56+
"document-domain": "()",
57+
"encrypted-media": "()",
58+
"execution-while-not-rendered": "()",
59+
"execution-while-out-of-viewport": "()",
60+
"fullscreen": "()",
61+
"geolocation": "()",
62+
"gyroscope": "()",
63+
"keyboard-map": "()",
64+
"magnetometer": "()",
65+
"microphone": "()",
66+
"midi": "()",
67+
"navigation-override": "()",
68+
"payment": "()",
69+
"picture-in-picture": "()",
70+
"publickey-credentials-get": "()",
71+
"screen-wake-lock": "()",
72+
"sync-xhr": "()",
73+
"usb": "()",
74+
"web-share": "()",
75+
"xr-spatial-tracking": "()",
76+
"clipboard-read": "()",
77+
"clipboard-write": "()",
78+
"gamepad": "()",
79+
"speaker-selection": "()",
80+
"conversion-measurement": "()",
81+
"focus-without-user-activation": "()",
82+
"hid": "()",
83+
"idle-detection": "()",
84+
"interest-cohort": "()",
85+
"serial": "()",
86+
"sync-script": "()",
87+
"trust-token-redemption": "()",
88+
"unload": "()",
89+
"window-management": "()",
90+
"vertical-scroll": "()",
91+
}
92+
4793
# Initialise app extensions
4894
assets.init_app(app)
4995
compress.init_app(app)
5096
csrf.init_app(app)
5197
limiter.init_app(app)
52-
talisman.init_app(app, content_security_policy=csp)
98+
talisman.init_app(app, content_security_policy=csp, permissions_policy=permissions_policy)
5399
WTFormsHelpers(app)
54100

55101
# Create static asset bundles

app/demos/forms.py

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -164,42 +164,42 @@ class KitchenSinkForm(FlaskForm):
164164
"StringField",
165165
widget=GovTextInput(),
166166
validators=[InputRequired(message="StringField is required")],
167-
description="Hint text: WTForm StringField rendered using a GovTextInput widget.",
167+
description="StringField rendered using a GovTextInput widget.",
168168
)
169169

170170
email_field = StringField(
171171
"EmailField",
172172
widget=GovTextInput(),
173173
validators=[InputRequired(message="EmailField is required"), Email()],
174-
description="Hint text: WTForm StringField rendered using a GovTextInput widget.",
174+
description="StringField rendered using a GovTextInput widget.",
175175
)
176176

177177
float_field = FloatField(
178178
"FloatField",
179179
widget=GovTextInput(),
180180
validators=[InputRequired(message="FloatField is required")],
181-
description="Hint text: WTForm FloatField rendered using a GovTextInput widget.",
181+
description="FloatField rendered using a GovTextInput widget.",
182182
)
183183

184184
integer_field = IntegerField(
185185
"IntegerField",
186186
widget=GovTextInput(),
187187
validators=[InputRequired(message="IntegerField is required")],
188-
description="Hint text: WTForm IntegerField rendered using a GovTextInput widget.",
188+
description="IntegerField rendered using a GovTextInput widget.",
189189
)
190190

191191
decimal_field = DecimalField(
192192
"DecimalField",
193193
widget=GovTextInput(),
194194
validators=[InputRequired(message="DecimalField is required")],
195-
description="Hint text: WTForm DecimalField rendered using a GovTextInput widget.",
195+
description="DecimalField rendered using a GovTextInput widget.",
196196
)
197197

198198
textarea_field = TextAreaField(
199199
"TextAreaField",
200200
widget=GovTextArea(),
201201
validators=[InputRequired(message="TextAreaField is required")],
202-
description="Hint text: WTForm TextAreaField rendered using a GovTextArea widget.",
202+
description="TextAreaField rendered using a GovTextArea widget.",
203203
)
204204

205205
charactercount_field = TextAreaField(
@@ -209,14 +209,14 @@ class KitchenSinkForm(FlaskForm):
209209
InputRequired(message="CharacterCountField is required"),
210210
Length(max=200, message="CharacterCountField must be 200 characters or fewer "),
211211
],
212-
description="Hint text: WTForm TextAreaField rendered using a GovCharacterCount widget.",
212+
description="TextAreaField rendered using a GovCharacterCount widget.",
213213
)
214214

215215
boolean_field = BooleanField(
216216
"BooleanField",
217217
widget=GovCheckboxInput(),
218218
validators=[InputRequired(message="Please tick the box")],
219-
description="Hint text: WTForm BooleanField rendered using a GovCheckboxInput widget.",
219+
description="BooleanField rendered using a GovCheckboxInput widget.",
220220
)
221221

222222
select_field = SelectField(
@@ -230,37 +230,37 @@ class KitchenSinkForm(FlaskForm):
230230
("three", "Three"),
231231
],
232232
default="",
233-
description="Hint text: WTForm SelectField rendered using a GovSelect widget.",
233+
description="SelectField rendered using a GovSelect widget.",
234234
)
235235

236236
select_multiple_field = SelectMultipleField(
237237
"SelectMultipleField",
238238
widget=GovCheckboxesInput(),
239239
validators=[InputRequired(message="Please select an option")],
240240
choices=[("one", "One"), ("two", "Two"), ("three", "Three")],
241-
description="Hint text: WTForm SelectMultipleField rendered using a GovCheckboxesInput widget.",
241+
description="SelectMultipleField rendered using a GovCheckboxesInput widget.",
242242
)
243243

244244
radio_field = RadioField(
245245
"RadioField",
246246
widget=GovRadioInput(),
247247
validators=[InputRequired(message="Please select an option")],
248248
choices=[("one", "One"), ("two", "Two"), ("three", "Three")],
249-
description="Hint text: WTForm RadioField rendered using a GovRadioInput widget.",
249+
description="RadioField rendered using a GovRadioInput widget.",
250250
)
251251

252252
file_field = FileField(
253253
"FileField",
254254
widget=GovFileInput(),
255255
validators=[InputRequired(message="Please upload a file")],
256-
description="Hint text: WTForm FileField rendered using a GovFileInput widget.",
256+
description="FileField rendered using a GovFileInput widget.",
257257
)
258258

259259
multiple_file_field = MultipleFileField(
260260
"MultipleFileField",
261261
widget=GovFileInput(multiple=True),
262262
validators=[InputRequired(message="Please upload a file")],
263-
description="Hint text: WTForm MultipleFileField rendered using a MultipleFileField widget.",
263+
description="MultipleFileField rendered using a MultipleFileField widget.",
264264
)
265265

266266
password_field = PasswordField(
@@ -273,21 +273,21 @@ class KitchenSinkForm(FlaskForm):
273273
message="Please ensure both password fields match",
274274
),
275275
],
276-
description="Hint text: WTForm PasswordField rendered using a GovPasswordInput widget.",
276+
description="PasswordField rendered using a GovPasswordInput widget.",
277277
)
278278

279279
date_field = DateField(
280280
"DateField",
281281
widget=GovDateInput(),
282282
validators=[InputRequired(message="DateField is required")],
283-
description="Hint text: WTForm DateField rendered using a GovDateInput widget.",
283+
description="DateField rendered using a GovDateInput widget.",
284284
)
285285

286286
date_time_field = DateTimeField(
287287
"DateTimeField",
288288
widget=GovDateInput(),
289289
validators=[InputRequired(message="DateTimeField is required")],
290-
description="Hint text: WTForm DateTimeField rendered using a GovDateInput widget.",
290+
description="DateTimeField rendered using a GovDateInput widget.",
291291
)
292292

293293
submit_button = SubmitField("SubmitField", widget=GovSubmitInput())

app/demos/routes.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import json
21
import os
32

3+
import yaml
44
from flask import flash, redirect, render_template, url_for
55
from werkzeug.exceptions import NotFound
66

@@ -19,12 +19,12 @@ def components():
1919
@bp.route("/components/<string:component>", methods=["GET"])
2020
def component(component):
2121
try:
22-
with open("govuk_components/{}/fixtures.json".format(component)) as json_file:
23-
fixtures = json.load(json_file)
22+
with open(f"govuk_components/{component}/{component}.yaml") as yaml_file:
23+
fixtures = yaml.safe_load(yaml_file)
2424
except FileNotFoundError:
2525
raise NotFound
2626

27-
return render_template("component.html", fixtures=fixtures)
27+
return render_template("component.html", component=component, fixtures=fixtures)
2828

2929

3030
@bp.route("/forms", methods=["GET"])

app/templates/base.html

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,7 @@
1313
<meta name="description" content="{{config['SERVICE_NAME']}}">
1414
<meta name="keywords" content="GOV.UK, govuk, gov, government, uk, frontend, ui, user interface, jinja, python, flask, port, template, templating, macro, component, design system, html, forms, wtf, wtforms, widget, widgets, demo, example">
1515
<meta name="author" content="{{config['DEPARTMENT_NAME']}}">
16-
<!--[if gt IE 8]><!--><link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='govuk-frontend-4.7.0.min.css') }}" /><!--<![endif]-->
17-
<!--[if IE 8]><link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='govuk-frontend-ie8-4.7.0.min.css') }}" /><![endif]-->
16+
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='govuk-frontend-5.1.0.min.css') }}" />
1817
{% assets "css" %}<link href="{{ ASSET_URL }}" rel="stylesheet">{% endassets %}
1918
{% endblock %}
2019

@@ -111,7 +110,8 @@
111110
{{ govukHeader({
112111
'homepageUrl': url_for('main.index'),
113112
'serviceName': config['SERVICE_NAME'],
114-
'serviceUrl': url_for('main.index')
113+
'serviceUrl': url_for('main.index'),
114+
'useTudorCrown': true
115115
}) }}
116116
{% endblock %}
117117

@@ -120,7 +120,7 @@
120120
'tag': {
121121
'text': config['SERVICE_PHASE']
122122
},
123-
'html': 'This is a new service – your <a class="govuk-link" href="mailto:' + config['CONTACT_EMAIL'] +'?subject=Feedback">feedback</a> will help us to improve it.'
123+
'html': 'This is a new service – your <a class="govuk-link" href="mailto:' + config['CONTACT_EMAIL'] + '">feedback</a> will help us to improve it.'
124124
}) }}
125125
{% endblock %}
126126

@@ -161,9 +161,10 @@
161161
{% endblock %}
162162

163163
{% block bodyEnd %}
164-
<!--[if gt IE 8]><!-->
165-
<script src="{{ url_for('static', filename='govuk-frontend-4.7.0.min.js') }}"> </script>
166-
<script>window.GOVUKFrontend.initAll()</script>
167-
<!--<![endif]-->
164+
<script type="module" src="{{ url_for('static', filename='govuk-frontend-5.1.0.min.js') }}"></script>
165+
<script type="module">
166+
import { initAll } from "{{ url_for('static', filename='govuk-frontend-5.1.0.min.js') }}"
167+
initAll()
168+
</script>
168169
{% assets "js" %}<script type="text/javascript" src="{{ ASSET_URL }}"></script>{% endassets %}
169170
{% endblock %}

0 commit comments

Comments
 (0)