As part of building a modified version of the Matrix template I wanted to use different style of icons. There are numerous sites and resources so finding appropriate ones has not been too difficult. The challenge has been getting them all into a single SVG file and to display correctly. Patrick has provided excellent instructions as part of the matrix install.
However the solution doesn’t work quite so well with other icons and SVG files from the wild. Abit of digging around found some simple setup and automation tools which also then helped me solve the issue of icons not always displaying well. (Part Two).
Let’s get start with Part One and Grunt.
Grunt is a Node based javascript task runner into which you can install various plugins to perform certain tasks and runs off
The great news is if you are using openHabian you already have node installed (or available to install). There is an excellent getting started guide which explains all the details as you want to.
Install Grunt
sudo npm install -g grunt-cli
Working Directory.
Now that Grunt is installed we need to setup some file in our working project directory to tell it what to do. For this tutorial let’s assume you are working on a new html theme called ‘jungle’ . (odd same theme as me). (This is not a tutorial on project directory structure)
So using the openhab directory structure
html/jungle
At the root of our jungle folder we need to create a config.json file.
nano config.json
Copy in the following code.
{
"name": "jungle habpanel dashboard",
"version": "0.1.0",
"devDependencies": {
"grunt": "^1.0.4",
"grunt-contrib-nodeunit": "^2.0.0",
"grunt-svg-sprite": "^1.5.0",
"minimatch": "^3.0.4"
},
}
(note the versions differ from getting started which caused me no end of problems with install grunt-svg-sprite)
Install the plugins.
sudo npm install grunt --save-dev
sudo npm install grunt-svg-sprite --save-dev
Hopefully node should install all the modules with no errors - Please let me know if there are any as I had to muck around abit before getting everything working and I may have missed something.
Create Gruntfile.js
The gruntfile contains the task instructions/configuration of what we want grunt to do. In this case clean and compress our SVG files. This is done by the grunt-svg-sprite plugin.
There is however a very handy gui configurator I found (after reading down in the underlying svg-sprite documentation).
http://jkphl.github.io/svg-sprite/#json
Let get a basic gruntfile setup. - Full file is in the code fence below.
Main Output Directory = out
Logging = Your call
Toggle SVG shape properties open
Toggle Dimensions open
Max. shape width = 50
Max. shape height = 50
Toggle Spacing
Padding on all edges = 10
Toggle Output modes
defs sprite = configure
Render HTML example = enable (optional but nice to see check things)
(see notes at end)
Now at the bottom you can select the ‘Gruntfile’ panel and there is your almost completed file.
'use strict';
var baseDir = 'svg/base/dir', // <-- Set to your SVG base directory
svgGlob = '**/*.svg', // <-- Glob to match your SVG files
outDir = 'output/dir', // <-- Main output directory
config = {
"dest": "out",
"shape": {
"dimension": {
"maxWidth": 50,
"maxHeight": 50
},
"spacing": {
"padding": 10
}
},
"mode": {
"defs": {
"example": true
}
}
};
module.exports = function(grunt) {
// Project configuration
grunt.initConfig({
// svg-sprite configuration
svg_sprite : {
dist : {
expand : true,
cwd : baseDir,
src : [svgGlob],
dest : outDir,
options : config
}
}
});
// These plugins provide necessary tasks
grunt.loadNpmTasks('grunt-svg-sprite');
// By default, compile the sprite(s)
grunt.registerTask('default', ['svg_sprite']);
};
Copy over to your favourite text editor and make the following updates.
var baseDir = 'original_svgs', // <-- Set to your SVG base directory
svgGlob = '**/*.svg', // <-- Glob to match your SVG files
outDir = 'out', // <-- Main output directory
Ready to go!
Load all your individual svgs into the ‘original_svgs’ folder
From a command line at the root of the project folder ‘/html/jungle’ run grunt.
grunt
If all goes well then you will have a new directory structure under /out which looks like this.
With the compiled file ‘sprite.def.svg’ . You can now copy this back to your root html for direct calls in your html code/habpanel. (there is probably a grunt plugin that does this as well!).
Happy grunting.
Note: defs vs symbols.
When I was working this all out I found that the compiled symbols file icons did not appear when referenced by ID, so I tried defs and had much better success with symbols appearing in my panel. (helpful hint for Chrome user press control key while clicking refresh forces a cache reload).
Since my workflow of compiling icons is setup I was able to focus on some icons did not display well, or inconsistent sized. Part 2 will cover this in Inkscape. This may also resolve the defs vs symbols issue.