Dynamic titles and meta tags using GulpJs - gulp

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

browsersync reload when a nunjucks partial file is modified

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'
])

Looking for a Gulp plugin that will skip markdown files based on particular header attributes

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 to build a list of links to html files in Gulp?

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.

Negating folders with Gulp and then including a singular file from same directory

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?

Creating a style guide / pattern library with gulp

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.