I have a Laravel directory structure and I have my Jade templates in the /resources/assets/jade/ folder.
Inside this folder will have multiple sub-directories which I will need to copy their exact structure to the /public/app/ directory where my app will be served from..
I have also got Typescript files being compiled into the same directory structure so its very important that the directory layout is copied as I have set it up.. I cant seem to do this successfully using the Grunt Pug plugin.. any help greatly appreciated, heres what I have so far:
module.exports = function(grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
pug: {
compile: {
options: {
client: false,
pretty: true,
data: {
debug: false
}
},
files: [{
'public/app/index.html': ['resources/assets/jade/index.jade']
},
{
src: "resources/assets/jade/*.jade",
dest: "public/app",
expand: true,
ext: ".html"
} ]
}
},
});
grunt.loadNpmTasks('grunt-contrib-pug');
grunt.registerTask('default', ['pug'] );
};
Looks like the old grunt-contrib-jade syntax works with PUG although I didnt see it documented anywhere so for dexterity heres what works perfectly:
module.exports = function(grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
pug: {
compile: {
options: {
client: false,
pretty: true
},
files: [ {
cwd: "resources/assets/jade",
src: "**/*.jade",
dest: "public/app",
expand: true,
ext: ".html"
} ]
}
},
});
grunt.loadNpmTasks('grunt-contrib-pug');
grunt.registerTask('default', ['pug'] );
};
Related
I'm setting a grunt file for a task. My goal is to create a css file from a sass file (scss) and add an autoprefix to all the proprieties which require so. Initially I used the propriety multifiles but it didn't work, so now I'm using the target propriety that works fine, but my problem is, even if I target the very same file, it will create another file in my folder where I put all my sass files.
So far my file is the following:
module.exports = function (grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
sass: {
dev: {
options: {
style: 'expanded',
sourcemap: 'none',
},
files: {
'../style.css': 'scss/style.scss'
}
},
dist: {
options: {
style: 'compressed',
sourcemap: 'none',
},
files: {
'../style-min.css': 'scss/style.scss'
}
}
},
autoprefixer: {
options: {
browsers: ['last 6 versions']
},
target: {
expand: true,
flatten: true,
src: '../style.css',
dest: ''
}
},
watch: {
css: {
files: '**/*.scss',
tasks: ['sass', 'autoprefixer']
}
},
});
grunt.loadNpmTasks('grunt-contrib-sass');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-autoprefixer');
grunt.registerTask('default', ['watch']);
}
My goal is to set up a global task for all my css files, like so:
target: {
expand: true,
flatten: true,
src: '*.css',
dest: ''
}
but it is not working even if I try something like:
target: {
expand: true,
flatten: true,
src: '../*.css',
dest: ''
}
Does anyone know why?
Use cwd (stands for current working directory) which is the path where grunt looks for the files matching the pattern in src. Also define the dest so that it would create the destination file in the same folder.
target: {
expand: true,
flatten: true,
cwd: '../',
src: [ '**/*.css' ],
dest: '../'
}
I must be missing something very simple here. I'm trying to write a function task that deals with files. The Grunt API docs mention that you can [Build the files object dynamically], but for some reason I can't get this to work. A simplified version of my Gruntfile.js file looks like this:
module.exports = function(grunt) {
grunt.initConfig({
proj: {
build: {
files: [{
expand: true,
cwd: 'src',
src: ['**/*.js'],
dest: 'dist'
}]
}
}
});
grunt.registerTask('proj', function(){
var files = grunt.config('proj.build.files');
console.log(files);
});
};
I expect the log to show a list of file mappings from the src directory to the dist directory. What actually gets logged is the object proj.build.files from the config, like this:
Running "proj:build" task
[ { expand: true, cwd: 'src', src: [ '**/*.js' ], dest: 'dist' } ]
Done, without errors.
The API docs only talk about this type of configuration in terms of other tasks. I tried looking through the uglify task to see how the file mappings are retrieved, but I couldn't figure it out.
Here is the workaround I found to dynamically build filesets for Grunt tasks:
uglify: {
app: {
files: [{
src: '{<%= _prefixSrc(pkg.target, pkg.resources.js) %>}', // Note the brackets!
dest: '<%= pkg.target %>min/<%= pkg.name %>.min.js'
}]
}
},
_prefixSrc: function(prefix, files) {
return files.map(function(file){
return prefix + file;
});
},
See also this issue/feature request on GitHub and feel free to comment it if you find it useful: https://github.com/gruntjs/grunt/issues/1307
You can use rename function to change file name is files object like below...
build: {
files: [{
expand: true,
cwd: 'src',
src: ['**/*.js'],
dest: 'dist',
rename: function(dest, src) {
/*
rename logic
you will have access to src and dest name and can return desirect name from this function.
*/
return src+123;
}
}]
}
I'm using Yeoman template to develop a static web site. grunt serve nicely works with the auto reload plugin.
For repeating elements I started to use {{mustache}} partials and it works like a blast. Now I want the auto reload to assemble my page, so I can look at the resulting page when editing one of the mustache files (either a main file or a partial).
I found a grunt task for it, but stitching it together eludes me. My config looks like this:
grunt.initConfig({
sass: {
dev: {
src: ['src/sass/*.sass'],
dest: 'dest/css/index.css',
},
},
watch: {
sass: {
// We watch and compile sass files as normal but don't live reload here
files: ['src/sass/*.sass'],
tasks: ['sass']
},
mustache: {
files: '**/*.mustache',
tasks: ['mustache_render'],
options: {
interrupt: true
},
},
livereload: {
options: { livereload: true },
files: ['dest/**/*']
}
},
mustache_render: {
options: {
{data: 'common-data.json'}
},
your_target: {
files: [
{expand: true,
template: '**/*.mustache',
dest: 'dest/'}
]
}
}
});
I must be missing something since the html files are not updated when I save the file.
You can add the livereload option directly to your mustache target options.
grunt.initConfig({
watch: {
mustache: {
files: '**/*.mustache',
tasks: ['mustache_render'],
options: {
interrupt: true,
livereload: true
},
}
},
mustache_render: {
options: {
{data: 'common-data.json'}
},
main: {
files: [
{expand: true,
template: '**/*.mustache',
dest: 'dest/'}
]
}
}
});
Also, if you're using grunt-contrib-connect to serve your files, don't forget to add the livereload option to it:
connect: {
http: {
options: {
hostname: "*",
port: process.env.PORT || 80,
livereload: true
}
}
}
I have this setup in my Gruntfile.js
module.exports = function(grunt) {
grunt.initConfig({
less: {
development: {
options: {
compress: false,
yuicompress: false,
optimization: 0
},
files: {
// target.css file: source.less file
"assets/css/main.css": "assets/css/main.less"
},
}
},
watch: {
styles: {
// Which files to watch (all .less files recursively in the less directory)
files: ['assets/css/*.less', 'assets/less/*.less'],
tasks: ['less'],
},
// Live reload CSS
css: {
files: ['assets/css/*.css'],
options: {
nospawn: true,
interrupt: false,
livereload: true,
},
},
},
});
// Watch
grunt.loadNpmTasks('grunt-contrib-watch');
// Less Complile
grunt.loadNpmTasks('grunt-contrib-less');
grunt.registerTask('default', ['less','watch']);
};
My sylesheet is loaded like this:
<link rel="stylesheet" href="http://project.dev/wp-content/themes/project/style.css">
Whenever I change the css file the I get a 404 error in the browser for this url
http://project.dev/assets/css/main.css?livereload=1392748371895
Which is of course right because the css file lives in:
http://project.dev/wp-content/themes/project/assets/css/main.css
How do I get live reload to get the right URL?
You have to set the base so that Grunt knows where to run the application from. The files the tasks output should be set to reflect the structure Wordpress expects. Its all in the path configuration.
You can achieve a more flexible path structure if you configure it early on Grunt's configuration. Assuming that the Gruntfile.js is in the root of your site (besides the wp-content directory), you could do the following configuration:
grunt.initConfig({
// configurable paths
cfg: {
dist: './wp-content/themes/project'
},
// tasks configurations come here...
});
Then on the watch task, you'd set:
livereload: {
files: ['<%= cfg.dist %>/assets/css/*.css'],
options: {
nospawn: true,
interrupt: false,
livereload: true
}
}
The resulting Gruntfile.js would look like:
module.exports = function(grunt) {
grunt.initConfig({
// configurable paths
cfg: {
dist: './wp-content/themes/project'
},
less: {
development: {
options: {
compress: false,
yuicompress: false,
optimization: 0
},
files: {
'<%= cfg.dist %>/assets/css/main.css': '<%= cfg.dist %>/assets/css/main.less'
}
}
},
watch: {
styles: {
files: ['<%= cfg.dist %>/assets/css/*.less', '<%= cfg.dist %>/assets/less/*.less'],
tasks: ['less']
},
css: {
files: ['<%= cfg.dist %>/assets/css/*.css'],
options: {
nospawn: true,
interrupt: false,
livereload: true
}
}
}
});
grunt.loadNpmTasks('grunt-contrib-less');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.registerTask('default', ['less','watch']);
};
You'd still have to adjust the above to fit your needs, but the principle is there.
I don't have a setup I can test this on, but I think you need to set the base option:
// Project configuration.
grunt.initConfig({
connect: {
server: {
options: {
base: 'www-root'
}
}
}
});
See doc here: https://github.com/gruntjs/grunt-contrib-connect/blob/master/README.md#basic-use
Read down through multiple servers if relevant.
For a single page app that I'm working on, I have the following structure:
dist
css
js
lib
partials
index.html
src
css
js
lib
views
partials
index.jade
Directory dist will be used by the express server to serve the project. I have trivial grunt tasks (using grunt-contrib-clean, grunt-contrib-copy) for cleaning dist and copying src/css, src/js, src/lib to dist.
The problem lies with src/views. This directory contains jade files which need to be compiled to html files. After compilation I want them in dist (index.html in the dist root, partials as subdir).
At the moment I am using the grunt-contrib-jade task to compile and copy the jade files. I want to copy them to dist, since I don't want to add the compiled html files to source control. But now this is not really workable, since you have to specify every jade file (now there are only a few, but that will grow):
jade: {
compile: {
options: {
pretty: true
},
files: {
// TODO make one line
'dist/index.html': ['src/views/index.jade'],
'dist/partials/banner.html': ['src/views/partials/banner.jade'],
'dist/partials/dashboard.html': ['src/views/partials/dashboard.jade'],
'dist/partials/navbar.html': ['src/views/partials/navbar.jade'],
'dist/partials/transfer.html': ['src/views/partials/transfer.jade']
}
}
},
Is there any way to use the grunt-contrib-jade task (or another one) with a directory filter? Like this:
jade: {
compile: {
options: {
pretty: true
},
dir: {
'dist': ['src/views']
}
}
}
Little clarification from Grunt wiki - expand mapping:
grunt.file.expandMapping(patterns, dest [, options])
Note that while this method may be used to programmatically generate a files array for a multi task, the declarative syntax for doing this described in the "Building the files object dynamically" section of the Configuring tasks guide is preferred.
Assuming the above, configuration will look like this:
files: [ {
expand: true,
src: "**/*.jade",
dest: "dist/",
cwd: "src/views",
ext: '.html'
} ];
Same result with declarative configuration.
I ended up upgrading to grunt 0.4 (which causes some other problems, but that I'll be able to handle).
With grunt version 0.4 it is possible to use grunt.file.expandMapping:
jade: {
compile: {
options: {
pretty: true
},
files: grunt.file.expandMapping(['**/*.jade'], 'dist/', {
cwd: 'src/views',
rename: function(destBase, destPath) {
return destBase + destPath.replace(/\.jade$/, '.html');
}
})
}
},
If you want to change only the extension of the files from .jade to .html, another option would be using the flatten and ext parameters like so:
jade: {
compile: {
options: {
data: { debug: false, title: 'My awesome application' }
},
files: grunt.file.expandMapping(['**/*.jade'], '<%= yeoman.dist %>/views', {
cwd: '<%= yeoman.app %>/views',
flatten: true,
ext: '.html'
})
}
}
Or even better (as explained here):
jade: {
compile: {
options: {
data: { debug: false, title: 'My awesome application' },
pretty: true
},
files: [
{
expand: true,
cwd: '<%= yeoman.app %>/views',
src: ['**/*.jade'],
dest: '<%= yeoman.dist %>/views',
ext: '.html'
}
]}
}
Thanks.