Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow custom image and font URL helpers #733

Merged
merged 3 commits into from
May 30, 2018
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
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,12 @@ Note: We're not following semantic versioning yet, we are going to talk about th
browser will then swap to NTA as long as it loads within the short swap period.
([PR #726](https://github.com/alphagov/govuk-frontend/pull/726))

- You can now override the helpers used to generate image and font urls, for
example if you are using sass-rails' asset-pipeline functionality.
You can do this by setting `$govuk-image-url-function` and
`$govuk-font-url-function` to the name of the function(s) you wish to use.
See `src/settings/_assets.scss` for more information and examples.
([PR #733](https://github.com/alphagov/govuk-frontend/pull/733))

🏠 Internal:

Expand Down
2 changes: 1 addition & 1 deletion src/settings/_all.scss
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// The order we import settings in is important, as some settings files rely on
// others

@import "paths";
@import "assets";

@import "compatibility";
@import "global-styles";
Expand Down
69 changes: 69 additions & 0 deletions src/settings/_assets.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/// Path to the assets directory, with trailing slash.
///
/// This is the directory where the images and fonts subdirectories live. You
/// will need to make this directory available via your application – see the
/// README for details.
///
/// @type String

$govuk-assets-path: "/assets/" !default;

/// Path to the images folder, with trailing slash.
///
/// @type String

$govuk-images-path: "#{$govuk-assets-path}images/" !default;

/// Path to the fonts folder, with trailing slash.
///
/// @type String

$govuk-fonts-path: "#{$govuk-assets-path}fonts/" !default;

/// Custom image URL function
///
/// If the built-in image URL helper does not meet your needs, you can specify
/// the name of a custom handler – either built in or by writing your own
/// function.
///
/// If you are writing your own handler, ensure that it returns a string wrapped
/// with `url()`
///
/// @type String
///
/// @example scss - Rails asset handling
/// $govuk-image-url-function: 'image-url';
///
/// @example scss - Custom asset handling
///
/// @function my-url-handler($filename) {
/// @return ''; // Some custom URL handling
/// }
///
/// $govuk-image-url-function: 'my-url-handler';

$govuk-image-url-function: false !default;

/// Custom font URL function
///
/// If the built-in font URL helper does not meet your needs, you can specify
/// the name of a custom handler – either built in or by writing your own
/// function.
///
/// If you are writing your own handler, ensure that it returns a string wrapped
/// with `url()`
///
/// @type String
///
/// @example scss - Rails asset handling
/// $govuk-font-url-function: 'font-url';
///
/// @example scss - Custom asset handling
///
/// @function my-url-handler($filename) {
/// @return ''; // Some custom URL handling
/// }
///
/// $govuk-font-url-function: 'my-url-handler';

$govuk-font-url-function: false !default;
12 changes: 0 additions & 12 deletions src/settings/_paths.scss

This file was deleted.

20 changes: 18 additions & 2 deletions src/tools/_font-url.scss
Original file line number Diff line number Diff line change
@@ -1,7 +1,23 @@
// Disable indentation linting in this file only
// sass-lint:disable indentation

/// Font URL
///
/// Returns a URL for the given font filename
/// If a custom font-url handler is defined ($govuk-font-url-function) then
/// it will be called, otherwise a url will be returned with the filename
/// appended to the font path.
///
/// @param {String} Font filename
/// @return {String} URL for the filename, wrapped in `url()`

@function govuk-font-url($filename) {
@return url($govuk-fonts-path + $filename);
$use-custom-function: variable-exists("govuk-font-url-function")
and $govuk-font-url-function
and function-exists($govuk-font-url-function);

@if ($use-custom-function) {
@return call($govuk-font-url-function, $filename);
} @else {
@return url($govuk-fonts-path + $filename);
}
}
20 changes: 18 additions & 2 deletions src/tools/_image-url.scss
Original file line number Diff line number Diff line change
@@ -1,7 +1,23 @@
// Disable indentation linting in this file only
// sass-lint:disable indentation

/// Image URL
///
/// Returns a URL for the given image filename
/// If a custom image-url handler is defined ($govuk-image-url-function) then
/// it will be called, otherwise a url will be returned with the filename
/// appended to the image path.
///
/// @param {String} Filename for the image to load
/// @return {String} URL for the filename, wrapped in `url()`

@function govuk-image-url($filename) {
@return url($govuk-images-path + $filename);
$use-custom-function: variable-exists("govuk-image-url-function")
and $govuk-image-url-function
and function-exists($govuk-image-url-function);

@if ($use-custom-function) {
@return call($govuk-image-url-function, $filename);
} @else {
@return url($govuk-images-path + $filename);
}
}
74 changes: 74 additions & 0 deletions src/tools/font-url.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/* eslint-env jest */

const util = require('util')

const configPaths = require('../../config/paths.json')

const sass = require('node-sass')
const sassRender = util.promisify(sass.render)

const sassConfig = {
includePaths: [ configPaths.src ],
outputStyle: 'compressed'
}

describe('@function font-url', () => {
it('by default concatenates the font path and the filename', async () => {
const sass = `
@import "tools/font-url";

$govuk-fonts-path: '/path/to/fonts/';

@font-face {
font-family: "whatever";
src: govuk-font-url("whatever.woff2");
}`

const results = await sassRender({ data: sass, ...sassConfig })

expect(results.css.toString().trim()).toEqual(
'@font-face{font-family:"whatever";src:url("/path/to/fonts/whatever.woff2")}'
)
})

it('can be overridden to use a defined Sass function', async () => {
const sass = `
@import "tools/font-url";

$govuk-font-url-function: 'to_upper_case';

@font-face {
font-family: "whatever";
src: govuk-font-url("whatever.woff2");
}`

const results = await sassRender({ data: sass, ...sassConfig })

expect(results.css.toString().trim()).toEqual(
'@font-face{font-family:"whatever";src:"WHATEVER.WOFF2"}'
)
})

it('can be overridden to use a custom function', async () => {
const sass = `
@import "tools/font-url";

@function custom-url-handler($filename) {
@return url("/custom/#{$filename}");
}

$govuk-fonts-path: '/assets/fonts/';
$govuk-font-url-function: 'custom-url-handler';

@font-face {
font-family: "whatever";
src: govuk-font-url("whatever.woff2");
}`

const results = await sassRender({ data: sass, ...sassConfig })

expect(results.css.toString().trim()).toEqual(
'@font-face{font-family:"whatever";src:url("/custom/whatever.woff2")}'
)
})
})
71 changes: 71 additions & 0 deletions src/tools/image-url.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/* eslint-env jest */

const util = require('util')

const configPaths = require('../../config/paths.json')

const sass = require('node-sass')
const sassRender = util.promisify(sass.render)

const sassConfig = {
includePaths: [ configPaths.src ],
outputStyle: 'compressed'
}

describe('@function image-url', () => {
it('by default concatenates the image path and the filename', async () => {
const sass = `
@import "tools/image-url";

$govuk-images-path: '/path/to/images/';

.foo {
background-image: govuk-image-url("baz.png");
}`

const results = await sassRender({ data: sass, ...sassConfig })

expect(results.css.toString().trim()).toEqual(
'.foo{background-image:url("/path/to/images/baz.png")}'
)
})

it('can be overridden to use a defined Sass function', async () => {
const sass = `
@import "tools/image-url";

$govuk-image-url-function: 'to_upper_case';

.foo {
background-image: govuk-image-url("baz.png");
}`

const results = await sassRender({ data: sass, ...sassConfig })

expect(results.css.toString().trim()).toEqual(
'.foo{background-image:"BAZ.PNG"}'
)
})

it('can be overridden to use a custom function', async () => {
const sass = `
@import "tools/image-url";

@function custom-url-handler($filename) {
@return url("/custom/#{$filename}");
}

$govuk-images-path: '/assets/fonts/';
$govuk-image-url-function: 'custom-url-handler';

.foo {
background-image: govuk-image-url("baz.png");
}`

const results = await sassRender({ data: sass, ...sassConfig })

expect(results.css.toString().trim()).toEqual(
'.foo{background-image:url("/custom/baz.png")}'
)
})
})