From b089449bccf6238c6e4ef1e203371dc9e03a5a2f Mon Sep 17 00:00:00 2001 From: Giuseppe Sorce Date: Tue, 1 Oct 2013 13:45:20 +0200 Subject: [PATCH 1/5] Allow indexPagePath to be an array --- src/tagging.plugin.coffee | 46 ++++++++++++++++++++++----------------- 1 file changed, 26 insertions(+), 20 deletions(-) diff --git a/src/tagging.plugin.coffee b/src/tagging.plugin.coffee index a101aff..7cb70ad 100644 --- a/src/tagging.plugin.coffee +++ b/src/tagging.plugin.coffee @@ -86,27 +86,33 @@ module.exports = (BasePlugin) -> # check whether a document for this tag already exists in the collection if not @tagCollection.findOne(tag: tag) slug = balUtil.generateSlugSync(tag) - doc = @docpad.createDocument( - slug: slug - relativePath: config.indexPagePath + "/" + slug + ".html" - isDocument: true - encoding: 'utf8' - , - data: " " # NOTE: can't be empty string due to - # quirk in FileModel (as of docpad v6.25) - meta: - layout: config.indexPageLayout - referencesOthers: true - tag: tag + + if _(config.indexPagePath).isString() + config.indexPagePath = [config.indexPagePath] + + _(config.indexPagePath).each( (path) -> + doc = @docpad.createDocument( + slug: slug + relativePath: path + "/" + slug + ".html" + isDocument: true + encoding: 'utf8' + , + data: " " # NOTE: can't be empty string due to + # quirk in FileModel (as of docpad v6.25) + meta: + layout: config.indexPageLayout + referencesOthers: true + tag: tag + ) + database.add doc + newDocs.add doc + + # if we're reloading (reset = false), our new document + # will not have made it into the collection of modified + # documents to render - so we need to add it + if not renderCollection.findOne(tag: tag) + renderCollection.add doc ) - database.add doc - newDocs.add doc - - # if we're reloading (reset = false), our new document - # will not have made it into the collection of modified - # documents to render - so we need to add it - if not renderCollection.findOne(tag: tag) - renderCollection.add doc docs_created++ From 10c29f6be786418807529b98f58c045e97d27984 Mon Sep 17 00:00:00 2001 From: Giuseppe Sorce Date: Tue, 1 Oct 2013 13:47:11 +0200 Subject: [PATCH 2/5] updates README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5f662ac..29e0bb2 100644 --- a/README.md +++ b/README.md @@ -90,7 +90,7 @@ ul -> - *collectionName* : Can be used to narrow the scope of the plugin to a specific collection and therefore improve performance (defaults to 'documents'). - *indexPageLayout* : Override the name of the layout file used for the tag index pages (defaults to 'tags'). -- *indexPagePath* : Override the relative output path of the tag index pages (defaults to 'tags'). +- *indexPagePath* : Override the relative output path of the tag index pages (defaults to 'tags'). An Array of paths is also accepted (e.g. ['en/tags', 'de/tags']) - *getTagWeight* : Override the function used to generate the tag weights (see below). ### Customising the weight function From 0b0cf078c7778c5c0d14e80dc3ca4b8923db8b5b Mon Sep 17 00:00:00 2001 From: Giuseppe Sorce Date: Tue, 1 Oct 2013 14:24:13 +0200 Subject: [PATCH 3/5] Adds relativePath matching as a rendering condition --- src/tagging.plugin.coffee | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/tagging.plugin.coffee b/src/tagging.plugin.coffee index 7cb70ad..4cbad88 100644 --- a/src/tagging.plugin.coffee +++ b/src/tagging.plugin.coffee @@ -81,19 +81,20 @@ module.exports = (BasePlugin) -> docpad.log 'debug', 'tagging::generateTags: Generating tag index pages' docs_created = 0 + if _(config.indexPagePath).isString() + config.indexPagePath = [config.indexPagePath] + newDocs = new docpad.FilesCollection() for own tag of @tagCloud # check whether a document for this tag already exists in the collection if not @tagCollection.findOne(tag: tag) - slug = balUtil.generateSlugSync(tag) - - if _(config.indexPagePath).isString() - config.indexPagePath = [config.indexPagePath] + slug = balUtil.generateSlugSync(tag) _(config.indexPagePath).each( (path) -> + relativePath = path + "/" + slug + ".html" doc = @docpad.createDocument( slug: slug - relativePath: path + "/" + slug + ".html" + relativePath: relativePath isDocument: true encoding: 'utf8' , @@ -110,7 +111,7 @@ module.exports = (BasePlugin) -> # if we're reloading (reset = false), our new document # will not have made it into the collection of modified # documents to render - so we need to add it - if not renderCollection.findOne(tag: tag) + if not renderCollection.findOne({tag: tag, relativePath: relativePath}) renderCollection.add doc ) From 9573f35ceab36d2515824cacca3fb42ddec60d2b Mon Sep 17 00:00:00 2001 From: Giuseppe Sorce Date: Mon, 7 Oct 2013 17:00:17 +0200 Subject: [PATCH 4/5] Replace multiple indexPagePath with context additionally allows context query for tagCloud and getTagurl --- src/tagging.plugin.coffee | 286 ++++++++++++++++++++------------------ 1 file changed, 149 insertions(+), 137 deletions(-) diff --git a/src/tagging.plugin.coffee b/src/tagging.plugin.coffee index 4cbad88..bde5ff2 100644 --- a/src/tagging.plugin.coffee +++ b/src/tagging.plugin.coffee @@ -1,140 +1,152 @@ module.exports = (BasePlugin) -> - _ = require('lodash') - balUtil = require('bal-util') - - class Tagging extends BasePlugin - name: 'tagging' - - config: - collectionName: 'documents' - indexPageLayout: 'tags' - indexPagePath: 'tags' - getTagWeight: (count, maxCount) -> - # apply logarithmic weight algorithm - logmin = 0 - logmax = Math.log(maxCount) - result = (Math.log(count) - logmin) / (logmax - logmin) - return result - - tagCloud: null - tagCollection: null - maxCount: 0 - - # This is to prevent/detect recursive firings of ContextualizeAfter event - contextualizeAfterLock: false - - extendCollections: (next) -> - @tagCollection = @docpad.getDatabase().createLiveChildCollection() - .setQuery("isTagIndex", tag: $exists: true) - - extendTemplateData: ({templateData}) -> - me = @ - templateData.getTagCloud = -> - return me.tagCloud - templateData.getTagUrl = (tag) -> - return me.getTagUrl(tag) - @ - - contextualizeAfter: ({collection, templateData}, next) -> - if not @contextualizeAfterLock - return @generateTags(collection, next) - else - next() - @ - - getTagUrl: (tag) -> - doc = @tagCollection.findOne(tag: tag) - return doc?.get('url') - - generateTags: (renderCollection, next) -> - - # Prepare - me = @ - docpad = @docpad - config = @config - database = docpad.getDatabase() - targetedDocuments = docpad.getCollection(@config.collectionName) - - # regenerate tag cloud - - docpad.log 'debug', 'tagging::generateTags: Generating tag cloud' - - @maxCount = 0 - @tagCloud = {} - - targetedDocuments.forEach (document) => - # Prepare - tags = document.get('tags') or [] - - for tag in tags - @tagCloud[tag] ?= - tag: tag, - count: 0, - url: "" - weight: 0 - count = ++@tagCloud[tag].count - @maxCount = count if count > @maxCount - - # generate tag index pages - - docpad.log 'debug', 'tagging::generateTags: Generating tag index pages' - - docs_created = 0 - if _(config.indexPagePath).isString() - config.indexPagePath = [config.indexPagePath] - - newDocs = new docpad.FilesCollection() - for own tag of @tagCloud - # check whether a document for this tag already exists in the collection - if not @tagCollection.findOne(tag: tag) - slug = balUtil.generateSlugSync(tag) - - _(config.indexPagePath).each( (path) -> - relativePath = path + "/" + slug + ".html" - doc = @docpad.createDocument( - slug: slug - relativePath: relativePath - isDocument: true - encoding: 'utf8' - , - data: " " # NOTE: can't be empty string due to - # quirk in FileModel (as of docpad v6.25) - meta: - layout: config.indexPageLayout - referencesOthers: true - tag: tag - ) - database.add doc - newDocs.add doc - - # if we're reloading (reset = false), our new document - # will not have made it into the collection of modified - # documents to render - so we need to add it - if not renderCollection.findOne({tag: tag, relativePath: relativePath}) - renderCollection.add doc - ) - - docs_created++ - - docpad.log 'debug', "tagging::generateTags: #{docs_created} new docs added" - - # docpad has already called load and contextualize on its documents - # so we need to call it manually here for our new docs - docpad.loadFiles {collection: newDocs}, (err) => - if err then return next(err) - - @contextualizeAfterLock = true - docpad.contextualizeFiles {collection: newDocs}, (err) => - if err then return next(err) - - @contextualizeAfterLock = false - - for own tag, item of @tagCloud - @tagCloud[tag].url = @getTagUrl(tag) - @tagCloud[tag].weight = @config.getTagWeight(item.count, @maxCount) - - next() - - @ + _ = require('lodash') + balUtil = require('bal-util') + + class Tagging extends BasePlugin + name: 'tagging' + + config: + collectionName: 'documents' + indexPageLayout: 'tags' + indexPagePath: 'tags' + context: null + getTagWeight: (count, maxCount) -> + # apply logarithmic weight algorithm + logmin = 0 + logmax = Math.log(maxCount) + result = (Math.log(count) - logmin) / (logmax - logmin) + return result + + tagCloud: {} + tagCollection: null + + # This is to prevent/detect recursive firings of ContextualizeAfter event + contextualizeAfterLock: false + + extendCollections: (next) -> + @tagCollection = @docpad.getDatabase().createLiveChildCollection() + .setQuery("isTagIndex", tag: $exists: true) + + extendTemplateData: ({templateData}) -> + me = @ + templateData.getTagCloud = (options) -> + return me.getTagCloud(options) + templateData.getTagUrl = (tag,options) -> + return me.getTagUrl(tag,options) + @ + + contextualizeAfter: ({collection, templateData}, next) -> + if not @contextualizeAfterLock + return @generateTags(collection, next) + else + next() + @ + + getTagCloud: (options) -> + context = options?.context ? 'all' + return @tagCloud[context].tags + + getTagUrl: (tag,options) -> + query = options ? {} + query.tag = tag + doc = @tagCollection.findOne(query) + return doc?.get('url') + + generateTags: (renderCollection, next) -> + # Prepare + me = @ + docpad = @docpad + config = @config + database = docpad.getDatabase() + targetedDocuments = docpad.getCollection(@config.collectionName) + + # regenerate tag cloud + + docpad.log 'debug', 'tagging::generateTags: Generating tag cloud' + + targetedDocuments.forEach (document) => + # Prepare + tags = document.get('tags') or [] + contexts = _(['all']).union([document.get('context') or null]) + .flatten() + .compact() + .value() + + for context in contexts + @tagCloud[context] ?= {tags: {}, maxCount: 0} + cloud = @tagCloud[context] + + for tag in tags + cloud.tags[tag] ?= + tag: tag, + count: 0, + url: "" + weight: 0 + count = ++cloud.tags[tag].count + cloud.maxCount = count if count > cloud.maxCount + + # generate tag index pages + + docpad.log 'debug', 'tagging::generateTags: Generating tag index pages' + docs_created = 0 + newDocs = new docpad.FilesCollection() + for own context, tagCloud of @tagCloud + for own tag of tagCloud.tags + + # check whether a document for this tag already exists in the collection + if not @tagCollection.findOne({tag: tag, context: context}) + slug = balUtil.generateSlugSync(tag) + contextPath = if context=='all' then '' else context + relativePath = _([ + contextPath, + config.indexPagePath, + slug + ".html" + ]).compact().join('/') + + doc = @docpad.createDocument( + slug: slug + relativePath: relativePath + context: context + isDocument: true + encoding: 'utf8' + , + data: " " # NOTE: can't be empty string due to, quirk in FileModel (as of docpad v6.25) + meta: + layout: config.indexPageLayout + referencesOthers: true + tag: tag + context: context + ) + database.add doc + newDocs.add doc + docs_created++ + + # if we're reloading (reset = false), our new document + # will not have made it into the collection of modified + # documents to render - so we need to add it + if not renderCollection.findOne({tag: tag, context: context}) + renderCollection.add doc + + docpad.log 'debug', "tagging::generateTags: #{docs_created} new docs added" + + # docpad has already called load and contextualize on its documents + # so we need to call it manually here for our new docs + docpad.loadFiles {collection: newDocs}, (err) => + if err then return next(err) + + @contextualizeAfterLock = true + docpad.contextualizeFiles {collection: newDocs}, (err) => + if err then return next(err) + + @contextualizeAfterLock = false + + for own context, tagCloud of @tagCloud + for own tag, item of tagCloud.tags + item.url = @getTagUrl(tag, {context: context}) + item.weight = @config.getTagWeight(item.count, tagCloud.maxCount) + + next() + + @ From e9447f7c3f77380d20f49bf13b3f22cea0f0b4b9 Mon Sep 17 00:00:00 2001 From: Giuseppe Sorce Date: Wed, 30 Oct 2013 15:30:19 +0100 Subject: [PATCH 5/5] updated coffee dependency --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b67695d..6169b00 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "bal-util": "~1.16.10" }, "devDependencies": { - "coffee-script": "~1.4.0" + "coffee-script": "~1.6.0" }, "main": "./out/tagging.plugin.js", "scripts": {