Introduction
In Using Node.js for Text Processing, I showed you how a simple method to use Node.js processing content of HTML files. In this tutorial, I'll show you another technique for adding content to HTML files using Node.js as a command line interface (CLI) by supplying a script with arguments (flags), set up a basic help message, and append a date stamp to an user supplied HTML file. If this is your tune, let's jam!Requirements
You should be fairly comfortable with JavaScript in general and have some working knowledge of how Node.js works prior to digging into this tutorial.
Required npm packages
In this tutorial, we'll need to ensure the following packages have been install in your project directory:
Note: This tutorial was written with Node.js (version ~0.12.7).
Building the script
First off, let's create a new file calledappend_date.js
. As with any typical Node.js script, we start off with a few variables requiring our packages:
var fs = require('fs');
var cheerio = require('cheerio');
var program = require('commander');
...
In this snippet, we use
fs
to read in the target file, cheerio
to manipulate the content with jQuery-like features,
and commander
for the CLI features of our script. Commander is a wonderful library
that I recently discovered and works very well with my documentation and web developing needs.Setting up the CLI
Like any well written CLI, we should start off with defining how it works. In the following snippet, we define the version of the CLI, how to use it (
.usage
), and any options (.option
) available to the user. Commander is kind enough to provide a basic help output if the user types in <command> -h/--help
as well as any usage and options you provide. Commander will display the default help message plus any info defined in the snippet below:...
program
.version('0.0.3')
.usage('[required options] -t <path/file.html> -d <date>')
.option('-t, --target [target]', '*required* target of HTML file (including the path and file name)')
.option('-d, --date [date]', '*required* date to append to the HTML file')
.parse(process.argv);
...
Main processing
Next, we check if both the target file and date flags have been supplied. From there, the script will load the target file and convert it to a string. The script will next check to see if a container element (
div#content
) exist and decide to create or update it. If the div#content
element exists, the script will then look to either create or update the span.date
element. With the elements in place, the script will now write out the updated HTML file.
...
if (program.target && program.date) {
console.log('Updating ' + program.target);
$ = cheerio.load(fs.readFileSync(program.target).toString()); // load file and convert it to a string
if ($('div#content').length <= 0) { // if div#content doesn't exist, create it
console.log(program.target + ' does not have div#content element. Adding it and datestamp now.');
$('body').append('\t<div id="content">\n\t\t\t<span class="date">Last updated: ' + program.date + '</span>\n\t\t</div>\n\t');
} else { // if div#content exists, look for span.date
console.log(program.target + ' has div#content element; looking for date stamp')
if ($('span.date')) { // if the span.date exists, update it
console.log(program.target + ' has span.date element; updating it now');
$('span.date').text('Last updated: ' + program.date);
} else { // span.date doesn't exist; create it
console.log(program.target + ' dos not have span.date element; adding it now');
$('div#content').append('\t<span class="date">Last updated: ' + program.date + '</span>\n\t\t'); // add date under the content div
}
}
var updated = $.html(); // collect updated html content
fs.writeFileSync(program.target,updated); // save out updated HTML file
...
Fail checks
Like any good CLI, it should fail gracefully by informing the user that something was missing or failed in some way. To accomplish that, our script should check if the target and date flags were not filled out as they will be required for the script to carry out it's purpose. In the following code snippet, the first else if statement confirms if the target file wasn't supplied by the user. The second else if statement confirms if the user supplied a date flag. The final else statement is a catch all if something goes skips a beat.
...
} else if (!program.target) {
console.log('Target for the HTML file was not provided; quitting.');
process.exit(1);
} else if (!program.date) {
console.log('No date stamp was provided; quitting');
process.exit(1);
} else {
console.log('undefined error; quitting');
process.exit(1);
}
This completes the script. At this point, we should save the file and call it
appendDate.js
.Note: this script doesn't verify the date string you enter into the
span.date
element. You could add a check for the program.date
content to conform to a specific format using Regex (like /(\d[0-9]){2}-(\d[0-9]{1})-(\d[0-9]{1})/g
) but that is entirely up to you.CLI in action
With script completed, lets test it out on a simple HTML file. Copy the following code and save the file name as
test.html
in the same directory as your node script:
<!DOCTYPE html>
<html>
<head>
<title>Date Stamp Test</title>
</head>
<body>
</body>
</html>
Let's test our script by executing the following command:
node appendDate.js -t test.html -d 2017-03-30
(or whatever date string you wish to use). Examine the test.html
. You should see our date stamp appended to the document with our custom date stamp.
Review
In ~40 lines of code, we created a script that takes arguments from the command line for a target file and a date string, loaded the target file, modified the target file with the date string, and wrote out the target file with the update HTML.
I hope this tutorial was useful and thank you for reading it.