I have a grunt project backed by a yeoman-generator that I've built based on the generator-webapp
, if it's of any help, you can find it on GitHub
The grunt project makes us of the grunt-usemin
task.
My project involve building a multilingual website, and to keep things clean, I've decided to put all the pages written in a language in a folder name after the 2-letter shortcode of the said language.
| project/
|--dist/
|----en/
|------index.html
|------404.html
|------...
|----fr/
|------index.html
|------404.html
|------...
The files are made from handlebars templates and processed with assemble
. In the layout I have building blocks for usemin
such as
<!-- build:css(.tmp) styles/main.css -->
<link rel="stylesheet" href="../styles/main.css">
<!-- endbuild -->
<!-- build:js scripts/vendor/modernizr.js -->
<script src="../bower_components/modernizr/modernizr.js"></script>
<!-- endbuild -->
Which, in a perfect world would translate to
<link rel="stylesheet" href="../styles/main.css">
<script src="../scripts/vendor/modernizr.js"></script>
but instead shows
<link rel="stylesheet" href="styles/main.css">
<script src="scripts/vendor/modernizr.js"></script>
which is less than ideal in my case.
The relevant part of the Gruntfile.js
looks like this
useminPrepare: {
options: {
dest: '<%= yeoman.dist %>'
},
html: [
'<%= yeoman.app %>/fr/{,*/}*.html',
'<%= yeoman.app %>/en/{,*/}*.html'
]
},
usemin: {
options: {
dirs: ['<%= yeoman.dist %>']
},
html: [
'<%= yeoman.dist %>/fr/{,*/}*.html',
'<%= yeoman.dist %>/en/{,*/}*.html'
],
css: ['<%= yeoman.dist %>/styles/{,*/}*.css']
}
I have tried to use the basedir
option
by setting it to <%= yeoman.dist %>
as well as changing the build blocks to
<!-- build:css(.tmp) ../styles/main.css -->
<link rel="stylesheet" href="../styles/main.css">
<!-- endbuild -->
<!-- build:js ../scripts/vendor/modernizr.js -->
<script src="../bower_components/modernizr/modernizr.js"></script>
<!-- endbuild -->
But unfortunately wasn't able to get a proper output.
More specifically, the first one didn't change anything, the second one had the folders scripts
and styles
outputted one level too high in the hierarchy
| project/
|--app/
|--dist/
|--styles/
|--scripts/
instead of
| project/
|--app/
|--dist/
|----styles/
|----scripts/
Would anyone happen to know what to do ? It seems a rather simple usecase but I couldn't find the help I need via Google, GitHub or SO...
I believe that you can achieve what you need in this way:
Html file:
<!-- build:css styles/main.css -->
<link href='../styles/css/style.css' rel='stylesheet' type='text/css'>
<link href='../styles/css/responsive.css' rel='stylesheet' type='text/css'>
<link href="../styles/css/skins/welld.css" rel='stylesheet' type='text/css' id="skin-file">
<!-- endbuild -->
Gruntfile.js
useminPrepare: {
options: {
dest: '<%= yeoman.dist %>/'
},
html: ['<%= yeoman.app %>/snippets/head.html','<%= yeoman.app %>/snippets/tail.html']
},
usemin: {
options: {
dirs: ['<%= yeoman.dist %>/'],
blockReplacements: {
css: function (block) {
return '<link rel="stylesheet" href="../' + block.dest + '"/>';
},
js: function (block) {
return '<script src="../' + block.dest + '"></script>';
}
}
},
html: ['<%= yeoman.dist %>/{,*/}*.html'],
css: ['<%= yeoman.dist %>/styles/{,*/}*.css']
}
The key solution is in the blockReplacements
option of the usemin task. Basically, the task will put your files under <%= yeoman.dist %>/styles/main.css, while your html will be under <%= yeoman.dist %>/en/somefileinEnglish.html and every instance of 'styles/main.css' in this file will be replaced with '../styles/main.css', adding the correct relative path.
As an extra tip, if you are building a multilingual website, you may want to consider grunt-i18n to translate your file while building, so you won't need to maintain a different html file for every language.