GruntJS glob as source - javascript

I have a huge array like
[ { src:
[ './src/branding/appLogo/template.hbs',
'./src/buttons/append/template.hbs',
'./src/buttons/button/template.hbs',
'./src/buttons/clean/template.hbs',
'./src/buttons/clear/template.hbs',
'./src/buttons/danger/template.hbs',
'./src/buttons/default/template.hbs',
'./src/buttons/disabled/template.hbs',
'./src/buttons/large/template.hbs',
'./src/buttons/link/template.hbs',
'./src/buttons/primary/template.hbs',
'./src/buttons/small/template.hbs',
'./src/buttons/success/template.hbs',
'./src/documentation/technology-overview/template.hbs',
'./src/forms/checkbox/template.hbs',
'./src/forms/fieldAppend/template.hbs',
'./src/forms/fieldDefault/template.hbs',
'./src/forms/fieldError/template.hbs',
'./src/forms/fieldPrepend/template.hbs',
'./src/forms/fieldPrependAppend/template.hbs',
'./src/forms/radioButton/template.hbs',
'./src/forms/select/template.hbs',
'./src/forms/textarea/template.hbs',
'./src/icons/appSwitch/template.hbs',
'./src/modules/alerts/template.hbs',
'./src/modules/attributions/template.hbs',
'./src/modules/avatar/template.hbs',
'./src/modules/beacon/template.hbs',
'./src/modules/d3DonutChart/template.hbs',
'./src/navigation/appSwitcher/template.hbs',
'./src/navigation/avatarDropdown/template.hbs',
'./src/navigation/contextMenu/template.hbs',
'./src/navigation/headerMenu/template.hbs',
'./src/navigation/paginate/template.hbs',
'./src/prototypes/home/template.hbs',
'./src/structures/form/template.hbs',
'./src/structures/header/template.hbs',
'./src/typography/blockquote/template.hbs',
'./src/typography/floats/template.hbs',
'./src/typography/headers/template.hbs',
'./src/typography/hidden/template.hbs',
'./src/typography/hr/template.hbs',
'./src/typography/hrText/template.hbs',
'./src/typography/lists/template.hbs',
'./src/typography/paragraph/template.hbs',
'./src/typography/pre/template.hbs',
'./src/typography/table/template.hbs',
'./src/typography/tags/template.hbs',
'./src/utilities/extends/template.hbs',
'./src/utilities/keyframes/template.hbs',
'./src/utilities/mixins/template.hbs',
'./src/utilities/svgFilterPieShrink/template.hbs',
'./src/utilities/svgFilterSubtleDropShadow/template.hbs' ],
dest: './build/scripts/handlebars.js' } ]
I want to render all those handlebars templates and they should all end up in a single file.
module.exports = (grunt) ->
config = grunt.file.readJSON("config.json")
hbsGlob = ''
grunt.task.loadTasks('./tasks')
grunt.option('config', config)
grunt.initConfig
pkg: grunt.file.readJSON("package.json")
handlebars:
options:
namespace: 'Guide'
processName: (path) ->
return path.replace('.js', '').replace('/', '.') + '.template'
guide:
files:
#hbsGlob
grunt.registerTask 'etch-scripts', =>
glob = grunt.option('filteredGlob')
glob.push "!./src/**/*.{md,js,json}"
options =
rename: (dest, matchedSrcPath, options) ->
return dest
#hbsGlob = grunt.file.expandMapping(glob, config.build + '/scripts/handlebars.js', options)
grunt.task.run 'handlebars:guide'
grunt.loadNpmTasks('grunt-contrib-handlebars');
The only output I am getting is
Running "handlebars:guide" (handlebars) task
>> 0 files created.
Done, without errors.
Any idea what is going wrong so I can use that glob as the src/dest?

After lots of research on this, I found a slight alternative that ended up working perfectly!
After setting the hbsGlob variable, I added that var to a Grunt config grunt.config.set('hbsGlob', #hbsGlob)
Then in the handlebars:guide task I set it to
guide:
files: '<%= hbsGlob %>'
And everything built out perfectly!
Edit -- Source: https://stackoverflow.com/a/14780870/399742

Related

gulp-task output in console is not printing expected result

I have the following gulp task which inserts .css and .js files in the html file:
gulp.task('inject', function () {
log('Injecting the JS and CSS files into index.html');
var wiredep = require('wiredep').stream;
var options = config.getWiredepDefaultOptions();
return gulp.src(config.index)
.pipe(wiredep(options))
.pipe($.inject(gulp.src(config.customFiles), {ignorePath: options.ignorePath}))
.pipe(gulp.dest(config.client));
});
and my gulp.config.js:
module.exports = function () {
var client = './public';
var config = {
allJS: [
'*.js',
'public/js/*.js',
'public/js/**/*.js'
],
client: client,
index: client + '/index.html',
customFiles: [
'./public/css/*.css',
'./public/js/*.js',
'./public/js/**/*.js'
],
bower: {
json: require('./bower.json'),
directory: './public/lib',
ignorePath: '/public/'
},
};
config.getWiredepDefaultOptions = function () {
var options = {
bowerJson: config.bower.json,
directory: config.bower.directory,
ignorePath: config.bower.ignorePath
};
return options;
};
return config;
};
This works as expected, but when I run the task I get this:
It always says gulp-inject 3 files into index.html, even though no new files was added.
Is there something wrong with my gulp file?
Well if you are using gulp-inject this is what I found.
If you look at the code in gulp-inject you can see it just spits out the file count unless it gets opt.quiet set. I didn't see a option in the docs for this setting but if you look at the tests it shows an example it being used.
Enabling quiet mode link line 505
inject(sources, {quiet: true});
Source where it generates the log statement. link line 109
function getNewContent(target, collection, opt) {
var logger = opt.quiet ? noop : function (filesCount) {
if (filesCount) {
log(cyan(filesCount) + ' files into ' + magenta(target.relative) + '.');
} else {
log('Nothing to inject into ' + magenta(target.relative) + '.');
}
};

Grunt-scaffold after() function access to prompt answers

The docs for the NPM package grunt-scaffold lacked any information really on its after() property/function.. I have a grunt file which creates a new directory for a new script and copies boilerplate files into it from the designated template folder.. The desire is to finish the grunt scaffold:new_script command and have it log out the location of the newly generated folder.
Gruntfile.js
module.exports = function(grunt) {
grunt.initConfig({
scaffold: {
new_script: {
options: {
questions: [{
name: 'script_name',
type: 'input',
message: 'Script name, catterpillar_case?(e.g. \'new_script\'):'
}],
template: {
"scripts/etl_template/": "scripts/{{script_name}}/",
},
after: function(){
console.log("New script generated in new folder scripts/{{script_name}}")
}
}
}
}
});
grunt.loadNpmTasks('grunt-scaffold');
grunt.registerTask('default', ['scaffold']);
};
However, the ouput is
-bash-4.1$ grunt scaffold:new_script
Running "scaffold:new_script" (scaffold) task
? Script name, catterpillar_case?(e.g. 'new_script'): test_grunt
New script generated in new folder scripts/{{script_name}}
Done.
This did not do the string replacing as it did when it created the scripts/test_grunt folder! As you can see the documentation almost doesn't exist for that after() functionality, and I'm wondering if I can use javascript"system argume
An example was not given in the documentation for the after() function, but if you use the same result parameter as in the example given for filter(), you can access the answer values via their names.
Gruntfile.js
module.exports = function(grunt) {
grunt.initConfig({
scaffold: {
new_script: {
options: {
questions: [{
name: 'script_name',
type: 'input',
message: 'Script name, catterpillar_case?(e.g. \'new_script\'):'
}],
template: {
"scripts/etl_template/": "scripts/{{script_name}}/",
},
after: function(result){
console.log("New script generated in new folder scripts/" + result.script_name)
}
}
}
}
});
grunt.loadNpmTasks('grunt-scaffold');
grunt.registerTask('default', ['scaffold']);
};
Output
-bash-4.1$ grunt scaffold:new_script
Running "scaffold:new_script" (scaffold) task
? Script name, catterpillar_case?(e.g. 'new_script'): test_grunt
New script generated in new folder scripts/test_grunt
Done.

grunt load dynamic JSON file

Is it possible to load a JSON file from a dynamic source? I want to do some localisation
grunt.file.readJSON('src/locales/<%= grunt.task.current.args[0] %>/i18n.json');
A fuller example of the Gruntfile looks like:
module.exports = function(grunt) {
var i18n = {
locales: ['en', 'fr', 'de', 'es'],
default: 'en',
replacements: function(locale){
var content = grunt.file.readJSON('src/locales/<%= grunt.task.current.args[0] %>/i18n.json');
var arr = [];
for(i in content){
var replacement = {
from: i,
to: content[i].value
};
arr.push(replacement);
}
return arr;
}
};
// Project configuration.
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
replace: {
build: {
src: ['local/en/**/*.html'], // source files array (supports minimatch)
dest: 'local/<%= grunt.task.current.args[0] %>/', // destination directory or file
replacements: i18n.replacements('<%= grunt.task.current.args[0] %>')
}
},
While registering the task looks like:
grunt.registerTask('localise', function(){
var tasks = [];
for(i in i18n.locales){
if(i18n.locales[i] !== i18n.default){
tasks.push('replace:build:' + i18n.locales[i]);
}
}
grunt.task.run(tasks);
});
Everything works as I'd hoped except loading the JSON to actually do the replacements.
I've also tried:
grunt.file.readJSON('src/locales/'+locale+'/i18n.json');
which didn't work either, leaving me a little stumped.
Anyone able to help?
Thanks
Try:
'src/locales/' + grunt.task.current.args[0] + '/i18n.json'
Ok, I got it working after much trial and error:
I updated the function returning the data to:
var i18n = {
locales: ['en', 'fr', 'de', 'es'],
default: 'en',
replacements: function(locale){
var content = grunt.file.readJSON('src/locales/'+ locale +'/i18n.json');
var arr = [{from: "/" + locale, to: "/en"}, {from: "Test", to: locale}];
for(i in content){
var replacement = {
from: i,
to: content[i].value
};
arr.push(replacement);
}
console.log(arr);
return arr;
}
};
Then set an empty array in the default task:
replace: {
build: {
src: ['local/en/**/*.html'], // source files array (supports minimatch)
dest: 'local/<%= grunt.task.current.args[0] %>/', // destination directory or file
replacements: []
}
},
Which is updated using it's own task
grunt.registerTask('updateConf', function(locale){
var content = i18n.replacements(locale);
grunt.config('replace.build.replacements', content);
});
That is run just before the replace task:
grunt.registerTask('localise', function(){
var tasks = [];
for(i in i18n.locales){
if(i18n.locales[i] !== i18n.default){
tasks.push('updateConf:' + i18n.locales[i]);
tasks.push('replace:build:' + i18n.locales[i]);
}
}
grunt.task.run(tasks);
});
Giving the right output. Probably not the most elegant of solutions but it works!

Can I use a Gulp task with multiple sources and multiple destinations?

I have the following in my gulpfile.js:
var sass_paths = [
'./httpdocs-site1/media/sass/**/*.scss',
'./httpdocs-site2/media/sass/**/*.scss',
'./httpdocs-site3/media/sass/**/*.scss'
];
gulp.task('sass', function() {
return gulp.src(sass_paths)
.pipe(sass({errLogToConsole: true}))
.pipe(autoprefixer('last 4 version'))
.pipe(minifyCSS({keepBreaks:true}))
.pipe(rename({ suffix: '.min'}))
.pipe(gulp.dest(???));
});
I'm wanting to output my minified css files to the following paths:
./httpdocs-site1/media/css
./httpdocs-site2/media/css
./httpdocs-site3/media/css
Am I misunderstanding how to use sources/destinations? Or am I trying to accomplish too much in a single task?
Edit: Updated output paths to corresponding site directories.
I guess that the running tasks per folder recipe may help.
Update
Following the ideas in the recipe, and oversimplifying your sample just to give the idea, this can be a solution:
var gulp = require('gulp'),
path = require('path'),
merge = require('merge-stream');
var folders = ['httpdocs-site1', 'httpdocs-site2', 'httpdocs-site3'];
gulp.task('default', function(){
var tasks = folders.map(function(element){
return gulp.src(element + '/media/sass/**/*.scss', {base: element + '/media/sass'})
// ... other steps ...
.pipe(gulp.dest(element + '/media/css'));
});
return merge(tasks);
});
you are going to want to use merge streams if you would like to use multiple srcs but you can have multiple destinations inside of the same one. Here is an example.
var merge = require('merge-stream');
gulp.task('sass', function() {
var firstPath = gulp.src(sass_paths[0])
.pipe(sass({errLogToConsole: true}))
.pipe(autoprefixer('last 4 version'))
.pipe(minifyCSS({keepBreaks:true}))
.pipe(rename({ suffix: '.min'}))
.pipe(gulp.dest('./httpdocs-site1/media/css'))
.pipe(gulp.dest('./httpdocs-site2/media/css'));
var secondPath = gulp.src(sass_paths[1])
.pipe(sass({errLogToConsole: true}))
.pipe(autoprefixer('last 4 version'))
.pipe(minifyCSS({keepBreaks:true}))
.pipe(rename({ suffix: '.min'}))
.pipe(gulp.dest('./httpdocs-site1/media/css'))
.pipe(gulp.dest('./httpdocs-site2/media/css'));
return merge(firstPath, secondPath);
});
I assumed you wanted different paths piped here so there is site1 and site2, but you can do this to as many places as needed. Also you can specify a dest prior to any of the steps if, for example, you wanted to have one dest that had the .min file and one that didn't.
You can use gulp-rename to modify where files will be written.
gulp.task('sass', function() {
return gulp.src(sass_paths, { base: '.' })
.pipe(sass({errLogToConsole: true}))
.pipe(autoprefixer('last 4 version'))
.pipe(minifyCSS({keepBreaks:true}))
.pipe(rename(function(path) {
path.dirname = path.dirname.replace('/sass', '/css');
path.extname = '.min.css';
}))
.pipe(gulp.dest('.'));
});
Important bit: use base option in gulp.src.
For the ones that ask themselves how can they deal with common/specifics css files (works the same for scripts), here is a possible output to tackle this problem :
var gulp = require('gulp');
var concat = require('gulp-concat');
var css = require('gulp-clean-css');
var sheets = [
{ src : 'public/css/home/*', name : 'home.min', dest : 'public/css/compressed' },
{ src : 'public/css/about/*', name : 'about.min', dest : 'public/css/compressed' }
];
var common = {
'materialize' : 'public/assets/materialize/css/materialize.css'
};
gulp.task('css', function() {
sheets.map(function(file) {
return gulp.src([
common.materialize,
file.src + '.css',
file.src + '.scss',
file.src + '.less'
])
.pipe( concat(file.name + '.css') )
.pipe( css() )
.pipe( gulp.dest(file.dest) )
});
});
All you have to do now is to add your sheets as the object notation is constructed.
If you have additionnal commons scripts, you can map them by name on the object common, then add them after materialize for this example, but before the file.src + '.css' as you may want to override the common files with your customs files.
Note that in the src attribute you can also put path like this :
'public/css/**/*.css'
to scope an entire descendence.
I had success without needing anything extra, a solution very similar to Anwar Nairi's
const p = {
dashboard: {
css: {
orig: ['public/dashboard/scss/style.scss', 'public/dashboard/styles/*.css'],
dest: 'public/dashboard/css/',
},
},
public: {
css: {
orig: ['public/styles/custom.scss', 'public/styles/*.css'],
dest: 'public/css/',
},
js: {
orig: ['public/javascript/*.js'],
dest: 'public/js/',
},
},
};
gulp.task('default', function(done) {
Object.keys(p).forEach(val => {
// 'val' will go two rounds, as 'dashboard' and as 'public'
return gulp
.src(p[val].css.orig)
.pipe(sourcemaps.init())
.pipe(sass())
.pipe(autoPrefixer())
.pipe(cssComb())
.pipe(cmq({ log: true }))
.pipe(concat('main.css'))
.pipe(cleanCss())
.pipe(sourcemaps.write())
.pipe(gulp.dest(p[val].css.dest))
.pipe(reload({ stream: true }));
});
done(); // <-- to avoid async problems using gulp 4
});
Multiple sources with multiple destinations on gulp without using any extra plugins just doing concatenation on each js and css. Below code works for me. Please try it out.
const gulp = require('gulp');
const concat = require('gulp-concat');
function task(done) {
var theme = {
minifiedCss: {
common: {
src : ['./app/css/**/*.min.css', '!./app/css/semantic.min.css'],
name : 'minified-bundle.css',
dest : './web/bundles/css/'
}
},
themeCss:{
common: {
src : ['./app/css/style.css', './app/css/responsive.css'],
name : 'theme-bundle.css',
dest : './web/bundles/css/'
}
},
themeJs: {
common: {
src: ['./app/js/jquery-2.1.1.js', './app/js/bootstrap.js'],
name: 'theme-bundle.js',
dest: './web/_themes/js/'
}
}
}
Object.keys(theme).map(function(key, index) {
return gulp.src(theme[key].common.src)
.pipe( concat(theme[key].common.name) )
.pipe(gulp.dest(theme[key].common.dest));
});
done();
}
exports.task = task;
Using gulp-if helps me a lot.
The gulp-if first argument. is the gulp-match second argument condition
gulp-if can be found in gulp-if
import {task, src, dest} from 'gulp';
import VinylFile = require("vinyl");
const gulpif = require('gulp-if');
src(['foo/*/**/*.md', 'bar/*.md'])
.pipe(gulpif((file: VinylFile) => /foo\/$/.test(file.base), dest('dist/docs/overview')))
.pipe(gulpif((file: VinylFile) => /bar\/$/.test(file.base), dest('dist/docs/guides')))
});
I think we should create 1 temporary folder for containing all these files. Then gulp.src point to this folder
The destination will have the same directory structure as the source.

Register Assemble Handlebars Helpers

I am trying to do something that seems relatively simple from the Assemble docs and other repos I've looked at but for some reason I'm having a problem registering my Handlebars helpers. The helper is in helpers > helper-classgrid.js
module.exports.register = function (Handlebars, options, params) {
Handlebars.register('classgrid', function (index, options) {
gridclass: function (index, options) {
if (index === 0 || index % 4 === 0) {
return options.fn(this);
}
return options.inverse(this);
};
};
My gruntfile where config.helpers = helpers:
assemble: {
options: {
layoutdir: '<%= config.guts %>/templates/layouts/',
assetsDir: '<%= grunt.config.get("assets_dir") %>',
environmentIsProduction: '<%= grunt.config.get("environmentIsProduction") %>',
environmentIsDev: '<%= grunt.config.get("environmentIsDev") %>',
data: ['<%= config.content %>/**/*.json', '<%= grunt.config.get("environmentData") %>'],
helpers: ['<%= config.helpers %>/helper-*.js']
},
}
Template code:
{{#classgrid #index}}
// do something here
{{/classgrid}}
Now when I implement my helper in my Handlerbars template and run the grunt task containing the assemble task I get the error
Warning: Missing helper: 'classgrid' Use --force to continue.
I'm not sure what I've done wrong or if I have to create a separate NPM package for my helpers which it seems to suggest in the assemble docs. I've looked at these 2 repos which seem to be doing what I'm trying to do
https://github.com/buildingblocks/bb-prototype-website/blob/master/Gruntfile.js
https://github.com/ghost-town/layouts-example/blob/master/Gruntfile.js#L33
Not sure if this was just a copy/paste issue, but the code above doesn't look correct... here's what should work:
module.exports.register = function (Handlebars, opts, params) {
Handlebars.registerHelper('classgrid', function (index, options) {
if (index === 0 || index % 4 === 0) {
return options.fn(this);
}
return options.inverse(this);
});
};
I'll try to create a test project to make sure this is working.
Edit: After creating a test project, I see that you were using Handlebars.register instead of Handlebars.registerHelper. I've updated the code to a working solution. Hope this helps.

Categories

Resources