I wanted to share something cool with everyone - I’ve built a little timesaver by adding a couple of tasks to the gulpfile.js. It was inspired by this discussion: Cannot get @font-face to work with Sage/Sass
Sage does a nice job of grabbing the font files and flattening them into the dist/fonts
folder on compile, but I always had to do the other CSS part manually.
Because I often work with fonts from various places like Fontsquirrel (which often are generated with lots of junk files plus a file called stylesheet.scss
), I often end up with a bunch of seperate font folders which means I have to move everything into assets/fonts
, clean up the contents, and then manually copy and paste the contents of all the loose stylesheets into a single file, and then finally update the file references for /dist/ - and after doing this repeatedly you start feeling the frustration. I thought it would be great to use Gulp to automate the process so I can add and remove fonts as I like and not have to worry about updating @font-face references by hand. So here is my stab at doing that…
This assumes you have a directory in /assets/ with font folders arranged like:
/fonts/
/name-of-font-1/
(font files, .woff, .eot, .ttf etc)
stylesheet.css
/name-of-font-2/
(font files, .woff, .eot, .ttf etc)
stylesheet.css
/name-of-font-3/
(font files, .woff, .eot, .ttf etc)
stylesheet.css
Look out for my comments next to the lines I added or modified, in each of the code blocks below. If your folder structure differs to the one I have, you may need to amend the glob patterns in the fontcss
task.
First off in my terminal I add a couple of gulp plugins:
gulp install --save-dev gulp-concat-util gulp-replace
Then in gulpfile.js I modify the variable list to call the new plugins:
// ## Globals
var argv = require('minimist')(process.argv.slice(2));
var autoprefixer = require('gulp-autoprefixer');
var browserSync = require('browser-sync').create();
var changed = require('gulp-changed');
var concat = require('gulp-concat-util'); //Updated concat to concat-util
var flatten = require('gulp-flatten');
var gulp = require('gulp');
var gulpif = require('gulp-if');
var imagemin = require('gulp-imagemin');
var jshint = require('gulp-jshint');
var lazypipe = require('lazypipe');
var less = require('gulp-less');
var merge = require('merge-stream');
var minifyCss = require('gulp-minify-css');
var plumber = require('gulp-plumber');
var rev = require('gulp-rev');
var runSequence = require('run-sequence');
var sass = require('gulp-sass');
var sourcemaps = require('gulp-sourcemaps');
var uglify = require('gulp-uglify');
var replace = require('gulp-replace'); //Added variable for gulp-replace
After this I wrote two new tasks after the JSHint code block:
// ### Custom tasks
// Take all the fontcss stylesheets and concat them into a single SCSS file
gulp.task ('font-css', function() {
return gulp.src([path.source + 'fonts/**/stylesheet.css']) //Gather up all the 'stylesheet.css' files
.pipe(concat('_fonts.scss')) //Concat them all into a single file
.pipe(concat.header('/* !!! WARNING !!! \nThis file is auto-generated. \nDo not edit it or else you will lose changes next time you compile! */\n\n'))
.pipe(replace("url('", "url('../fonts/"))
.pipe(gulp.dest(path.source + ['styles/components'])); // Put them in the assets/styles/components folder
});
// Remove the font-face SCSS file if a cleanup is run
gulp.task('clean-font-css', require('del').bind(null, [path.source + 'styles/components/_fonts.scss']));
and then add the new fontcss
task to watch
, build
and clean
tasks:
// ### Watch
// `gulp watch` - Use BrowserSync to proxy your dev server and synchronize code
// changes across devices. Specify the hostname of your dev server at
// `manifest.config.devUrl`. When a modification is made to an asset, run the
// build step for that asset and inject the changes into the page.
// See: http://www.browsersync.io
gulp.task('watch', function() {
browserSync.init({
files: ['{lib,templates}/**/*.php', '*.php'],
proxy: config.devUrl,
snippetOptions: {
whitelist: ['/wp-admin/admin-ajax.php'],
blacklist: ['/wp-admin/**']
}
});
gulp.watch([path.source + 'fonts/**/stylesheet.css'], ['font-css']); //New fontcss task
gulp.watch([path.source + 'styles/**/*'], ['styles']);
gulp.watch([path.source + 'scripts/**/*'], ['jshint', 'scripts']);
gulp.watch([path.source + 'fonts/**/*'], ['fonts']);
gulp.watch([path.source + 'images/**/*'], ['images']);
gulp.watch(['bower.json', 'assets/manifest.json'], ['build']);
});
// ### Build
// `gulp build` - Run all the build tasks but don't clean up beforehand.
// Generally you should be running `gulp` instead of `gulp build`.
gulp.task('build', function(callback) {
runSequence(
'font-css', //New fontcss task
'styles',
'scripts',
['fonts', 'images'],
callback);
});
// ### Gulp
// `gulp` - Run a complete build. To compile for production run `gulp --production`.
gulp.task('default', ['clean', 'clean-font-css' /*New fontcss cleanup task*/], function() {
gulp.start('build');
});
Finally, I open /styles/main.scss
and add:
@import "components/_fonts"; // Import custom @font-face fonts
After all that you should be able to run gulp
to re-compile everything, and you should see all your fonts referenced nicely in dist/styles/main.css
. It also works with gulp watch
so you can move stuff in an out of the fonts
folder and have it all regenerate nicely
You’ll know it’s all working when you see extra tasks in the gulp output:
$ gulp
[06:55:45] Using gulpfile /var/www/clients/project/www/wp-content/themes/cheriemcom-theme/gulpfile.js
[06:55:45] Starting 'clean'...
[06:55:45] Starting 'clean-font-css'...
[06:55:45] Finished 'clean-font-css' after 8.96 ms
[06:55:46] Finished 'clean' after 78 ms
[06:55:46] Starting 'default'...
[06:55:46] Starting 'build'...
[06:55:46] Starting 'font-css'...
[06:55:46] Finished 'default' after 24 ms
[06:55:46] Finished 'font-css' after 193 ms
[06:55:46] Starting 'wiredep'...
[06:55:47] Finished 'wiredep' after 1.15 s
[06:55:47] Starting 'styles'...
[06:55:51] Finished 'styles' after 4.01 s
[06:55:51] Starting 'jshint'...
[06:55:51] Finished 'jshint' after 380 ms
[06:55:51] Starting 'scripts'...
[06:55:56] Finished 'scripts' after 4.57 s
[06:55:56] Starting 'fonts'...
[06:55:56] Starting 'images'...
[06:55:56] gulp-imagemin: Minified 0 images
[06:55:56] Finished 'images' after 14 ms
[06:55:56] Finished 'fonts' after 604 ms
[06:55:56] Finished 'build' after 11 s
/!\ A WORD OF CAUTION
This process generates a file here: assets/styles/components/_fonts.scss
which will be automatically generated every time something changes in your fonts
folder, so don’t do any manual editing in this file or you are prone to lose it all!
This is my first proper exploration into Gulp and it really is a thing of beauty. Hopefully it saves someone some time in their workflow It’s not fully tested but I haven’t seen any explosions so far. If there’s something here that could be improved I am all ears too.