How to build a list of links to html files in Gulp? - html

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.

Related

Dynamic titles and meta tags using GulpJs

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));
});

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

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.

How to zip multiple folders generating multiple .zip files in gulp?

My folder structure looks like this:
- /projects
- /projects/proj1
- /projects/proj2
- /projects/proj3
- /zips
For each folder in projects (proj1, proj2 and proj3) I want to zip contents of each of those folders and generate proj1.zip, proj2.zip and proj3.zip in /zips folder.
Following example function generates single zip file from proj1 folder
zip = require('gulp-zip');
gulp.task('default', function () {
return gulp.src('./projects/proj1/*')
.pipe(zip('proj1.zip'))
.pipe(gulp.dest('./zips'));
});
But how I can execute such task for each folder in projects? I can get all folders to zip by gulp.src('./projects/*') but what then?
Old question I know and I am pretty new to gulp so this might be considered a hack but I have just been trying to do what you are after and I ended up with this.
My file structure is this:
proj
proj/dist
proj/dist/sub01
proj/dist/sub02
proj/dist/sub03
proj/zipped
And my task ended up like this:
var gulp = require("gulp");
var foreach = require("gulp-foreach");
var zip = require("gulp-zip");
gulp.task("zip-dist", function(){
return gulp.src("./dist/*")
.pipe(foreach(function(stream, file){
var fileName = file.path.substr(file.path.lastIndexOf("/")+1);
gulp.src("./dist/"+fileName+"/**/*")
.pipe(zip(fileName+".zip"))
.pipe(gulp.dest("./zipped"));
return stream;
}));
});
It grabs all the first level contents of ./dist as its source and then pipes it to gulp-foreach.
gulp-foreach looks at each item and I use a plain javascript substr() to get the name of the current item which I store as a variable.
Finally I set a new src using the stored fileName var and pipe the result to gulp-zip using the stored var again as the name of the zipped file.
The result is a structure that looks like this:
proj
proj/dist
proj/dist/sub01
proj/dist/sub02
proj/dist/sub03
proj/zipped
proj/zipped/sub01.zip
proj/zipped/sub02.zip
proj/zipped/sub03.zip
Again, I am a million miles from being an expert but this worked for me and if I understand the question might work for you as well or at least give you some ideas.

How should I create a complete build with Gulp?

Just learning Gulp. Looks great, but I can't find any information on how to make a complete distribution with it.
Let's say I want to use Gulp to concatenate and minify my CSS and JS, and optimise my images.
In doing so I change the location of JS scripts in my build directory (eg. from bower_components/jquery/dist/jquery.js to js/jquery.js).
How do I automatically update my build HTML/PHP documents to reference the correct files? What is the standard way of doing this?
How do I copy over the rest of my project files?. These are files that need to be included as part of the distribution, such as HTML, PHP, various txt, JSON and all sorts of other files. Surely I don't have to copy and paste those from my development directory each time I do a clean build with Gulp?
Sorry for asking what are probably very n00bish questions. It's possible I should be using something else other than Gulp to manage these, but I'm not sure where to start.
Many thanks in advance.
Point #1
The way i used to achieve this:
var scripts = [];
function getScriptStream(dir) { // Find it as a gulp module or create it
var devT = new Stream.Transform({objectMode: true});
devT._transform = function(file, unused, done) {
scripts.push(path.relative(dir, file.path));
this.push(file);
done();
};
return devT;
}
// Bower
gulp.task('build_bower', function() {
var jsFilter = g.filter('**/*.js');
var ngFilter = g.filter(['!**/angular.js', '!**/angular-mocks.js']);
return g.bowerFiles({
paths: {
bowerDirectory: src.vendors
},
includeDev: !prod
})
.pipe(ngFilter)
.pipe(jsFilter)
.pipe(g.cond(prod, g.streamify(g.concat.bind(null, 'libs.js'))))
.pipe(getScriptStream(src.html))
.pipe(jsFilter.restore())
.pipe(ngFilter.restore())
.pipe(gulp.dest(build.vendors));
});
// JavaScript
gulp.task('build_js', function() {
return gulp.src(src.js + '/**/*.js', {buffer: buffer})
.pipe(g.streamify(g.jshint))
.pipe(g.streamify(g.jshint.reporter.bind(null, 'default')))
.pipe(g.cond(prod, g.streamify(g.concat.bind(null,'app.js'))))
.pipe(g.cond(
prod,
g.streamify.bind(null, g.uglify),
g.livereload.bind(null, server)
))
.pipe(gulp.dest(build.js))
.pipe(getScriptStream(build.html));
});
// HTML
gulp.task('build_html', ['build_bower', 'build_js', 'build_views',
'build_templates'], function() {
fs.writeFile('scripts.json', JSON.stringify(scripts));
return gulp.src(src.html + '/index.html' , {buffer: true})
.pipe(g.replace(/(^\s+)<!-- SCRIPTS -->\r?\n/m, function($, $1) {
return $ + scripts.map(function(script) {
return $1 + '<script type="text/javascript" src="'+script+'"></script>';
}).join('\n') + '\n';
}))
.pipe(gulp.dest(build.html));
});
It has the advantages of concatenating and minifying everything for production while include every files for testing purpose keeping error line numbers coherent.
Point 2
Copying files with gulp is just as simple as doing this:
gulp.src(path).pipe(gulp.dest(buildPath));
Bonus
I generally proceed to deployment by creating a "build" branch and just cloning her in the production server. I created buildbranch for that matter:
// Publish task
gulp.task('publish', function(cb) {
buildBranch({
branch: 'build',
ignore: ['.git', '.token', 'www', 'node_modules']
}, function(err) {
if(err) {
throw err;
}
cb();
});
});
To loosely answer my own question, several years later:
How do I automatically update my build HTML/PHP documents to reference the correct files? What is the standard way of doing this?
Always link to dist version, but ensure sourcemaps are created, so the source is easy to debug. Of course, the watch task is a must.
How do I copy over the rest of my project files?. These are files that need to be included as part of the distribution, such as HTML, PHP, various txt, JSON and all sorts of other files. Surely I don't have to copy and paste those from my development directory each time I do a clean build with Gulp?
This usually isn't a problem as there aren't offer too many files. Large files and configuration are often kept out if the repo, besides.