1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 | var path = require('path');
|
21 | var util = require('util');
|
22 | var fs = require('fs');
|
23 | var async = require('async');
|
24 | var taggen = require('tagcloud-generator');
|
25 | var Tempdir = require('temporary/lib/dir');
|
26 |
|
27 | var tagCloudData = undefined;
|
28 | var tempDir = undefined;
|
29 |
|
30 | var logger;
|
31 |
|
32 |
|
33 |
|
34 |
|
35 | module.exports.config = function(akasha, config) {
|
36 |
|
37 | logger = akasha.getLogger("tagged-content");
|
38 |
|
39 | config.root_partials.push(path.join(__dirname, 'partials'));
|
40 |
|
41 | if (config.mahabhuta) {
|
42 | config.mahabhuta.push(function($, metadata, dirty, done) {
|
43 |
|
44 | $('tag-cloud').each(function(i, elem) {
|
45 | genTagCloudData(akasha, config);
|
46 | $(this).replaceWith(
|
47 | taggen.generateSimpleCloud(tagCloudData.tagData, function(tagName) {
|
48 | return tagPageUrl(config, tagName);
|
49 | }, "")
|
50 | );
|
51 | });
|
52 | done();
|
53 | });
|
54 | config.mahabhuta.push(function($, metadata, dirty, done) {
|
55 |
|
56 | var tfds = [];
|
57 | $('tags-for-document').each(function(i, elem) { tfds.push(elem); });
|
58 | async.each(tfds,
|
59 | function(tfd, cb) {
|
60 | if (tfd)
|
61 | doTagsForDocument(metadata, "tagged-content-doctags.html.ejs", function(err, tags) {
|
62 | if (err) cb(err);
|
63 | else {
|
64 | $(tfd).replaceWith(tags);
|
65 | cb();
|
66 | }
|
67 | });
|
68 | else cb();
|
69 | },
|
70 | function(err) {
|
71 | if (err) done(err);
|
72 | else done();
|
73 | });
|
74 | });
|
75 | }
|
76 |
|
77 | config.funcs.tagCloud = function(arg, callback) {
|
78 | genTagCloudData(akasha, config);
|
79 | var val = taggen.generateSimpleCloud(tagCloudData.tagData, function(tagName) {
|
80 | return tagPageUrl(config, tagName);
|
81 | }, "");
|
82 |
|
83 | if (callback) callback(undefined, val);
|
84 | return val;
|
85 | }
|
86 |
|
87 | var doTagsForDocument = function(arg, template, done) {
|
88 | akasha.readDocumentEntry(config, arg.documentPath, function(err, entry) {
|
89 | if (err) done(err);
|
90 | else {
|
91 | var taglist = entryTags(entry);
|
92 |
|
93 | var val = "";
|
94 | if (taglist) {
|
95 | var tagz = [];
|
96 | for (var i = 0; i < taglist.length; i++) {
|
97 | tagz.push({
|
98 | tagName: taglist[i],
|
99 | tagUrl: tagPageUrl(config, taglist[i])
|
100 | });
|
101 | }
|
102 | val = akasha.partialSync(template, { tagz: tagz });
|
103 | }
|
104 | done(undefined, val);
|
105 | }
|
106 | });
|
107 | }
|
108 |
|
109 |
|
110 | config.funcs.tagsForDocument = function(arg, callback) {
|
111 | throw new Error("do not call tagsForDocument - use <tags-for-document>");
|
112 | doTagsForDocument(arg, "tagged-content-doctags.html.ejs", callback);
|
113 | }
|
114 |
|
115 | |
116 |
|
117 |
|
118 |
|
119 |
|
120 | akasha.emitter.on('before-render-files', function(cb) {
|
121 | util.log('before-render-files received');
|
122 | module.exports.generateTagIndexes(akasha, config, function(err) {
|
123 | if (err) cb(err); else cb();
|
124 | });
|
125 | });
|
126 | akasha.emitter.on('done-render-files', function(cb) {
|
127 | util.log('done-render-files received');
|
128 |
|
129 | cb();
|
130 | });
|
131 | }
|
132 |
|
133 | var tagPageUrl = function(config, tagName) {
|
134 | return config.tags.pathIndexes + tag2encode4url(tagName) +'.html';
|
135 | }
|
136 |
|
137 | var tagParse = function(tags) {
|
138 | var taglist = [];
|
139 | var re = /\s*,\s*/;
|
140 | if (tags) tags.split(re).forEach(function(tag) {
|
141 | taglist.push(tag.trim());
|
142 | });
|
143 | return taglist;
|
144 | }
|
145 |
|
146 | var entryTags = function(entry) {
|
147 | if (entry.frontmatter
|
148 | && entry.frontmatter.hasOwnProperty('yaml')
|
149 | && entry.frontmatter.yaml
|
150 | && entry.frontmatter.yaml.hasOwnProperty('tags')) {
|
151 |
|
152 |
|
153 |
|
154 | var taglist = tagParse(entry.frontmatter.yaml.tags);
|
155 | return taglist;
|
156 | } else {
|
157 | return undefined;
|
158 | }
|
159 | }
|
160 |
|
161 |
|
162 |
|
163 |
|
164 |
|
165 |
|
166 |
|
167 |
|
168 | var tag2encode4url = function(tagName) {
|
169 | return tagName.toLowerCase()
|
170 | .replace(/ /g, '-')
|
171 | .replace(/\//g, '-')
|
172 | .replace(/\?/g, '-')
|
173 | .replace(/=/g, '-')
|
174 | .replace(/&/g, '-');
|
175 | }
|
176 |
|
177 | var sortByTitle = function(a,b) {
|
178 | if (a.frontmatter.yaml.title < b.frontmatter.yaml.title) return -1;
|
179 | else if (a.frontmatter.yaml.title === b.frontmatter.yaml.title) return 0;
|
180 | else return 1;
|
181 | };
|
182 |
|
183 | var sortByDate = function(a,b) {
|
184 | var aPublicationDate = Date.parse(
|
185 | a.frontmatter.yaml.publicationDate ? a.frontmatter.yaml.publicationDate : a.stat.mtime
|
186 | );
|
187 | var bPublicationDate = Date.parse(
|
188 | b.frontmatter.yaml.publicationDate ? b.frontmatter.yaml.publicationDate : b.stat.mtime
|
189 | );
|
190 | if (aPublicationDate < bPublicationDate) return -1;
|
191 | else if (aPublicationDate === bPublicationDate) return 0;
|
192 | else return 1;
|
193 | };
|
194 |
|
195 | module.exports.generateTagIndexes = function(akasha, config, cb) {
|
196 | genTagCloudData(akasha, config);
|
197 | tempDir = new Tempdir;
|
198 | config.root_docs.push(tempDir.path);
|
199 | var tagsDir = path.join(tempDir.path, config.tags.pathIndexes);
|
200 | fs.mkdirSync(tagsDir);
|
201 |
|
202 | for (tagnm in tagCloudData.tagData) {
|
203 | var tagData = tagCloudData.tagData[tagnm];
|
204 | var tagNameEncoded = tag2encode4url(tagData.tagName);
|
205 |
|
206 | if (config.tags.sortBy === 'date') {
|
207 | tagData.entries.sort(sortByDate);
|
208 | tagData.entries.reverse();
|
209 | } else if (config.tags.sortBy === 'title') {
|
210 | tagData.entries.sort(sortByTitle);
|
211 | } else {
|
212 | tagData.entries.sort(sortByTitle);
|
213 | };
|
214 |
|
215 | var entryText = config.tags.header
|
216 | .replace("@title@", tagData.tagName)
|
217 | .replace("@tagName@", tagData.tagName);
|
218 |
|
219 | var entriez = [];
|
220 | for (var j = 0; j < tagData.entries.length; j++) {
|
221 | var entry = tagData.entries[j];
|
222 | entriez.push({
|
223 | url: akasha.urlForFile(entry.path),
|
224 | title: entry.frontmatter.yaml.title,
|
225 | teaser: entry.frontmatter.yaml.teaser
|
226 | ? entry.frontmatter.yaml.teaser
|
227 | : "",
|
228 | youtubeThumbnail: entry.frontmatter.yaml.youtubeThumbnail
|
229 | ? entry.frontmatter.yaml.youtubeThumbnail
|
230 | : undefined
|
231 | });
|
232 | }
|
233 |
|
234 |
|
235 | var rsslink = "";
|
236 | if (config.rss) {
|
237 |
|
238 |
|
239 | tagData.entries.sort(sortByDate);
|
240 | tagData.entries.reverse();
|
241 |
|
242 | var rssitems = [];
|
243 | for (var q = 0; q < tagData.entries.length; q++) {
|
244 | var entry = tagData.entries[q];
|
245 | rssitems.push({
|
246 | title: entry.frontmatter.yaml.title,
|
247 | description: entry.frontmatter.yaml.teaser
|
248 | ? entry.frontmatter.yaml.teaser
|
249 | : "",
|
250 | url: config.root_url +'/'+ entry.renderedFileName,
|
251 | date: entry.frontmatter.yaml.publicationDate
|
252 | ? entry.frontmatter.yaml.publicationDate
|
253 | : entry.stat.mtime
|
254 | });
|
255 | }
|
256 |
|
257 |
|
258 | var feedRenderTo = path.join(config.tags.pathIndexes, tagNameEncoded +".xml");
|
259 | logger.trace(tagnm +' writing RSS to '+ feedRenderTo);
|
260 |
|
261 | akasha.generateRSS(config, {
|
262 | feed_url: config.root_url + feedRenderTo,
|
263 | pubDate: new Date()
|
264 | },
|
265 | rssitems, feedRenderTo, function(err) {
|
266 | if (err) logger.error(err);
|
267 | });
|
268 |
|
269 | rsslink = '<a href="'+ feedRenderTo +'"><img src="/img/rss_button.gif" align="right" width="50"/></a>';
|
270 | }
|
271 |
|
272 |
|
273 | entryText += akasha.partialSync("tagged-content-tagpagelist.html.ejs", {
|
274 | entries: entriez
|
275 | });
|
276 | if (rsslink !== "") {
|
277 | entryText += '<div>' + rsslink + '</div>';
|
278 | entryText += '<rss-header-meta href="'+ config.root_url + feedRenderTo +'"></rss-header-meta>';
|
279 | }
|
280 | var tagFileName = path.join(tagsDir, tagNameEncoded +".html.ejs");
|
281 |
|
282 | fs.writeFileSync(tagFileName, entryText, {
|
283 | encoding: 'utf8'
|
284 | });
|
285 | }
|
286 |
|
287 | akasha.gatherDir(config, tempDir.path, function(err) {
|
288 | if (err) cb(err); else cb();
|
289 | });
|
290 | }
|
291 |
|
292 | var genTagCloudData = function(akasha, config) {
|
293 | if (!tagCloudData) {
|
294 | tagCloudData = {
|
295 | tagData: []
|
296 | };
|
297 | akasha.eachDocument(config, function(entry) {
|
298 |
|
299 | var taglist = entryTags(entry);
|
300 | if (taglist) {
|
301 | for (var i = 0; i < taglist.length; i++) {
|
302 | var tagnm = taglist[i];
|
303 | if (! tagCloudData.tagData[tagnm]) {
|
304 | tagCloudData.tagData[tagnm] = { tagName: tagnm, entries: [] };
|
305 | }
|
306 |
|
307 | tagCloudData.tagData[tagnm].entries.push(entry);
|
308 | }
|
309 | }
|
310 | });
|
311 | util.log('******** DONE akasha.eachDocument count='+ tagCloudData.tagData.length);
|
312 | |
313 |
|
314 |
|
315 |
|
316 |
|
317 | for (tagnm in tagCloudData.tagData) {
|
318 | tagCloudData.tagData[tagnm].count = tagCloudData.tagData[tagnm].entries.length;
|
319 |
|
320 | }
|
321 | taggen.generateFontSizes(tagCloudData.tagData);
|
322 |
|
323 | }
|
324 | } |
\ | No newline at end of file |