Reading files in Hexo

So now and then I might want to read a file in my hexo working tree that contains data that is needed when generating pages. For example I may have a file in my root name space that contains API access keys that are hidden from git with a .gitignore file. I might be using some API that requires an access key to get data that I used in the build process, so I will want to read that file, and fail gracefully if for some reason it’s not there.

The Promise.

I will want to use a promise, as this is often what is used within hexo, and it is what is needed to do any kind of async thing such as reading a file or making a request.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// the first promise I wrote myself
readFile = function (path, filename) {
return new Promise(function (resolve, reject) {
fs.readFile(path + filename, 'utf8', function (err, data) {
if (err) {
reject('Error reading file: ' + err);
}
resolve(data);
});
});
};

A simple read file tag

So I might want a tag that I can use to inject data from anywhere in my root namespace into a blogpost.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// read a file from the base dir forward.
hexo.extend.tag.register('mytags_readfile', function (args) {
var filename = args[0];
log('reading file : ' + filename);
return readFile(hexo.base_dir, filename).then(function (content) {
log('file read good.');
return '<pre><code>' + content + '</code></pre>';
}).catch (function (err) {
log('error reading file');
return '<pre>Error reading file ' + filename + '</pre>';
});
}, {
async : true
});

Here for example I will use it to inject the package.json file from my hexo project.

1
{% mytags_readfile package.json %}
{
  "name": "hexo_sitesource",
  "version": "1.0.96",
  "private": true,
  "hexo": {
    "version": "3.2.2"
  },
  "scripts": {
    "start": "cd public && node server.js"
  },
  "dependencies": {
    "hexo": "^3.2.0",
    "hexo-generator-archive": "^0.1.4",
    "hexo-generator-category": "^0.1.3",
    "hexo-generator-index": "^0.2.0",
    "hexo-generator-sitemap": "^1.1.2",
    "hexo-generator-tag": "^0.2.0",
    "hexo-renderer-ejs": "^0.2.0",
    "hexo-renderer-marked": "^0.2.10",
    "hexo-renderer-stylus": "^0.3.1",
    "hexo-server": "^0.2.0",
    "node-dir": "^0.1.16",
    "sitemap": "^1.11.1"
  },
  "devDependencies": {
    "grunt": "^1.0.1"
  }
}

Geting an access key, or token from my apikeys.json file.

With some api’s I must have an access token, or api key of some kind. I would not want to hard code an access key into my source code, and push it to a public reposatory. So I would want to read data from a hidden file to get a key, then use that key to make a request to the api.

To get started with this first I will want a method to get the key from my hidden apikeys.json file. It will make use of the readFile method I just put togeather.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// get an access key, or token from apikeys.json.
getKey = function (apiName) {
apiName = apiName || 'github';
return new Promise(function (resolve, reject) {
readFile(hexo.base_dir, 'apikeys.json').then(function (content) {
resolve(JSON.parse(content)[apiName]);
}).catch (function () {
log('error getting api key for : ' + apiName);
reject('');
});
});
};

The Github tag

This will make a request with a key that I obtained from apikeys.json thanks to my getKey, readFile, and an httpRequest method I found earlier. All of which is in my-tags.js in my hexo scripts folder.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
var formatRepos = function (content) {
html = '<pre> Here are my repos at github.<br><br>';
content.forEach(function (repo) {
html += '<a href=\"' + repo.html_url + '\">' + repo.name + '</a><br>';
html += repo.description + '<br><br>';
});
return html + '</pre>';
};
// read a file from the base dir forward.
hexo.extend.tag.register('mytags_github', function (args) {
return new Promise(function (resolve, reject) {
getKey('github').then(function (key) {
resolve(key);
}).catch (function () {
reject('');
});
}).then(function (key) {
return httpRequest({
host : 'api.github.com',
method : 'GET',
path : '/users/dustinpfister/repos?access_token=' + key,
headers : {
'user-agent' : 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)'
}
}).then(function (content) {
log('request is good.');
return formatRepos(content);
}).catch (function (err) {
log('bad request.');
log(err);
return '<pre>Error getting the data from github <\/pre>';
});
}).catch (function () {
return '<pre>error with the github</pre>';
});
}, {
async : true
});

Here it is in action…………

 Here are my repos at github.

bFly
My submission to the 2013 js13kgames.com competition

blend_static
Simple blender projects

blog_img
blog images

blog_posts
The source code of my blog posts that are used in the build process of my site here at github

blog_wrep
blog word report cli tool

cityBuilder1500
a city building game

clad_clash
A game about ships

deglitcher13k
my 2016 submission to js13k games

deterministic
playing around with the idea of deterministic systems

deterministic_demos_0_0_11
demos for deterministic v 0.0.11

dustinpfister.github.io
The github page of dustinpfister

em
This is for EM

express_flyjson
josn on the fly

express_todo
Yet another one of these

express_visual_analytics
visualizing my sites analytics data

firstThreeJS
First time playing with three.js

forframe
Animation by a forFrame basis

forframe-client
A client system for playing back forFrame animations

game_balloon_attack
null

game_dig
a game about digging in dirt

game_forever_stupid
For the 2015 Buffalo Game Space Game Jam

game_offgrid
Life off the grid

game_parcel_idle
A game about land parcels

game_tumbler
A new game about locks

game_ufj
Unidentified Flying Jerk

game_urban_planner_1500
A sim city clone that aims to be a little different

game_wild_lawn_idle
An idle game about a wild lawn

gh-pages-test
Testing out the gh-pages branch

grunt-postcheck
check out markdown file posts

heroku_cors
testing out cors

conclusion

Be sure to check out my other posts on hexo