Skip to content

Data lead

Building out representations of systems can make maintenance of templates and data an issue.

If you think about a page of citizens you can click into to view more information, then this could be required to build several views that do the same thing.

It also means data can be used to keep things consistent. If we wanted to use that information across a range of pages.

There are various ways to do routing and data lookup - we can make use of the URL params

Before you start

This assumes you have a working prototype, if not go to setup, then do the following:

Terminal window
npm install git@github.com:htmlandbacon/govuk-prototype-personas.git

This installs a set of user data you can use for this example.

Breakdown

We’ll need to do the following steps to a data view:

  1. The screens (list and various views)
  2. Routing
  3. Data lookup

The screens

We have two screens for this, first a list of citizens, and second the actual citizen page.

For the list of citizens we can make use of the summary cards using the plugin from the data and functions section.

/app/views/citizens.njk
{% extends "layouts/main.html" %}
{% block pageTitle %} Citizen List {% endblock %}
{% block content %}
<div class="govuk-grid-row">
<div class="govuk-grid-column-two-thirds">
<h1 govuk-heading-xl>Citizen List</h1>
{# get a list of all citizens from the plugin #}
{% set citizens = getCitizens() %}
{# loop over the data #}
{% for citizen in citizens %}
{# if you want to see the values of citizen do {{ citizen | dump }} #}
{# use govukSummaryList to output the details #}
{{
govukSummaryList({
card: {
title: {
text: citizen.name
},
actions: {
items: [
{
href: "/citizen?slug=" + citizen.slug,
text: "View choice",
visuallyHiddenText: citizen.name
}
]
}
},
rows: [
{
key: {
text: "ID"
},
value: {
html: citizen.national_insurance_number
}
},
{
key: {
text: "Phone"
},
value: {
html: citizen.contacts.phone
}
}
]
})
}}
{% endfor %}
</div>
</div>
{% endblock %}

For the single view we can use the summary list to display the address.

/app/views/citizen.njk
{% extends "layouts/main.html" %}
{# look up the data based on the slug #}
{% set citizen = getCitizenBySlug(data.slug) %}
{% block pageTitle %} {{ citizen.name }} Citizen{% endblock %}
{% block beforeContent %}
{# add a back link for ease of browsing #}
{{
govukBackLink({
text: "Back",
href: "javascript:window.history.back()"
})
}}
{% endblock %}
{% block content %}
<div class="govuk-grid-row">
<div class="govuk-grid-column-two-thirds">
<h1 govuk-heading-m>Details for {{ citizen.name }}</h1>
{# if you want to the the values of citizen do {{ citizen | dump }} #}
{# use govukSummaryList to output the details #}
{{
govukSummaryList({
rows: [
{
key: {
text: "ID"
},
value: {
text: citizen.national_insurance_number
}
},
{
key: {
text: "Date of birth"
},
value: {
text: citizen.dob
}
},
{
key: {
text: "Address"
},
value: {
text: citizen.addresses | length + " Found"
}
},
{
key: {
text: "Phone"
},
value: {
text: citizen.contacts.phone
}
},
{
key: {
text: "Email"
},
value: {
text: citizen.contacts.email
}
}
]
})
}}
</div>
</div>
{% endblock %}

Routing

The prototype kit turns URLs into files, assuming you named your files citizens.njk and citizen.njk then the URLs /citizens and /citizen should work, if you named them something else, or put them in a subfolder then they should work in the same way.

For the individual view, we’ve used the URL param slug that gets auto-populated into the view.

We could use routes and route parameters to make URLs look more fixed, but it would behave in the same way.

Data lookup

This means we can loop over the citizens anywhere in our views.

For the individual screen, we are using:

{% set citizens = getCitizens() %}

This means we can loop over the citizens any where in our views.

For the individual screen we are using:

{% set citizen = getCitizenBySlug(data.slug) %}

Where data.slug is the value from the URL.

This doesn’t have to be driven by a variable in some views we may want to fix this, we can do this by providing our own slug

Exercises

  1. Change the list view to a table hint: you may want to do this as html
  2. Expose the addresses on the individual view
  3. Add a second URL paramter of partner_slug and use this to add partner information to the individual view