├── assets
├── scss
│ ├── core
│ │ ├── _forms.scss
│ │ ├── _reset.scss
│ │ └── _typography.scss
│ ├── objects
│ │ └── _grid.scss
│ ├── templates
│ │ ├── _page.scss
│ │ ├── _archive.scss
│ │ ├── _single.scss
│ │ └── _search.scss
│ ├── components
│ │ ├── _global-footer.scss
│ │ ├── _global-footer-menu.scss
│ │ ├── _global-header.scss
│ │ ├── _pagination.scss
│ │ ├── _navigation.scss
│ │ └── _search-form.scss
│ ├── settings
│ │ └── _settings.scss
│ ├── overrides
│ │ └── _block-editor.scss
│ ├── helpers
│ │ ├── _colour.scss
│ │ ├── _typography.scss
│ │ ├── _aspect-ratio.scss
│ │ └── _font-faces.scss
│ ├── editor.scss
│ └── main.scss
└── js
│ ├── main.js
│ └── editor.js
├── templates
├── partials
│ ├── side-nav.php
│ ├── article.php
│ ├── pager.php
│ ├── entry-meta.php
│ ├── article-list-item.php
│ ├── breadcrumb.php
│ ├── head.php
│ ├── navigation.php
│ ├── search-form.php
│ ├── global-footer.php
│ └── global-header.php
├── index.php
├── single.php
├── functions.php
├── style.css
├── page.php
├── home.php
├── archive.php
├── 404.php
├── layouts
│ └── main.php
├── theme.json
└── search.php
├── .gitattributes
├── vendor.phar
├── app
├── load.php
├── Posts
│ ├── PostTypes.php
│ └── CustomFields.php
├── Theme
│ ├── TitleTag.php
│ ├── Menus.php
│ ├── Media.php
│ ├── Widgets.php
│ ├── WpHead.php
│ ├── Tables.php
│ └── Scripts.php
├── Blocks
│ └── BlockEditor.php
├── di.php
└── Lib
│ └── Whippet
│ └── TemplateTags.php
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── static
├── lib
│ └── govuk-frontend
│ │ └── dist
│ │ └── govuk
│ │ └── assets
│ │ ├── images
│ │ ├── favicon.ico
│ │ ├── govuk-icon-180.png
│ │ ├── govuk-icon-192.png
│ │ ├── govuk-icon-512.png
│ │ ├── govuk-opengraph-image.png
│ │ ├── favicon.svg
│ │ ├── govuk-icon-mask.svg
│ │ └── govuk-crest.svg
│ │ ├── rebrand
│ │ ├── images
│ │ │ ├── favicon.ico
│ │ │ ├── govuk-icon-180.png
│ │ │ ├── govuk-icon-192.png
│ │ │ ├── govuk-icon-512.png
│ │ │ ├── govuk-opengraph-image.png
│ │ │ ├── favicon.svg
│ │ │ ├── govuk-icon-mask.svg
│ │ │ └── govuk-crest.svg
│ │ └── manifest.json
│ │ ├── fonts
│ │ ├── bold-affa96571d-v2.woff
│ │ ├── bold-b542beb274-v2.woff2
│ │ ├── light-94a07e06a1-v2.woff2
│ │ └── light-f591b13f7d-v2.woff
│ │ └── manifest.json
├── editor.min.js
└── editor.min.css.map
├── peridot.php
├── .php_cs
├── .github
├── dependabot.yml
└── workflows
│ └── theme.yml
├── spec
├── posts
│ ├── post_types.spec.php
│ └── custom_fields.spec.php
├── blocks
│ └── block_editor.spec.php
├── lib
│ └── whippet
│ │ └── template_tags.spec.php
└── theme
│ ├── title_tag.spec.php
│ ├── menus.spec.php
│ ├── media.spec.php
│ ├── widgets.spec.php
│ ├── wp_head.spec.php
│ ├── tables.spec.php
│ └── scripts.spec.php
├── composer.json
├── COPYING.md
├── package.json
├── README.md
├── .gitignore
└── CHANGELOG.md
/assets/scss/core/_forms.scss:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/assets/scss/core/_reset.scss:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/assets/scss/objects/_grid.scss:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/assets/scss/templates/_page.scss:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/templates/partials/side-nav.php:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | /static/** -diff
2 |
--------------------------------------------------------------------------------
/assets/scss/templates/_archive.scss:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/assets/scss/templates/_single.scss:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/templates/index.php:
--------------------------------------------------------------------------------
1 | Don't use the index template.
--------------------------------------------------------------------------------
/vendor.phar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dxw/govuk-theme/HEAD/vendor.phar
--------------------------------------------------------------------------------
/assets/scss/components/_global-footer.scss:
--------------------------------------------------------------------------------
1 | .global-footer {
2 |
3 | }
4 |
--------------------------------------------------------------------------------
/assets/scss/settings/_settings.scss:
--------------------------------------------------------------------------------
1 | $govuk-page-width: 1200px !default;
2 |
--------------------------------------------------------------------------------
/assets/js/main.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | const GOVUKFrontend = require('govuk-frontend')
4 | GOVUKFrontend.initAll()
5 |
--------------------------------------------------------------------------------
/app/load.php:
--------------------------------------------------------------------------------
1 | register();
8 |
--------------------------------------------------------------------------------
/assets/scss/helpers/_colour.scss:
--------------------------------------------------------------------------------
1 | @function tint($color, $percentage) {
2 | @return mix(white, $color, $percentage);
3 | }
4 |
5 | @function shade($color, $percentage) {
6 | @return mix(black, $color, $percentage);
7 | }
8 |
--------------------------------------------------------------------------------
/app/Posts/PostTypes.php:
--------------------------------------------------------------------------------
1 | exclude('vendor')
5 | ->exclude('assets')
6 | ->exclude('static')
7 | ->exclude('templates')
8 | ->exclude('node_modules')
9 | ->in(__DIR__);
10 |
11 | return \Dxw\PhpCsFixerConfig\Config::create()
12 | ->setFinder($finder);
13 |
--------------------------------------------------------------------------------
/app/Theme/Menus.php:
--------------------------------------------------------------------------------
1 |
2 |
| ' => ' | ', 37 | ' | ' => ' | '
39 | ];
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/templates/theme.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": 2,
3 | "settings": {
4 | "color": {
5 | "custom": false,
6 | "customDuotone": false,
7 | "customGradient": false,
8 | "defaultPalette": false,
9 | "gradients": {},
10 | "link": false,
11 | "palette": [
12 | {
13 | "name": "Black",
14 | "slug": "black",
15 | "color": "#000"
16 | },
17 | {
18 | "name": "White",
19 | "slug": "white",
20 | "color": "#fff"
21 | },
22 | {
23 | "name": "Light Grey",
24 | "slug": "light-grey",
25 | "color": "#b1b4b6"
26 | }
27 | ]
28 | },
29 | "layout": {
30 | "contentSize": "960px",
31 | "wideSize": "1360px"
32 | },
33 | "typography": {
34 | "customFontSize": false,
35 | "lineHeight": true,
36 | "dropCap": false,
37 | "letterSpacing": false,
38 | "fontWeight": false,
39 | "fontSizes": [
40 | {
41 | "name": "Small",
42 | "slug": "normal",
43 | "size": "1rem"
44 | },
45 | {
46 | "name": "Normal",
47 | "slug": "normal",
48 | "size": "1.1875rem"
49 | },
50 | {
51 | "name": "Medium",
52 | "slug": "medium",
53 | "size": "1.5rem"
54 | },
55 | {
56 | "name": "Large",
57 | "slug": "large",
58 | "size": "2rem"
59 | },
60 | {
61 | "name": "Huge",
62 | "slug": "huge",
63 | "size": "3rem"
64 | }
65 | ]
66 | },
67 | "blocks": {
68 | "core/button": {
69 | "border": {
70 | "radius": false
71 | }
72 | }
73 | }
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/templates/search.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
6 |
7 | w_template_title(); ?>4 |
8 |
9 |
10 |
11 | found_posts ? $endCount : $wp_query->found_posts;
18 | ?>
19 |
20 |
21 |
47 |
--------------------------------------------------------------------------------
/static/lib/govuk-frontend/dist/govuk/assets/images/favicon.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/static/lib/govuk-frontend/dist/govuk/assets/rebrand/images/favicon.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/.github/workflows/theme.yml:
--------------------------------------------------------------------------------
1 | name: Theme
2 |
3 | on: push
4 |
5 | jobs:
6 | kahlan:
7 | runs-on: ubuntu-24.04
8 | strategy:
9 | matrix:
10 | php-versions: ['7.4']
11 | steps:
12 | - uses: actions/checkout@v4.2.2
13 | - name: Setup PHP
14 | uses: shivammathur/setup-php@v2
15 | with:
16 | php-version: ${{ matrix.php-versions }}
17 | - name: Get Composer Cache Directory
18 | id: composer-cache
19 | run: |
20 | echo "::set-output name=dir::$(composer config cache-files-dir)"
21 | - uses: actions/cache@v5
22 | with:
23 | path: ${{ steps.composer-cache.outputs.dir }}
24 | key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
25 | restore-keys: |
26 | ${{ runner.os }}-composer-
27 | - name: Install dependencies
28 | run: composer install --no-interaction
29 | - name: Run Kahlan tests
30 | run: vendor/bin/kahlan
31 | php-cs-fixer:
32 | runs-on: ubuntu-24.04
33 | strategy:
34 | matrix:
35 | php-versions: ['7.4']
36 | steps:
37 | - uses: actions/checkout@v4.2.2
38 | - name: Setup PHP
39 | uses: shivammathur/setup-php@v2
40 | with:
41 | php-version: ${{ matrix.php-versions }}
42 | - name: Get Composer Cache Directory
43 | id: composer-cache
44 | run: |
45 | echo "::set-output name=dir::$(composer config cache-files-dir)"
46 | - uses: actions/cache@v5
47 | with:
48 | path: ${{ steps.composer-cache.outputs.dir }}
49 | key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
50 | restore-keys: |
51 | ${{ runner.os }}-composer-
52 | - name: Install dependencies
53 | run: composer install --no-interaction
54 | - name: PHP CS fix
55 | run: vendor/bin/php-cs-fixer fix --dry-run -v --diff
56 |
--------------------------------------------------------------------------------
/app/Theme/Scripts.php:
--------------------------------------------------------------------------------
1 | registerFunction('assetPath', [$this, 'assetPath']);
10 | $helpers->registerFunction('getAssetPath', [$this, 'getAssetPath']);
11 | }
12 |
13 | public function register()
14 | {
15 | add_action('wp_enqueue_scripts', [$this, 'wpEnqueueScripts']);
16 | add_action('enqueue_block_editor_assets', [$this, 'wpEnqueueEditorScripts']);
17 | add_theme_support('editor-styles');
18 | add_editor_style('../static/editor.min.css');
19 | }
20 |
21 | public function getAssetPath($path)
22 | {
23 | return dirname(get_template_directory_uri()).'/static/'.$path;
24 | }
25 |
26 | public function assetPath($path)
27 | {
28 | echo esc_url($this->getAssetPath($path));
29 | }
30 |
31 | public function wpEnqueueScripts()
32 | {
33 | //
34 | // Do not add javascript to your theme here, unless you're sure you should.
35 | //
36 | // Normally, you should add Javascript to assets/js/main.js or make a file in assets/js/plugins.
37 | //
38 | // You can/should enqueue a script here only if it is a widely used library that is required by a plugin (or is likely to be later)
39 | //
40 |
41 | // Pretty much everything else should be compiled by Grunt.
42 | wp_enqueue_script('main', $this->getAssetPath('main.min.js'), ['jquery'], '', true);
43 |
44 | wp_enqueue_style('main', $this->getAssetPath('main.min.css'));
45 | }
46 |
47 | public function wpEnqueueEditorScripts()
48 | {
49 | wp_enqueue_script('theme-editor', $this->getAssetPath('editor.min.js'), ['wp-blocks', 'wp-dom'], filemtime(get_stylesheet_directory() . '/../assets/js/editor.js'), true);
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## IMPORTANT ##
2 | #
3 | # Usually a pattern here also belongs in your `.dockerignore` file and vice
4 | # versa.
5 | # Note that Docker's ignore syntax is slightly different to Git's. The main
6 | # difference is that Git interprets patterns without a leading slash as applying
7 | # to any subdirectory, while Docker interprets them as relative to the project
8 | # root directory. To resolve that, a `.dockerignore` should prefix those
9 | # patterns with `**/`. This is also compatible with Git.
10 | ## How to use this file
11 | # Add patterns to the section they apply to, sorted by:
12 | # 1. absolute paths to or patterns for files (with a `/` prefix)
13 | # 2. absolute paths to or patterns for directories
14 | # 3. relative paths to or patterns for files (without a `/` prefix)
15 | # 4. relative paths to or patterns for directories
16 | # 5. pattern exceptions (sorted as above)
17 | # Sort them alphanumerically within each section.
18 | # If no section fits, create one. No path or pattern should exist without a
19 | # section or label.
20 |
21 | ## Sensitive files
22 | # To override these ignored files on a case-by-case basis,
23 | # instead of adding a rule to this file, force add them:
24 | # ```
25 | # git add path/to/file --force
26 | # This reduces the risk of accidentally committing files that happen to match
27 | # the ignore pattern exception, or a file being removed and readded
28 | # unintentionally in the future.
29 | ### Databases
30 | *.db*
31 | *.dump*
32 | *.sql*
33 | *.sqlite3*
34 | ### Environment variables
35 | .env
36 | .env.*
37 | ### Logs
38 | *.log*
39 | ### Secrets and keys
40 | *.crt*
41 | *.key*
42 | *.pem*
43 | ### Spreadsheet data
44 | *.bks*
45 | *.csv*
46 | *.dex*
47 | *.numbers*
48 | *.ods*
49 | *.ots*
50 | *.tsv*
51 | *.xlr*
52 | *.xls*
53 | ### Terraform
54 | .terraformrc*
55 | terraform.rc*
56 | *.tfstate*
57 | *.tfvars*
58 | .terraform/
59 | ### XML data
60 | *.xml*
61 | ## Dependencies
62 | node_modules/
63 | vendor/
64 | ## WordPress media
65 | /wp-content/uploads
66 | ## Temporary files
67 | tmp/
68 | ## Build artifacts
69 | .php_cs.cache
70 | .sass-cache/
71 | *.bak*
72 |
--------------------------------------------------------------------------------
/spec/theme/wp_head.spec.php:
--------------------------------------------------------------------------------
1 | wpHead = new \Dxw\GovukTheme\Theme\WpHead();
6 | });
7 |
8 | afterEach(function () {
9 | });
10 |
11 | it('is registrable', function () {
12 | expect($this->wpHead)->toBeAnInstanceOf(\Dxw\Iguana\Registerable::class);
13 | });
14 |
15 | describe('->register()', function () {
16 | it('adds actions', function () {
17 | allow('add_action')->toBeCalled();
18 | expect('add_action')->toBeCalled()->once()->with('init', [$this->wpHead, 'init']);
19 | $this->wpHead->register();
20 | });
21 | });
22 |
23 | describe('->init()', function () {
24 | it('modifies the output of the WordPress head', function () {
25 | $actions = [
26 | ['wp_head', 'print_emoji_detection_script', 7],
27 | ['wp_print_styles', 'print_emoji_styles'],
28 | ['admin_print_styles', 'print_emoji_styles'],
29 | ['admin_print_scripts', 'print_emoji_detection_script'],
30 | ['wp_head', 'rsd_link'],
31 | ['wp_head', 'wp_generator'],
32 | ['wp_head', 'wlwmanifest_link'],
33 | ['wp_head', 'feed_links_extra', 3],
34 | ['wp_head', 'start_post_rel_link', 10, 0],
35 | ['wp_head', 'parent_post_rel_link', 10, 0],
36 | ['wp_head', 'adjacent_posts_rel_link', 10, 0],
37 | ];
38 |
39 | allow('remove_action')->toBeCalled();
40 |
41 | foreach ($actions as $args) {
42 | if (count($args) == 2) {
43 | list($a, $b) = $args;
44 | expect('remove_action')->toBeCalled()->once()->with($a, $b);
45 | }
46 | if (count($args) == 3) {
47 | list($a, $b, $c) = $args;
48 | expect('remove_action')->toBeCalled()->once()->with($a, $b, $c);
49 | }
50 | if (count($args) == 4) {
51 | list($a, $b, $c, $d) = $args;
52 | expect('remove_action')->toBeCalled()->once()->with($a, $b, $c, $d);
53 | }
54 | }
55 | $this->wpHead->init();
56 | });
57 | });
58 | });
59 |
--------------------------------------------------------------------------------
/spec/theme/tables.spec.php:
--------------------------------------------------------------------------------
1 | tables = new \Dxw\GovukTheme\Theme\Tables();
6 | });
7 |
8 | it('is registerable', function () {
9 | expect($this->tables)->toBeAnInstanceOf(\Dxw\Iguana\Registerable::class);
10 | });
11 |
12 | describe('->register()', function () {
13 | it('registers the filter', function () {
14 | allow('add_filter')->toBeCalled();
15 | expect('add_filter')->toBeCalled()->once()->with('render_block', [$this->tables, 'useGovukMarkup'], 10, 2);
16 | $this->tables->register();
17 | });
18 | });
19 |
20 | describe('->useGovukMarkup()', function () {
21 | context('this is not a core table block', function () {
22 | it('returns the block content unchanged', function () {
23 | $block['blockName'] = 'core/paragraph';
24 | $blockContent = 'Results to of found_posts ?>22 | 23 | 24 | 35 | 36 | 37 |
38 |
39 |
40 |
41 |
42 | No results found. 43 | 44 | 45 | 46 |
You're using a fallback template:Did you really mean to? If you can, define a specific template and use it. Like single-post.php.
3 |
40 |
41 |
42 |
4 |
5 |
30 |
31 |
32 |
33 |
39 |
34 |
38 |
35 | 'header-search-form']) ?>
36 |
37 | |
|---|