From cadbcf3c0badc301419358d9389a6bc56dcf1be7 Mon Sep 17 00:00:00 2001 From: Benjamin Lupton Date: Thu, 19 Jul 2012 11:33:31 +1000 Subject: [PATCH] Pulled #251, Fixed #269, #268 We now only clear the meta attributes from the document attributes on a new parse. Instead of clearing everything. Other parsing optimisations were also made. File IDs are now also the relativePath instead of the relativeBase to avoid collisions. --- src/lib/docpad.coffee | 147 +++++++++----------- src/lib/interfaces/console.coffee | 2 +- src/lib/models/document.coffee | 70 +++++++--- src/lib/models/file.coffee | 133 +++++++++--------- src/lib/testers.coffee | 2 +- src/test/docpad.test.coffee | 32 +++-- test/out-expected/.dotdocument | 1 + test/out-expected/.dotfile | 1 + test/out-expected/attributes-nolayout.txt | 2 +- test/out-expected/attributes-withlayout.txt | 17 ++- test/package.json | 2 +- test/src/documents/.dotdocument | 1 + test/src/files/.dotfile | 1 + 13 files changed, 215 insertions(+), 196 deletions(-) create mode 100644 test/out-expected/.dotdocument create mode 100644 test/out-expected/.dotfile create mode 100644 test/src/documents/.dotdocument create mode 100644 test/src/files/.dotfile diff --git a/src/lib/docpad.coffee b/src/lib/docpad.coffee index 1799aa46..dbd01af5 100755 --- a/src/lib/docpad.coffee +++ b/src/lib/docpad.coffee @@ -3,7 +3,6 @@ # Necessary pathUtil = require('path') -fsUtil = require('fs') _ = require('underscore') caterpillar = require('caterpillar') CSON = require('cson') @@ -131,31 +130,6 @@ class DocPad extends EventEmitterEnhanced getEvents: -> @events - errors: - '400': 'Bad Request' - '401': 'Unauthorized' - '402': 'Payment Required' - '403': 'Forbidden' - '404': 'Not Found' - '405': 'Method Not Allowed' - '406': 'Not Acceptable' - '407': 'Proxy Authentication Required' - '408': 'Request Timeout' - '409': 'Conflict' - '410': 'Gone' - '411': 'Length Required' - '412': 'Precondition Failed' - '413': 'Request Entity Too Large' - '414': 'Request-URI Too Long' - '415': 'Unsupported Media Type' - '416': 'Requested Range Not Satisfiable' - '417': 'Expectation Failed' - '500': 'Internal Server Error' - '501': 'Not Implemented' - '502': 'Bad Gateway' - '503': 'Service Unavailable' - '504': 'Gateway Timeout' - '505': 'HTTP Version Not Supported' # --------------------------------- # Collections @@ -522,10 +496,6 @@ class DocPad extends EventEmitterEnhanced # Whether or not we should extend the server with extra middleware and routing extendServer: true - # Enable Custom Error Pages - # A flag to provide an entry to handle custom error pages - useCustomErrors: false - # Port # The port that the server should use port: process.env.PORT ? 9778 @@ -1322,6 +1292,7 @@ class DocPad extends EventEmitterEnhanced {layoutId} = opts layouts = docpad.getCollection('layouts') layout = layouts.findOne(id: layoutId) + layout = layouts.findOne(relativePath: layoutId) unless layout layout = layouts.findOne(relativeBase: layoutId) unless layout next(null,{layout}) @@ -2560,6 +2531,54 @@ class DocPad extends EventEmitterEnhanced # --------------------------------- # Server + # Serve Document + serveDocument: (opts,next) => + # Prepare + [opts,next] = balUtil.extractOptsAndCallback(opts,next) + {document,err,req,res} = opts + docpad = @ + + # If no document, then exit early + unless document + if opts.statusCode? + return res.send(opts.statusCode) + else + return next() + + # Content Type + contentType = document.get('contentTypeRendered') or document.get('contentType') + res.contentType(contentType) + + # Send + dynamic = document.get('dynamic') + if dynamic + templateData = docpad.getTemplateData({req,err}) + document.render {templateData}, (err) -> + content = document.get('contentRendered') or document.get('content') or document.getData() + if err + docpad.error(err) + return next(err) + else + if opts.statusCode? + return res.send(content, opts.statusCode) + else + return res.send(content) + else + content = document.get('contentRendered') or document.get('content') or document.getData() + if content + if opts.statusCode? + return res.send(content, opts.statusCode) + else + return res.send(content) + else + if opts.statusCode? + return res.send(opts.statusCode) + else + return next() + + # Chain + @ + # Server server: (opts,next) => # Require @@ -2631,7 +2650,7 @@ class DocPad extends EventEmitterEnhanced return next(err) if err # Router Middleware - server.use server.router + server.use(server.router) # Routing server.use (req,res,next) -> @@ -2650,66 +2669,32 @@ class DocPad extends EventEmitterEnhanced if url isnt pageUrl return res.redirect(url,301) - # Content Type - contentTypeRendered = document.get('contentTypeRendered') - if contentTypeRendered - res.contentType(contentTypeRendered) - - # Send - dynamic = document.get('dynamic') - if dynamic - templateData = docpad.getTemplateData(req:req) - document.render {templateData}, (err) -> - contentRendered = document.get('contentRendered') - if err - docpad.error(err) - return next(err) - else - return res.send(contentRendered) - else - contentRendered = document.get('contentRendered') - if contentRendered - return res.send(contentRendered) - else - return next() + # Serve the document to the user + docpad.serveDocument({document,req,res,next}) # Static if config.maxAge - server.use(express.static config.outPath, maxAge: config.maxAge) + server.use(express.static(config.outPath,{maxAge:config.maxAge})) else - server.use(express.static config.outPath) + server.use(express.static(config.outPath)) # 404 Middleware - server.use (req, res, next) -> + server.use (req,res,next) -> database = docpad.getDatabase() - return next() unless database - notFound = 404 - if config.useCustomErrors - file = database.findOne(relativePath: '404.html') - if file - data = file.get('contentRendered') or document.get('content') - else - data = notFound + ' ' + errorCodes[notFound] - - return res.send(data, notFound) - else - return res.send(notFound) + return res.send(500) unless database + + # Serve the document to the user + document = database.findOne(relativePath: '404.html') + docpad.serveDocument({document,req,res,next,statusCode:404}) # 500 Middleware - server.use (err, req, res, next) -> + server.error (err,req,res,next) -> database = docpad.getDatabase() - return next() unless database - serverError = 500 - if config.useCustomErrors - file = database.findOne(relativePath: '404.html') - if file - data = file.get('contentRendered') or document.get('content') - else - data = serverError + ' ' + errorCodes[serverError] - - return res.send(data, serverError) - else - res.send(serverError) + return res.send(500) unless database + + # Serve the document to the user + document = database.findOne(relativePath: '404.html') + docpad.serveDocument({document,req,res,next,statusCode:500,err}) # Start the Server startServer() diff --git a/src/lib/interfaces/console.coffee b/src/lib/interfaces/console.coffee index 5fdf1eb5..399ab8be 100755 --- a/src/lib/interfaces/console.coffee +++ b/src/lib/interfaces/console.coffee @@ -276,7 +276,7 @@ class ConsoleInterface # Prepare filename filename = commander.args[0] or null - if !filename or consoleInterface.split('.').length <= 2 # [name,ext,ext] = 3 parts + if !filename or filename.split('.').length <= 2 # [name,ext,ext] = 3 parts opts.renderSingleExtensions = true opts.filename = filename diff --git a/src/lib/models/document.coffee b/src/lib/models/document.coffee index f79ef191..882904a4 100755 --- a/src/lib/models/document.coffee +++ b/src/lib/models/document.coffee @@ -119,11 +119,22 @@ class DocumentModel extends FileModel # Parses some data, and loads the meta data and content from it # next(err) parseData: (data,next) -> - # Reset + # Prepare + meta = @getMeta() + + # Wipe any meta attributes that we've copied over to our file + reset = {} + for own key,value of meta.attributes + reset[key] = @defaults[key] + reset = balUtil.dereference(reset) + @set(reset) + + # Then wipe the layout and clear the meta attributes from the meta model @layout = null - @getMeta().clear() + meta.clear() - # Super + # Reparse the data and extract the content + # With the content, fetch the new meta data, header, and body super data, => # Content content = @get('content') @@ -146,7 +157,7 @@ class DocumentModel extends FileModel # Language try switch parser - when 'coffee', 'cson', 'coffeescript', 'coffee-script' + when 'cson', 'coffee', 'coffeescript', 'coffee-script' CSON = require('cson') unless CSON meta = CSON.parseSync(header) @meta.set(meta) @@ -297,47 +308,60 @@ class DocumentModel extends FileModel # Check return next(err) if err + # Prepare + changes = {} + # Fetch meta = @getMeta() - fullPath = @get('fullPath') or null - basename = @get('basename') or null - relativeBase = @get('relativeBase') or null - relativeDirPath = @get('relativeDirPath') ? null + fullPath = @get('fullPath') + basename = @get('basename') + relativeDirPath = @get('relativeDirPath') extensions = @get('extensions') - extensionRendered = @get('extensionRendered') or null - url = meta.get('url') or null - name = meta.get('name') or null - outPath = meta.get('outPath') or null - contentTypeRendered = null + extensionRendered = @get('extensionRendered') + url = meta.get('url') + name = meta.get('name') + outPath = meta.get('outPath') filenameRendered = null - # Adjust + # Use our eve's rendered extension if it exists if eve? extensionRendered = eve.get('extensionRendered') - if basename? and extensionRendered? + + # Figure out the rendered filename + if basename and extensionRendered if basename[0] is '.' and extensionRendered is extensions[0] filenameRendered = basename else filenameRendered = "#{basename}.#{extensionRendered}" - if relativeDirPath? and filenameRendered? + changes.filenameRendered = filenameRendered + + # Figure out the rendered url + if !url and filenameRendered if relativeDirPath url = "/#{relativeDirPath}/#{filenameRendered}" else url = "/#{filenameRendered}" - if filenameRendered? - name or= filenameRendered - if @outDirPath? - outPath = pathUtil.join(@outDirPath,url) - if url? + changes.url = url + + # Set name if it doesn't exist already + if !name and filenameRendered? + changes.name = name = filenameRendered + + # Create the outPath if we have a outpute directory + if @outDirPath + changes.outPath = outPath = pathUtil.join(@outDirPath,url) + + # Update the URL + if url @removeUrl(@get('url')) @setUrl(url) # Content Types if outPath or fullPath - contentTypeRendered = mime.lookup(outPath or fullPath) + changes.contentTypeRendered = contentTypeRendered = mime.lookup(outPath or fullPath) # Apply - @set({extensionRendered,filenameRendered,url,name,outPath,contentTypeRendered}) + @set(changes) # Forward next() diff --git a/src/lib/models/file.coffee b/src/lib/models/file.coffee index 5d91b5f4..cccc10d9 100755 --- a/src/lib/models/file.coffee +++ b/src/lib/models/file.coffee @@ -78,6 +78,12 @@ class FileModel extends Model # The MIME content-type for the source document contentType: null + # The date object for when this document was created + ctime: null + + # The date object for when this document was last modified + mtime: null + # --------------------------------- # Content variables @@ -95,7 +101,7 @@ class FileModel extends Model # The title for this document title: null - # The date object for this document + # The date object for this document, defaults to mtime date: null # The generated slug (url safe seo title) for this document @@ -125,8 +131,9 @@ class FileModel extends Model @setStat(stat) if stat @setData(data) if data @set({ - extensions:[] - urls:[] + extensions: [] + urls: [] + id: @cid },{silent:true}) # Super @@ -289,24 +296,6 @@ class FileModel extends Model # Prepare encoding = 'utf8' - # Reset the file properties back to their originals - backup = @attributes - reset = balUtil.dereference balUtil.extend({},@defaults,{ - basename: backup.basename - extension: backup.extension - extensions: backup.extensions - filename: backup.filename - fullPath: backup.fullPath - outPath: backup.outPath - outDirPath: backup.outDirPath - relativePath: backup.relativePath - relativeBase: backup.relativeBase - contentType: backup.contentType - urls: [] - }) - @set(reset) - @setData(data) - # Extract content from data if data instanceof Buffer encoding = @getEncoding(data) @@ -323,6 +312,7 @@ class FileModel extends Model content = content.replace(/\r\n?/gm,'\n').replace(/\t/g,' ') # Apply + @setData(data) @set({content,encoding}) # Next @@ -332,7 +322,7 @@ class FileModel extends Model # Set the url for the file setUrl: (url) -> @addUrl(url) - @set(url: url) + @set({url}) @ # Add a url @@ -385,62 +375,63 @@ class FileModel extends Model # next(err) normalize: (opts={},next) -> # Prepare - {opts,next} = @getActionArgs(opts,next) - basename = @get('basename') or null - filename = @get('filename') or null - fullPath = @get('fullPath') or null - relativePath = @get('relativePath') or null - id = @get('id') or null - date = @get('date') or null - fullDirPath = @get('fullDirPath') or null - relativeDirPath = @get('relativeDirPath') ? '' - relativeBase = @get('relativeBase') or null - extension = @get('extension') or null - extensions = @get('extensions') or null - contentType = @get('contentType') or null + changes = {} + # Fetch + {opts,next} = @getActionArgs(opts,next) + basename = @get('basename') + filename = @get('filename') + fullPath = @get('fullPath') + extensions = @get('extensions') + relativePath = @get('relativePath') + mtime = @get('mtime') # Filename - if fullPath? - filename = pathUtil.basename(fullPath) - if filename? + if fullPath + changes.filename = filename = pathUtil.basename(fullPath) + + # Basename, extensions, extension + if filename if filename[0] is '.' basename = filename.replace(/^(\.[^\.]+)\..*$/, '$1') else basename = filename.replace(/\..*$/, '') + changes.basename = basename # Extensions if extensions? is false or extensions.length is 0 extensions = filename.split(/\./g) extensions.shift() # ignore the first result, as that is our filename + changes.extensions = extensions # determine the single extension that determine this file if extensions.length extension = extensions[extensions.length-1] else extension = null + changes.extension = extension - # Paths - if fullPath? - fullDirPath = pathUtil.dirname(fullPath) or '' - contentType = mime.lookup(fullPath) - if relativePath? - relativeDirPath = pathUtil.dirname(relativePath).replace(/^\.$/,'') or '' - relativeBase = + # fullDirPath, contentType + if fullPath + changes.fullDirPath = fullDirPath = pathUtil.dirname(fullPath) or '' + changes.contentType = contentType = mime.lookup(fullPath) + + # relativeDirPath, relativeBase + if relativePath + changes.relativeDirPath = relativeDirPath = pathUtil.dirname(relativePath).replace(/^\.$/,'') or '' + changes.relativeBase = relativeBase = if relativeDirPath pathUtil.join(relativeDirPath, basename) else basename - - # ID - id or= relativePath or fullPath or @cid + changes.id = id = relativePath # Date - if @stat? - date or= new Date(@stat.mtime) + if mtime + changes.date = date = mtime # Apply - @set({basename,filename,fullPath,relativePath,fullDirPath,relativeDirPath,id,relativeBase,extensions,extension,contentType,date}) + @set(changes) # Next next() @@ -450,36 +441,38 @@ class FileModel extends Model # Put our data into perspective of the bigger picture. For instance, generate the url for it's rendered equivalant. # next(err) contextualize: (opts={},next) -> + # Prepare + changes = {} + # Fetch {opts,next} = @getActionArgs(opts,next) + relativePath = @get('relativePath') or null relativeBase = @get('relativeBase') or null - extensions = @get('extensions') or null filename = @get('filename') or null - url = @get('url') or null - slug = @get('slug') or null - name = @get('name') or null outPath = @get('outPath') or null outDirPath = @get('outDirPath') or null - # Adjust + # Create the URL for the file + if relativePath? + url = "/#{relativePath}" + @setUrl(url) + + # Create a slug for the file if relativeBase? - if extensions? and extensions.length and filename? - if filename[0] is '.' - extensions = extensions.slice(1) - url = "/#{relativeBase}.#{extensions.join('.')}" - else - url = "/#{relativeBase}" - slug or= balUtil.generateSlugSync(relativeBase) + changes.slug = slug = balUtil.generateSlugSync(relativeBase) + + # Set name if it doesn't exist already if filename? - name or= filename - if @outDirPath? - outPath = pathUtil.join(@outDirPath,url) - outDirPath = pathUtil.dirname(outPath) if outPath - if url? - @addUrl(url) + changes.name = name = filename + + # Create the outPath if we have a outpute directory + if @outDirPath? and relativePath? + changes.outPath = outPath = pathUtil.join(@outDirPath,relativePath) + if outPath + changes.outDirPath = outDirPath = pathUtil.dirname(outPath) # Apply - @set({url,slug,name,outPath,outDirPath}) + @set(changes) # Forward next() diff --git a/src/lib/testers.coffee b/src/lib/testers.coffee index eb5234a0..8874ff62 100755 --- a/src/lib/testers.coffee +++ b/src/lib/testers.coffee @@ -11,7 +11,7 @@ CSON = require('cson') DocPad = require(__dirname+'/docpad') # Prepare -pluginPort = 1000+process.pid +pluginPort = 2000+process.pid testers = { underscore, balUtil, diff --git a/src/test/docpad.test.coffee b/src/test/docpad.test.coffee index 40019e14..db2a84c8 100755 --- a/src/test/docpad.test.coffee +++ b/src/test/docpad.test.coffee @@ -89,17 +89,27 @@ joe.suite 'docpad-core', (suite,test) -> expect(actualString).to.be.equal(expectedString) test 'same files', (done) -> - balUtil.scanlist outPath, (err,outList) -> - balUtil.scanlist outExpectedPath, (err,outExpectedList) -> - # check we have the same files - expect(_.difference(_.keys(outList),_.keys(outExpectedList))).to.be.empty - # check the contents of those files match - for own key,actual of outList - expected = outExpectedList[key] - testMarkup(key,actual,expected) - # done with same file check - # start the markup tests - done() + balUtil.scandir( + path:outPath + readFiles: true + ignoreHiddenFiles: false + next: (err,outList) -> + balUtil.scandir( + path: outExpectedPath + readFiles: true + ignoreHiddenFiles: false + next: (err,outExpectedList) -> + # check we have the same files + expect(_.difference(_.keys(outList),_.keys(outExpectedList))).to.be.empty + # check the contents of those files match + for own key,actual of outList + expected = outExpectedList[key] + testMarkup(key,actual,expected) + # done with same file check + # start the markup tests + done() + ) + ) suite 'server', (suite,test) -> diff --git a/test/out-expected/.dotdocument b/test/out-expected/.dotdocument new file mode 100644 index 00000000..5dc4cb2f --- /dev/null +++ b/test/out-expected/.dotdocument @@ -0,0 +1 @@ +this is a dot document \ No newline at end of file diff --git a/test/out-expected/.dotfile b/test/out-expected/.dotfile new file mode 100644 index 00000000..c9809e87 --- /dev/null +++ b/test/out-expected/.dotfile @@ -0,0 +1 @@ +this is a dot file \ No newline at end of file diff --git a/test/out-expected/attributes-nolayout.txt b/test/out-expected/attributes-nolayout.txt index 600ac2a9..7ae05ff6 100755 --- a/test/out-expected/attributes-nolayout.txt +++ b/test/out-expected/attributes-nolayout.txt @@ -15,7 +15,7 @@ header: 'title: \'Attributes No Layout\'\ntags: [\'attributes\',\'with-layout\']\n', id: 'attributes-nolayout.txt.coffee', isDocument: true, - meta: + meta: { title: 'Attributes No Layout', tags: [ 'attributes', 'with-layout' ] }, name: 'attributes-nolayout.txt', diff --git a/test/out-expected/attributes-withlayout.txt b/test/out-expected/attributes-withlayout.txt index e5142cfa..f83eaf9a 100755 --- a/test/out-expected/attributes-withlayout.txt +++ b/test/out-expected/attributes-withlayout.txt @@ -1,7 +1,8 @@ -
{ basename: 'attributes-withlayout', +
+{ basename: 'attributes-withlayout', body: '# Fetch data\nattrs = @getDocument().getAttributes()\n\n# Delete environment specific variables\ndelete attrs.ctime\ndelete attrs.mtime\ndelete attrs.date\ndelete attrs.fullPath\ndelete attrs.fullDirPath\ndelete attrs.outPath\ndelete attrs.outDirPath\ndelete attrs.data\n\n# Sort the attributes\nkeys = []\nkeys.push(key) for own key,value of attrs\nkeys.sort()\nsortedAttrs = {}\nfor key in keys\n sortedAttrs[key] = attrs[key]\n\n# Output data\ntext @require(\'util\').inspect(sortedAttrs)', content: '# Fetch data\nattrs = @getDocument().getAttributes()\n\n# Delete environment specific variables\ndelete attrs.ctime\ndelete attrs.mtime\ndelete attrs.date\ndelete attrs.fullPath\ndelete attrs.fullDirPath\ndelete attrs.outPath\ndelete attrs.outDirPath\ndelete attrs.data\n\n# Sort the attributes\nkeys = []\nkeys.push(key) for own key,value of attrs\nkeys.sort()\nsortedAttrs = {}\nfor key in keys\n sortedAttrs[key] = attrs[key]\n\n# Output data\ntext @require(\'util\').inspect(sortedAttrs)', - contentRendered: '
{ basename: \'attributes-withlayout\',\n body: \'# Fetch data\\nattrs = @getDocument().getAttributes()\\n\\n# Delete environment specific variables\\ndelete attrs.ctime\\ndelete attrs.mtime\\ndelete attrs.date\\ndelete attrs.fullPath\\ndelete attrs.fullDirPath\\ndelete attrs.outPath\\ndelete attrs.outDirPath\\ndelete attrs.data\\n\\n# Sort the attributes\\nkeys = []\\nkeys.push(key) for own key,value of attrs\\nkeys.sort()\\nsortedAttrs = {}\\nfor key in keys\\n sortedAttrs[key] = attrs[key]\\n\\n# Output data\\ntext @require(\\\'util\\\').inspect(sortedAttrs)\',\n content: \'# Fetch data\\nattrs = @getDocument().getAttributes()\\n\\n# Delete environment specific variables\\ndelete attrs.ctime\\ndelete attrs.mtime\\ndelete attrs.date\\ndelete attrs.fullPath\\ndelete attrs.fullDirPath\\ndelete attrs.outPath\\ndelete attrs.outDirPath\\ndelete attrs.data\\n\\n# Sort the attributes\\nkeys = []\\nkeys.push(key) for own key,value of attrs\\nkeys.sort()\\nsortedAttrs = {}\\nfor key in keys\\n sortedAttrs[key] = attrs[key]\\n\\n# Output data\\ntext @require(\\\'util\\\').inspect(sortedAttrs)\',\n contentRendered: false,\n contentRenderedWithoutLayouts: null,\n contentType: \'application/octet-stream\',\n contentTypeRendered: \'text/plain\',\n dynamic: false,\n encoding: \'utf8\',\n extension: \'coffee\',\n extensionRendered: \'txt\',\n extensions: [ \'txt\', \'coffee\' ],\n filename: \'attributes-withlayout.txt.coffee\',\n filenameRendered: \'attributes-withlayout.txt\',\n header: \'title: \\\'Attributes With Layout\\\'\\nlayout: \\\'attributes\\\'\\ntags: [\\\'attributes\\\',\\\'with-layout\\\']\\n\',\n id: \'attributes-withlayout.txt.coffee\',\n isDocument: true,\n layout: \'attributes.txt.coffee\',\n meta: \n { title: \'Attributes With Layout\',\n layout: \'attributes\',\n tags: [ \'attributes\', \'with-layout\' ] },\n name: \'attributes-withlayout.txt\',\n parser: \'yaml\',\n referencesOthers: false,\n relativeBase: \'attributes-withlayout\',\n relativeDirPath: \'\',\n relativePath: \'attributes-withlayout.txt.coffee\',\n render: true,\n renderSingleExtensions: false,\n rendered: false,\n slug: \'attributes-withlayout\',\n tags: [ \'attributes\', \'with-layout\' ],\n title: \'Attributes With Layout\',\n url: \'/attributes-withlayout.txt\',\n urls: [ \'/attributes-withlayout.txt\' ],\n write: true }
', + contentRendered: '
\n{ basename: \'attributes-withlayout\',\n body: \'# Fetch data\\nattrs = @getDocument().getAttributes()\\n\\n# Delete environment specific variables\\ndelete attrs.ctime\\ndelete attrs.mtime\\ndelete attrs.date\\ndelete attrs.fullPath\\ndelete attrs.fullDirPath\\ndelete attrs.outPath\\ndelete attrs.outDirPath\\ndelete attrs.data\\n\\n# Sort the attributes\\nkeys = []\\nkeys.push(key) for own key,value of attrs\\nkeys.sort()\\nsortedAttrs = {}\\nfor key in keys\\n sortedAttrs[key] = attrs[key]\\n\\n# Output data\\ntext @require(\\\'util\\\').inspect(sortedAttrs)\',\n content: \'# Fetch data\\nattrs = @getDocument().getAttributes()\\n\\n# Delete environment specific variables\\ndelete attrs.ctime\\ndelete attrs.mtime\\ndelete attrs.date\\ndelete attrs.fullPath\\ndelete attrs.fullDirPath\\ndelete attrs.outPath\\ndelete attrs.outDirPath\\ndelete attrs.data\\n\\n# Sort the attributes\\nkeys = []\\nkeys.push(key) for own key,value of attrs\\nkeys.sort()\\nsortedAttrs = {}\\nfor key in keys\\n sortedAttrs[key] = attrs[key]\\n\\n# Output data\\ntext @require(\\\'util\\\').inspect(sortedAttrs)\',\n contentRendered: false,\n contentRenderedWithoutLayouts: null,\n contentType: \'application/octet-stream\',\n contentTypeRendered: \'text/plain\',\n dynamic: false,\n encoding: \'utf8\',\n extension: \'coffee\',\n extensionRendered: \'txt\',\n extensions: [ \'txt\', \'coffee\' ],\n filename: \'attributes-withlayout.txt.coffee\',\n filenameRendered: \'attributes-withlayout.txt\',\n header: \'title: \\\'Attributes With Layout\\\'\\nlayout: \\\'attributes\\\'\\ntags: [\\\'attributes\\\',\\\'with-layout\\\']\\n\',\n id: \'attributes-withlayout.txt.coffee\',\n isDocument: true,\n layout: \'attributes.txt.coffee\',\n meta: \n { title: \'Attributes With Layout\',\n layout: \'attributes\',\n tags: [ \'attributes\', \'with-layout\' ] },\n name: \'attributes-withlayout.txt\',\n parser: \'yaml\',\n referencesOthers: false,\n relativeBase: \'attributes-withlayout\',\n relativeDirPath: \'\',\n relativePath: \'attributes-withlayout.txt.coffee\',\n render: true,\n renderSingleExtensions: false,\n rendered: false,\n slug: \'attributes-withlayout\',\n tags: [ \'attributes\', \'with-layout\' ],\n title: \'Attributes With Layout\',\n url: \'/attributes-withlayout.txt\',\n urls: [ \'/attributes-withlayout.txt\' ],\n write: true }
\n\n', contentRenderedWithoutLayouts: '{ basename: \'attributes-withlayout\',\n body: \'# Fetch data\\nattrs = @getDocument().getAttributes()\\n\\n# Delete environment specific variables\\ndelete attrs.ctime\\ndelete attrs.mtime\\ndelete attrs.date\\ndelete attrs.fullPath\\ndelete attrs.fullDirPath\\ndelete attrs.outPath\\ndelete attrs.outDirPath\\ndelete attrs.data\\n\\n# Sort the attributes\\nkeys = []\\nkeys.push(key) for own key,value of attrs\\nkeys.sort()\\nsortedAttrs = {}\\nfor key in keys\\n sortedAttrs[key] = attrs[key]\\n\\n# Output data\\ntext @require(\\\'util\\\').inspect(sortedAttrs)\',\n content: \'# Fetch data\\nattrs = @getDocument().getAttributes()\\n\\n# Delete environment specific variables\\ndelete attrs.ctime\\ndelete attrs.mtime\\ndelete attrs.date\\ndelete attrs.fullPath\\ndelete attrs.fullDirPath\\ndelete attrs.outPath\\ndelete attrs.outDirPath\\ndelete attrs.data\\n\\n# Sort the attributes\\nkeys = []\\nkeys.push(key) for own key,value of attrs\\nkeys.sort()\\nsortedAttrs = {}\\nfor key in keys\\n sortedAttrs[key] = attrs[key]\\n\\n# Output data\\ntext @require(\\\'util\\\').inspect(sortedAttrs)\',\n contentRendered: false,\n contentRenderedWithoutLayouts: null,\n contentType: \'application/octet-stream\',\n contentTypeRendered: \'text/plain\',\n dynamic: false,\n encoding: \'utf8\',\n extension: \'coffee\',\n extensionRendered: \'txt\',\n extensions: [ \'txt\', \'coffee\' ],\n filename: \'attributes-withlayout.txt.coffee\',\n filenameRendered: \'attributes-withlayout.txt\',\n header: \'title: \\\'Attributes With Layout\\\'\\nlayout: \\\'attributes\\\'\\ntags: [\\\'attributes\\\',\\\'with-layout\\\']\\n\',\n id: \'attributes-withlayout.txt.coffee\',\n isDocument: true,\n layout: \'attributes.txt.coffee\',\n meta: \n { title: \'Attributes With Layout\',\n layout: \'attributes\',\n tags: [ \'attributes\', \'with-layout\' ] },\n name: \'attributes-withlayout.txt\',\n parser: \'yaml\',\n referencesOthers: false,\n relativeBase: \'attributes-withlayout\',\n relativeDirPath: \'\',\n relativePath: \'attributes-withlayout.txt.coffee\',\n render: true,\n renderSingleExtensions: false,\n rendered: false,\n slug: \'attributes-withlayout\',\n tags: [ \'attributes\', \'with-layout\' ],\n title: \'Attributes With Layout\',\n url: \'/attributes-withlayout.txt\',\n urls: [ \'/attributes-withlayout.txt\' ],\n write: true }', contentType: 'application/octet-stream', contentTypeRendered: 'text/plain', @@ -16,7 +17,7 @@ id: 'attributes-withlayout.txt.coffee', isDocument: true, layout: 'attributes.txt.coffee', - meta: + meta: { title: 'Attributes With Layout', layout: 'attributes', tags: [ 'attributes', 'with-layout' ] }, @@ -34,10 +35,12 @@ title: 'Attributes With Layout', url: '/attributes-withlayout.txt', urls: [ '/attributes-withlayout.txt' ], - write: true }
+ \ No newline at end of file + write: true } diff --git a/test/package.json b/test/package.json index 48c1bbf5..478b65ea 100755 --- a/test/package.json +++ b/test/package.json @@ -5,7 +5,7 @@ "dependencies": { "moment": "1.6.x", "docpad-plugin-markdown": "latest", - "docpad-plugin-coffee": "latest", + "docpad-plugin-coffeekup": "latest", "docpad-plugin-eco": "latest" } } \ No newline at end of file diff --git a/test/src/documents/.dotdocument b/test/src/documents/.dotdocument new file mode 100644 index 00000000..5dc4cb2f --- /dev/null +++ b/test/src/documents/.dotdocument @@ -0,0 +1 @@ +this is a dot document \ No newline at end of file diff --git a/test/src/files/.dotfile b/test/src/files/.dotfile new file mode 100644 index 00000000..c9809e87 --- /dev/null +++ b/test/src/files/.dotfile @@ -0,0 +1 @@ +this is a dot file \ No newline at end of file