1 | 'use strict';
|
2 |
|
3 | var yaml = require('yaml-js')
|
4 | var path = require('path')
|
5 | var fs = require('fs')
|
6 | var _ = require('lodash')
|
7 | var util = require('../util')
|
8 | var debug = require('debug')('darko')
|
9 |
|
10 |
|
11 | var PTN_POST_FILE = /(\d{4}-\d{1,2}-\d{1,2})-([^\\]+?)(\.\w+)$/
|
12 |
|
13 |
|
14 | function Post(attrs) {
|
15 | var fpath = attrs.fpath
|
16 | var m = fpath.match(PTN_POST_FILE)
|
17 |
|
18 | if (!m) {
|
19 | debug('Ignored ' + path.relative(attrs.site.cwd, attrs.fpath))
|
20 | return
|
21 | }
|
22 | var date = m[1].split('-')
|
23 |
|
24 | this.site = attrs.site
|
25 | this.categories = attrs.categories || []
|
26 | this.path = path.relative(this.site.cwd, fpath)
|
27 | this.slug = m[2]
|
28 | this.ext = m[3]
|
29 | this.date = new Date(
|
30 | parseInt(date[0], 10),
|
31 | parseInt(date[1], 10) - 1,
|
32 | parseInt(date[2], 10)
|
33 | )
|
34 | this.title = util.capitalize(this.slug)
|
35 |
|
36 | if (fs.existsSync(fpath)) {
|
37 | var content = fs.readFileSync(fpath, this.site.encoding)
|
38 | var parts = content.split('---')
|
39 |
|
40 | if (parts.length >= 3) {
|
41 | _.extend(this, yaml.load(parts[1]))
|
42 | this.content = parts.slice(2).join('---').trim()
|
43 | var caret = this.content.indexOf('\n\n')
|
44 | this.excerpt = caret > 0 ? this.content.slice(0, caret) : this.content
|
45 | }
|
46 | else {
|
47 | throw new Error('Failed to parse YAML front matter from ' + fpath)
|
48 | }
|
49 | }
|
50 |
|
51 | if (this.categories.length === 0) {
|
52 | if (this.category) {
|
53 | this.categories = this.category
|
54 | delete this.category
|
55 | }
|
56 | else {
|
57 | var parentFolders = path.relative(this.site.cwd, path.dirname(fpath))
|
58 | this.categories = _.without(parentFolders.split(path.sep), '_posts', '_drafts')
|
59 | }
|
60 | }
|
61 |
|
62 |
|
63 |
|
64 | if (_.isString(this.categories)) {
|
65 | this.categories = this.categories.split(' ')
|
66 | }
|
67 | if (_.isString(this.tags)) {
|
68 | this.tags = this.tags.split(' ')
|
69 | }
|
70 |
|
71 |
|
72 | if (_.isString(this.date)) {
|
73 | this.date = new Date(this.date)
|
74 | }
|
75 |
|
76 | if (!this.hasOwnProperty('published')) {
|
77 | this.published = true
|
78 | }
|
79 |
|
80 | var data = {
|
81 | year: this.date.getFullYear(),
|
82 | i_month: this.date.getMonth() + 1,
|
83 | i_day: this.date.getDate(),
|
84 | title: this.slug,
|
85 | categories: this.categories ? this.categories[0] : ''
|
86 | }
|
87 |
|
88 | data.month = util.pad(data.i_month, '0', 2)
|
89 | data.day = util.pad(data.i_day, '0', 2)
|
90 |
|
91 | this.url = this.site.permalink
|
92 | .replace(/:(\w+)/g, function(m, key) {
|
93 | return data[key] || ''
|
94 | })
|
95 | .replace(/\/{2,}/g, '/')
|
96 |
|
97 | this.id = path.join(path.dirname(this.url), path.basename(this.url, '.html'))
|
98 |
|
99 | this.dest = path.join(this.site.dest, this.site.baseurl.slice(1), this.url)
|
100 | if (path.extname(this.dest) !== '.html') {
|
101 | this.dest = this.dest.replace(/\/?$/, '/index.html')
|
102 | }
|
103 | }
|
104 |
|
105 | Object.defineProperties(Post.prototype, {
|
106 | valid: {
|
107 | get: function() {
|
108 | return /(_posts|_drafts)$/.test(path.dirname(this.path)) &&
|
109 | PTN_POST_FILE.test(path.basename(this.path))
|
110 | }
|
111 | },
|
112 |
|
113 | future: {
|
114 | get: function() {
|
115 | var now = new Date()
|
116 | var tomorrow = new Date(now.getFullYear(), now.getMonth(), now.getDate() + 1)
|
117 |
|
118 | return tomorrow.getTime() <= this.date.getTime()
|
119 | }
|
120 | },
|
121 |
|
122 | publishable: {
|
123 | get: function() {
|
124 | return this.valid &&
|
125 | (this.published || this.site.includeDrafts) &&
|
126 | (!this.future || this.site.includeFuture)
|
127 | }
|
128 | }
|
129 | })
|
130 |
|
131 |
|
132 | module.exports = Post
|