I'm using GulpJS and gulp-token-replace to replace variables within an HTML file, such as title and meta tags. It's working great, but I'm stuck with only one configuration file (config-title-meta.json). I want to have an individual configuration file for each folder, so that I might be able to edit "main" variables for all html pages, but customize others, without having to edit each individual page. Am I using the correct tool for this?
gulpfile.js:
var replace = require('gulp-token-replace');
gulp.task('compile-html', function() {
var config = require('./config-title-meta.json');
return gulp.src([
'./**/*.html',
'!header.html', // ignore
'!footer.html' // ignore
])
.pipe(fileinclude({
prefix: '##',
basepath: '#file'
}))
.pipe(replace({global:config}))
.pipe(gulp.dest(Paths.scripts.dest));
});
Related
I have a gulp task as following:
gulp.task("nunjucks", () => {
return gulp
.src([src_folder + "pages/**/*.njk"])
.pipe(plumber())
.pipe(
data(() =>
JSON.parse(fs.readFileSync(src_folder + "datas/dist/data.json"))
)
)
.pipe(nunjucks())
.pipe(beautify.html({ indent_size: 2 }))
.pipe(gulp.dest(dist_folder))
.pipe(browserSync.stream({match: '**/*.html'}));
});
gulp.watch([src_folder + '**/*.njk'], gulp.series("nunjucks")).on("change", browserSync.reload);
and my project structures look like this:
atoms, molecules and organisms contains nunjucks partials.
The problem I have is that whenever I update a partial file (ex: organisms/partial1.njk), my task detects changes on all the files inside pages (the path I provided for the task src), as you can see here :
I only want to reload the files that includes this partial and not all the files.
How can I solve this?
Its not up to your gulp task to know which one of your Nunjuck pages contain partials. Perhaps if you re-group your .njk files within your Pages folder, you could then better manage what gets reloaded. The following is untested, but hopefully conveys the idea...
pages/
- init/
- other-stuff/
You could then update the src from your gulp task to something like so...
gulp.src([
'!pages/other-stuff/**/*',
'pages/init/**/*.njk'
])
I have markdown files that look like this
---
name: Some Name
date: '2013-09-09'
isCool: true
---
really cool text
I want to have a gulp task that only lets markdown through that has a particular property, for example isCool = true.
So I would imagine something like this
gulp.src('source/content/*/*.md')
.pipe(mdPrune({
isCool: true
}))
.pipe(gulp.dest('build/content/cool'));
then only the markdown that had an isCool attribute in the header would end up the build/content/cool folder.
gulp-filter would work.
const filter = require('gulp-filter');
gulp.task('default', function () {
// return true if want the file in the stream
const myFilter = filter(function (file) {
let contents = file.contents.toString();
return contents.match('isCool: true');
});
return gulp.src(['./src/*.md'])
.pipe(myFilter)
.pipe(gulp.dest('md'));
});
That will allow the file through if isCool: true is anywhere in the file. If that is a problem, just work on the regex to restrict it to the line after the date entry for example.
[The filter could also be defined outside of any task if it might be reused elsewhere or you just prefer it that way.
How can you use Gulp to gather in one html file a list of all the pages that are in the directory?
For example, in the build directory I have two files contact.html with title "Contacts" and faq.html with the title "Frequently asked questions", I need to get them and create a ui.html which would be a list of links to files of the form:
Frequently asked questions
Contacts
Well, with the addition of step your design (a connected css file).
Found the gulp-listing module, but it can not be customized, there it is as follows:
gulp.task('scripts', function() {
return gulp.src('./src/*.html')
.pipe(listing('listing.html'))
.pipe(gulp.dest('./src/'));
});
I used two gulp modules for do this.
gulp-filelist - for create file list
gulp-modify-file - for update this file
gulp
.src(['./html/**/*.html'])
.pipe(require('gulp-filelist')('filelist.js', { relative: true }))
.pipe(require('gulp-modify-file')((content) => {
const start = 'var list = '
return `${start}${content}`
}))
.pipe(gulp.dest('js'))
After run gulp, you got in js/filelist.js something like this:
var list = [
"Cancellation/template.html",
"Cancellation/email.html",
]
You can add this script in your html file, and with js display all info.
I'm using Gulp and I have a folder that has several .js files in in, of which I only need one of them; I read up on negating files within Gulp and from what I understood you should remove them first and then afterwards you can add them back in case you didn't want to negate them all.
I have this code for example:
var js_scripts = [
'js/dev/lib/**/*.js',
'js/dev/plugins/**/*.js',
'!js/dev/plugins/fancybox/*.js',
'js/dev/plugins/fancybox/jquery.fancybox-1.3.4.pack.js',
'!js/dev/plugins/inner/*.js',
'!js/dev/plugins/jquery.bxslider/**/*.js',
'js/dev/plugins/jquery.bxslider/jquery.bxslider.min.js',
// We have to set the bootstrap lines separately as some need to go before others
'js/dev/bootstrap/collapse.js',
'js/dev/bootstrap/dropdown.js',
'js/dev/bootstrap/tab.js',
'js/dev/bootstrap/transition.js',
'js/dev/scripts.js'
];
gulp.task('scripts', function() {
return gulp.src(js_scripts)
.pipe(sourcemaps.init())
.pipe(concat('scripts.js'))
.pipe(sourcemaps.write('../maps'))
.pipe(gulp.dest('./js'));
});
gulp.task('uglify', ['scripts'], function() {
return gulp.src(js_scripts)
.pipe(gulpif('!**/*.min.js', uglify({mangle: false})))
.pipe(concat('scripts.min.js'))
.pipe(gulp.dest('./js'));
});
However I have just noticed that both js/dev/plugins/fancybox/jquery.fancybox-1.3.4.pack.js and js/dev/plugins/jquery.bxslider/jquery.bxslider.min.js have not been included in the output files even though I added them back in after initial removal.
According to the docs it states that:
Note that globs are evaluated in order, which means this is possible:
// exclude every JS file that starts with a b except bad.js
gulp.src(['*.js', '!b*.js', 'bad.js'])
So the fact that I first include the whole plugins directory and then remove everything inside js/dev/plugins/jquery.bxslider/ and then re-add the file js/dev/plugins/jquery.bxslider/jquery.bxslider.min.js for example then should should include that file?
I noticed if I removed this line: !js/dev/plugins/jquery.bxslider/**/*.js then it gets included.
What am I doing wrong here?
I know there is already a tonne of automated tools to create a style guide / pattern library but in the interest of learning I'd like to see if I can roll my own.
Compiling the SASS is straight forward. Same with the js. I can also see how to wrap blocks of HTML from multiple files with a class and compiled into a single file. Ideal for displaying all the 'partials' together on one page.
gulp.task('inject:wrap', function(){
return gulp.src('./_patterns/*/*/*.html')
/// get the partial html filename here and insert below ###
.pipe(inject.wrap('<div id="###" class="pattern">', '</div>'))
.pipe(concat('patterns.html'))
.pipe(gulp.dest('build'));
});
gulp.task('process', ['inject:wrap']);
What I struggling with is how I can get the filename of the block - let's say _button.html - and pass this to the wrapper as the element id "###" above. Which I can then use to build the style guides navigation / anchor links.
Here's a sample code I've got, uses jade template language (which takes care of injections, partials, evaluation etc. by itself); There are two tasks, one generates static HTML pages, other pre-compiles templates to be used as runtime template functions wrapped in AMD
// preprocess & render jade static templates
gulp.task('views:preprocess', function () {
return gulp.src([ 'source/views/*.jade', '!source/views/layout.jade' ])
.pipe(plumber()) // plumber, because why not?
.pipe(data(function (file) {
// prepare data to be passed to the template
// here we can use the file name to map specific data to each file
return _.assign(settingsData, { timestamp: timestamp });
}))
// render template with data
.pipe(jade())
.pipe(gulp.dest('destination'));
});
// precompile jade runtime templates
gulp.task('views:precompile', function () {
// grab folder names
var folders = fs.readdirSync('source/templates').filter(function (file) {
return fs.statSync(path.join('source/templates', file)).isDirectory();
});
// create a separate task for each folder
var tasks = folders.map(function (folder) {
return gulp.src(path.join('source/templates', folder, '*.jade'))
.pipe(plumber())
// pre-compile the template as functions, for runtime
.pipe(jade({
client: true
}))
// wrap it in AMD, so we can use stuff like require.js to fetch them later
.pipe(wrap({
moduleRoot: 'source/templates',
modulePrefix: 'templates',
deps: [ 'jade' ],
params: [ 'jade' ]
}))
// concat all the templates in each folder to a single .js file
.pipe(concat(folder + '.js'))
.pipe(uglify())
.pipe(header(banner, { package: packageData }))
.pipe(gulp.dest('destination/scripts/templates'));
});
return merge(tasks);
});
Modules I've used are merge-stream, path, gulp, fs, gulp-data, gulp-jade, gulp-plumber etc.
Didn't quite understand what you're trying to achieve, but I hope this gives you some clues.