Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 53 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,42 @@ If you're not using Nunjucks, change the existing GOV.UK header to a `<div>` ele

We made this change in [pull request #6536: Refactor heading to detach element from component](https://github.com/alphagov/govuk-frontend/pull/6536).

#### Update Nunjucks blocks around the GOV.UK footer

We've changed the structure of pages around the footer to separate the `<footer>` element from the GOV.UK footer component. This allows other components can be included within the `<footer>` of each page.

You will need to follow different upgrading instructions depending on the current state of your code. In all cases, you should ensure that the final page has a single `<footer>` element present.

If you're using GOV.UK Frontend's template and overriding the `govukFooter` component, update references to the `footer` Nunjucks block to use `govukFooter` instead.

```njk
{# Previously #}
{% block footer %}
{{ govukFooter() }}
{% endblock %}

{# Now #}
{% block govukFooter %}
{{ govukFooter() }}
{% endblock %}
```

If you're not using GOV.UK Frontend's template but are using the `govukFooter` component, update your template to include a `<footer>` element around the component.

If you're not using the `footer` Nunjucks block at any point, or you're only using the block in order to remove it, you don't need to change anything.

If you're not using Nunjucks, change the existing GOV.UK footer to a `<div>` element and wrap it with a `<footer>` element.

```html
<footer class="govuk-template__footer">
<div class="govuk-footer">
[...]
</div>
</footer>
```

We made this change in [pull request #6537: Refactor footer to detach element from component](https://github.com/alphagov/govuk-frontend/pull/6537).

### New features

#### Customise the template's `<header>` element
Expand All @@ -64,6 +100,23 @@ New Nunjucks blocks:

We made this change in [pull request #6536: Refactor heading to detach element from component](https://github.com/alphagov/govuk-frontend/pull/6536).

#### Customise the template's `<footer>` element

Nunjucks users can customise the appearance and content of the template's `<footer>` element with new blocks and variables.

New variables:

- `footerClasses` applies custom classes to the element.
- `footerAttributes` applies custom HTML attributes to the element.

New Nunjucks blocks:

- `footerStart` inserts HTML immediately after the element's opening tag.
- `footerEnd` inserts HTML immediately before the element's closing tag.
- `govukFooter` allows for customising the `govukFooter` component without affecting other parts of the footer.

We made this change in [pull request #6537: Refactor footer to detach element from component](https://github.com/alphagov/govuk-frontend/pull/6537).

### Fixes

#### Add `aria-hidden="true"` to the Service navigation's menu toggle
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

{%- set _rebrand = params.rebrand | default(govukRebrand() if govukRebrand is callable else govukRebrand) -%}

<footer class="govuk-footer {%- if params.classes %} {{ params.classes }}{% endif %}"
<div class="govuk-footer {%- if params.classes %} {{ params.classes }}{% endif %}"
{{- govukAttributes(params.attributes) }}>
<div class="govuk-width-container {%- if params.containerClasses %} {{ params.containerClasses }}{% endif %}">
{% if _rebrand %}
Expand Down Expand Up @@ -106,4 +106,4 @@
</div>
</div>
</div>
</footer>
</div>
106 changes: 103 additions & 3 deletions packages/govuk-frontend/src/govuk/template.jsdom.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -715,17 +715,70 @@ describe('Template', () => {
})

describe('<footer>', () => {
it('renders the <footer> element by default', () => {
replacePageWith(renderTemplate('govuk/template.njk'))
const $footer = document.querySelector('footer')

expect($footer).toBeInTheDocument()
expect($footer).toHaveClass('govuk-template__footer')
})

it('does not render the <footer> element if there is no content inside it', () => {
replacePageWith(
renderTemplate('govuk/template.njk', {
blocks: {
govukFooter: '',
footerStart: '',
footerEnd: ''
}
})
)

expect(document.querySelector('footer')).not.toBeInTheDocument()
})

it('can have custom classes added using footerClasses', () => {
replacePageWith(
renderTemplate('govuk/template.njk', {
context: {
footerClasses: 'custom-footer-class'
}
})
)

expect(document.querySelector('footer')).toHaveClass(
'custom-footer-class'
)
})

it('can have custom attributes added using footerAttributes', () => {
replacePageWith(
renderTemplate('govuk/template.njk', {
context: {
footerAttributes: {
'data-foo': 'bar'
}
}
})
)

expect(document.querySelector('footer')).toHaveAttribute(
'data-foo',
'bar'
)
})

it('can be overridden using the footer block', () => {
replacePageWith(
renderTemplate('govuk/template.njk', {
blocks: {
footer: '<div class="my-footer">footer</div>'
footer: '<mark>footer</mark>'
}
})
)

expect(document.querySelector('.my-footer')).toBeInTheDocument()
expect(document.querySelector('.govuk-footer')).toBeNull()
expect(document.querySelector('mark')).toBeInTheDocument()
expect(document.querySelector('.govuk-footer')).not.toBeInTheDocument()
})

it('sets the rebrand param to true by default if govukRebrand is true', () => {
Expand All @@ -741,6 +794,53 @@ describe('Template', () => {
document.querySelector('.govuk-footer .govuk-footer__crown')
).toBeInTheDocument()
})

describe('govukFooter block', () => {
it('allows content to be inserted using govukFooter', () => {
replacePageWith(
renderTemplate('govuk/template.njk', {
blocks: {
govukFooter: '<mark>govukFooter</mark>'
}
})
)

expect(document.querySelector('mark')).toBeInTheDocument()
expect(
document.querySelector('.govuk-footer')
).not.toBeInTheDocument()
})
})

describe('footerStart block', () => {
it('allows content to be inserted using footerStart', () => {
replacePageWith(
renderTemplate('govuk/template.njk', {
blocks: {
footerStart: '<mark>footerStart</mark>'
}
})
)

expect(document.querySelector('mark')).toBeInTheDocument()
expect(document.querySelector('.govuk-footer')).toBeInTheDocument()
})
})

describe('footerEnd block', () => {
it('allows content to be inserted using footerEnd', () => {
replacePageWith(
renderTemplate('govuk/template.njk', {
blocks: {
footerEnd: '<mark>footerEnd</mark>'
}
})
)

expect(document.querySelector('mark')).toBeInTheDocument()
expect(document.querySelector('.govuk-footer')).toBeInTheDocument()
})
})
})
})
})
21 changes: 18 additions & 3 deletions packages/govuk-frontend/src/govuk/template.njk
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,25 @@
</div>
{% endblock %}

{# Only output <footer> if any of its child blocks have content. #}
{% macro _govukTemplateFooter() %}
{%- if caller() | trim | length > 0 %}
<footer class="govuk-template__footer {%- if footerClasses %} {{ footerClasses }}{% endif %}" {{- govukAttributes(footerAttributes)}}>
{{ caller() }}
</footer>
{%- endif %}
{% endmacro %}

{% block footer %}
{{ govukFooter({
rebrand: _rebrand
}) }}
{% call _govukTemplateFooter() %}
{% block footerStart %}{% endblock %}
{% block govukFooter %}
{{ govukFooter({
rebrand: _rebrand
}) }}
{% endblock %}
{% block footerEnd %}{% endblock %}
{% endcall %}
{% endblock %}

{% block bodyEnd %}{% endblock %}
Expand Down