Every Post Gets a Link
04/10/15
So, when I first started this blog, I was just adding on top of an index.html file. So, a lot of my first posts are only contained in there, not their own file.
I figure that fixing this with cheerio might actually be pretty easy. First, I need to find all the posts that don't have a link.
Let's start from scratch. It's a good learning experience. First, let's count all my blogposts again.
/*jslint node: true */
(function () {
"use strict";
var fs = require('fs'),
$ = require('cheerio');
fs.readFile('public/blog/index.html', 'utf-8', function (err, data) {
if (err) {
console.log(err);
}
console.log($('.blogpost', data).length);
});
}());
Output is:
$ node scripts/createLinks.js
247
From here, let's count all posts that don't have an tile link.
/*jslint node: true */
(function () {
"use strict";
var fs = require('fs'),
$ = require('cheerio');
fs.readFile('public/blog/index.html', 'utf-8', function (err, data) {
var noLinks;
if (err) {
console.log(err);
}
noLinks = $('.blogpost', data).not(function () {
if ($(this).find('h1 a').html()) {
return true;
}
return false;
});
console.log(noLinks.length);
});
}());
This gives me an output of:
$ node scripts/createLinks.js
21
I'm actually surprised it took more than 21 posts to start making individual links (I've manually made some links to some of the posts before when I started linking things).
From here, I need to create some files where I can save the html to make each post its own page. Let's make it in a test directory while I'm figuring stuff out (don't want to pollute the blog area with poorly constructed filenames or anything).
noLinks.each(function () {
var blogpost = $(this),
titleToFilename,
title,
filename;
titleToFilename = function (title) {
return 'test/'
+ title
.replace(/\ /g, '_')
.replace(/[()?:\.]/g, '')
.toLowerCase()
+ '.html';
};
title = blogpost.children('h1').text().trim();
console.log(title);
filename = titleToFilename(title);
console.log(filename);
console.log();
fs.writeFile(filename, '', 'utf-8', function (err) {
if (err) {
return console.log(err);
}
});
});
This code outputs:
$ node scripts/createLinks.js
Goal for Today: RSS Feed
test/goal_for_today_rss_feed.html
Things Looking Much Less Horrible
test/things_looking_much_less_horrible.html
Project of Focus: Making This Blog Look Better
test/project_of_focus_making_this_blog_look_better.html
What is Consciousness?
test/what_is_consciousness.html
Sick
test/sick.html
The Free Will Debate
test/the_free_will_debate.html
First Try At a Never-Ending Github Streak
test/first_try_at_a_never-ending_github_streak.html
Things Looking a Bit Better Around Here
test/things_looking_a_bit_better_around_here.html
Some More Specific Goals for This Blog
test/some_more_specific_goals_for_this_blog.html
Let's Try Making Things Prettier
test/let's_try_making_things_prettier.html
What is Your Job?
test/what_is_your_job.html
Parallel Growth
test/parallel_growth.html
Random Fiction: Which is the Dream?
test/random_fiction_which_is_the_dream.html
Site Change: Adding Dates (Manually)
test/site_change_adding_dates_manually.html
Sick Day
test/sick_day.html
The Walking Dead
test/the_walking_dead.html
Disruption
test/disruption.html
Everyday
test/everyday.html
Exercise PID Control
test/exercise_pid_control.html
Eventually....
test/eventually.html
The First Stone
test/the_first_stone.html
And if I check the test directory:
$ ls test/
disruption.html
eventually.html
everyday.html
exercise_pid_control.html
first_try_at_a_never-ending_github_streak.html
goal_for_today_rss_feed.html
let's_try_making_things_prettier.html
parallel_growth.html
project_of_focus_making_this_blog_look_better.html
random_fiction_which_is_the_dream.html
sick_day.html
sick.html
site_change_adding_dates_manually.html
some_more_specific_goals_for_this_blog.html
the_first_stone.html
the_free_will_debate.html
the_walking_dead.html
things_looking_a_bit_better_around_here.html
things_looking_much_less_horrible.html
what_is_consciousness.html
what_is_your_job.html
Yay! We'd be done now if those files weren't empty and if they were in the blog area and the index.html file html was updated to link to those files..
Let's make it so those files aren't empty and are in the blog area and that index.html links to those files.
Non-empty:
noLinks.each(function () {
var blogpost = $(this),
titleToFilename,
title,
filename,
blogData;
titleToFilename = function (title) {
return 'test/'
+ title
.replace(/\ /g, '_')
.replace(/[()?:\.]/g, '')
.toLowerCase()
+ '.html';
};
title = blogpost.children('h1').text().trim();
filename = titleToFilename(title);
blogData = '<html>\n'
+ ' <head>\n'
+ ' <title>\n'
+ ' ' + title + '\n'
+ ' </title>\n'
+ ' <link rel="stylesheet" href="/style.css">\n'
+ ' <link rel="stylesheet" href="style.css">\n'
+ ' </head>\n'
+ ' <body>\n'
+ ' <div id="browse_bar">'
+ browseBar.html()
+ '</div>\n'
+ ' <div id="content">\n'
+ ' <div class="blogpost">'
+ blogpost.html()
+ '</div>\n'
+ ' </div>\n'
+ ' </body>\n';
fs.writeFile(filename, blogData, 'utf-8', function (err) {
if (err) {
return console.log(err);
}
});
});
The files come out reading mostly like I wrote it by hand (except for the characters that are escaped for me that I didn't realize needed to be escaped). I had no idea that ' was a thing.
Updating the index file.... Actually, I realize while trying to do this that I need to restructure my code a bit to make it ridiculously easy to do this. And from there it's just a little change to make it so it's all saved to my blog area proper.
The final code:
/*jslint node: true */
(function () {
"use strict";
var fs = require('fs'),
cheerio = require('cheerio'),
indexPath = 'public/blog/index.html';
fs.readFile(indexPath, 'utf-8', function (err, data) {
var noLinks,
browseBar,
title,
filename,
$ = cheerio.load(data);
if (err) {
console.log(err);
}
title = function (blogpost) {
return blogpost.children('h1').text().trim();
};
filename = function (blogpost) {
return title(blogpost)
.replace(/\ /g, '_')
.replace(/[()?:\.]/g, '')
.toLowerCase()
+ '.html';
};
browseBar = $('#browse_bar');
noLinks = $('.blogpost').not(function () {
var blogpost = $(this);
if (blogpost.find('h1 a').html()) {
return true;
}
return false;
});
noLinks.each(function () {
var blogpost = $(this),
blogData,
path = require('path'),
blogpath;
blogData = '<html>\n'
+ ' <head>\n'
+ ' <title>\n'
+ ' ' + title + '\n'
+ ' </title>\n'
+ ' <link rel="stylesheet" href="/style.css">\n'
+ ' <link rel="stylesheet" href="style.css">\n'
+ ' </head>\n'
+ ' <body>\n'
+ ' <div id="browse_bar">'
+ browseBar.html()
+ '</div>\n'
+ ' <div id="content">\n'
+ ' <div class="blogpost">'
+ blogpost.html()
+ '</div>\n'
+ ' </div>\n'
+ ' </body>\n';
blogpost.children('h1').html(
'\n <a href="' + filename(blogpost) + '">\n'
+ ' ' + title(blogpost) + '</a>\n'
+ ' '
);
blogpath = path.join('public/blog', filename(blogpost));
fs.writeFile(blogpath, blogData, 'utf-8', function (e) {
if (e) {
return console.log(err);
}
});
});
fs.writeFile(indexPath, $.html(), 'utf-8', function (err) {
if (err) {
return console.log(err);
}
});
});
}());
So, after I've constructed the single blogpost html into blogData, I alter the html loaded into $ such that there's a link pointing to the file I'm about to create as the title of the post within the loaded index html. After all blogpost files are created, the index.html path is rewritten with the modified html. This rewrite also has the additional niceties of correcting any incorrect html I wrote the best cheerio knows how.
And just like that I've managed to make a script that makes working links to all the blogposts I had originally written within my blog's index.html.
Awesome.
Next time: save the order of my blog and diary posts into some sort of json file? From there, I can construct index.html from the files I have and said json file. Yeah, I think that sounds like a plan.
Also, I think this diary post is good enough to be a proper blogpost.