posts now render and save
This commit is contained in:
		
							parent
							
								
									011ff5718a
								
							
						
					
					
						commit
						3ed837c743
					
				@ -36,6 +36,7 @@
 | 
			
		||||
    "marked": "~0.3.2",
 | 
			
		||||
    "js-yaml": "~3.2.5",
 | 
			
		||||
    "path": "~3.46.1",
 | 
			
		||||
    "forEachAsync": "~5.0.2"
 | 
			
		||||
    "forEachAsync": "~5.0.5",
 | 
			
		||||
    "node-uuid": "~1.4.2"
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										272
									
								
								deardesi.js
									
									
									
									
									
								
							
							
						
						
									
										272
									
								
								deardesi.js
									
									
									
									
									
								
							@ -8,21 +8,85 @@
 | 
			
		||||
    , Mustache      = exports.Mustache      || require('mustache')
 | 
			
		||||
    , marked        = exports.marked        || require('marked')
 | 
			
		||||
    , forEachAsync  = exports.forEachAsync  || require('foreachasync').forEachAsync
 | 
			
		||||
    , sha1sum       = exports.sha1sum       || require('./lib/deardesi-node').sha1sum
 | 
			
		||||
    //, sha1sum       = exports.sha1sum       || require('./lib/deardesi-node').sha1sum
 | 
			
		||||
    , frontmatter   = exports.Frontmatter   || require('./lib/frontmatter').Frontmatter
 | 
			
		||||
    , safeResolve   = exports.safeResolve   || require('./lib/deardesi-utils').safeResolve
 | 
			
		||||
    //, safeResolve   = exports.safeResolve   || require('./lib/deardesi-utils').safeResolve
 | 
			
		||||
    , fsapi         = exports.fsapi         || require('./lib/deardesi-node').fsapi
 | 
			
		||||
    //, UUID          = exports.uuid          || require('node-uuid')
 | 
			
		||||
    ;
 | 
			
		||||
 | 
			
		||||
  function runDesi(desi) {
 | 
			
		||||
    var config = desi.config
 | 
			
		||||
      , cache = desi.cache
 | 
			
		||||
  // See https://github.com/janl/mustache.js/issues/415
 | 
			
		||||
  function num2str(obj) {
 | 
			
		||||
    return JSON.parse(JSON.stringify(obj, function (key, val) {
 | 
			
		||||
      if ('number' === typeof val) {
 | 
			
		||||
        val = val.toString();
 | 
			
		||||
      }
 | 
			
		||||
      return val;
 | 
			
		||||
    }));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function getLayout(desi, themename, layout, arr) {
 | 
			
		||||
    arr = arr || [];
 | 
			
		||||
 | 
			
		||||
    var layoutdir = 'layouts'
 | 
			
		||||
      , themepath
 | 
			
		||||
      , file
 | 
			
		||||
      ;
 | 
			
		||||
 | 
			
		||||
    if (!themename) {
 | 
			
		||||
      themename = desi.config.themes.default;
 | 
			
		||||
    }
 | 
			
		||||
    if (!layout) {
 | 
			
		||||
      layout = 'post.html';
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    themepath = themename + '/' + layoutdir + '/' + layout;
 | 
			
		||||
 | 
			
		||||
    desi.content.themes.some(function (theme) {
 | 
			
		||||
      // TODO what if it isn't html?
 | 
			
		||||
      if (theme.path === themepath || theme.path.match(themepath + '\\.html')) {
 | 
			
		||||
        file = theme;
 | 
			
		||||
        arr.push(theme);
 | 
			
		||||
        return true;
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    if (!file) {
 | 
			
		||||
      console.error("could not find " + themepath);
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // TODO handle possible circular dep condition page -> post -> page
 | 
			
		||||
    console.info(file);
 | 
			
		||||
    if (file.yml && file.yml.layout) {
 | 
			
		||||
      return getLayout(desi, themename, file.yml.layout, arr);
 | 
			
		||||
    } else {
 | 
			
		||||
      // return the chain page -> posts -> default -> twitter
 | 
			
		||||
      return arr;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function runDesi(desi, development) {
 | 
			
		||||
    var cache = desi.cache
 | 
			
		||||
      //, config = desi.config
 | 
			
		||||
      , cacheByPath = {}
 | 
			
		||||
      , cacheBySha1 = {}
 | 
			
		||||
      , dfiles
 | 
			
		||||
      , dthemes
 | 
			
		||||
      ;
 | 
			
		||||
 | 
			
		||||
    desi.urls = desi.config.urls = {};
 | 
			
		||||
    if (development) {
 | 
			
		||||
      desi.urls.base_path = desi.config.development.base_path;
 | 
			
		||||
      desi.urls.url = desi.config.development.url;
 | 
			
		||||
      desi.urls.development_url = desi.config.development.url;
 | 
			
		||||
    } else {
 | 
			
		||||
      desi.config.base_path = desi.urls.base_path = desi.config.production.base_path;
 | 
			
		||||
      desi.urls.url = desi.config.production.url;
 | 
			
		||||
      desi.urls.production_url = desi.config.production.url;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    cache.sources = cache.sources || [];
 | 
			
		||||
    cache.sources.forEach(function (source) {
 | 
			
		||||
      cacheByPath[source.path] = source;
 | 
			
		||||
@ -103,37 +167,40 @@
 | 
			
		||||
 | 
			
		||||
  console.log('');
 | 
			
		||||
  console.log('');
 | 
			
		||||
  console.log('getting config...');
 | 
			
		||||
  return fsapi.getConfig().then(function (config) {
 | 
			
		||||
    console.log('loading caches...');
 | 
			
		||||
    return fsapi.getCache().then(function (cache) {
 | 
			
		||||
      console.log('cache');
 | 
			
		||||
      console.log(cache);
 | 
			
		||||
      console.log('last update: ' + (cache.lastUpdate && new Date(cache.lastUpdate) || 'never'));
 | 
			
		||||
      var collectionnames = Object.keys(config.collections)
 | 
			
		||||
  console.log('getting config, data, caches...');
 | 
			
		||||
  return PromiseA.all([fsapi.getConfig(), fsapi.getData(), fsapi.getCache(), fsapi.getPartials()]).then(function (things) {
 | 
			
		||||
    var config = things[0]
 | 
			
		||||
      , data = things[1]
 | 
			
		||||
      , cache = things[2]
 | 
			
		||||
      , partials = things[3]
 | 
			
		||||
      ;
 | 
			
		||||
 | 
			
		||||
    console.log('loaded config, data, caches.');
 | 
			
		||||
    console.log(things);
 | 
			
		||||
    console.log('last update: ' + (cache.lastUpdate && new Date(cache.lastUpdate) || 'never'));
 | 
			
		||||
    var collectionnames = Object.keys(config.collections)
 | 
			
		||||
      ;
 | 
			
		||||
 | 
			
		||||
    return fsapi.getMeta(
 | 
			
		||||
      collectionnames
 | 
			
		||||
    , { dotfiles: false
 | 
			
		||||
      , extensions: ['md', 'markdown', 'htm', 'html', 'jade']
 | 
			
		||||
      }
 | 
			
		||||
    ).then(function (collections) {
 | 
			
		||||
      var themenames = Object.keys(config.themes).filter(function (k) { return 'default' !== k; })
 | 
			
		||||
        ;
 | 
			
		||||
 | 
			
		||||
      console.log('collections');
 | 
			
		||||
      console.log(collections);
 | 
			
		||||
      return fsapi.getMeta(
 | 
			
		||||
        collectionnames
 | 
			
		||||
      , { dotfiles: false
 | 
			
		||||
        , extensions: ['md', 'markdown', 'htm', 'html', 'jade']
 | 
			
		||||
        themenames
 | 
			
		||||
      , { dotfiles: false 
 | 
			
		||||
        , extensions: ['md', 'markdown', 'htm', 'html', 'jade', 'css', 'js', 'yml']
 | 
			
		||||
        }
 | 
			
		||||
      ).then(function (collections) {
 | 
			
		||||
        var themenames = Object.keys(config.themes).filter(function (k) { return 'default' !== k; })
 | 
			
		||||
          ;
 | 
			
		||||
 | 
			
		||||
        console.log('collections');
 | 
			
		||||
        console.log(collections);
 | 
			
		||||
        return fsapi.getMeta(
 | 
			
		||||
          themenames
 | 
			
		||||
        , { dotfiles: false 
 | 
			
		||||
          , extensions: ['md', 'markdown', 'htm', 'html', 'jade', 'css', 'js', 'yml']
 | 
			
		||||
          }
 | 
			
		||||
        ).then(function (themes) {
 | 
			
		||||
          console.log('themes');
 | 
			
		||||
          console.log(themes);
 | 
			
		||||
          return { config: config, cache: cache, meta: { collections: collections, themes: themes } };
 | 
			
		||||
        });
 | 
			
		||||
      ).then(function (themes) {
 | 
			
		||||
        console.log('themes');
 | 
			
		||||
        console.log(themes);
 | 
			
		||||
        return { config: config, data: data, cache: cache, meta: { collections: collections, themes: themes }, partials: partials };
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
  }).then(runDesi).then(function (desi) {
 | 
			
		||||
@ -168,48 +235,33 @@
 | 
			
		||||
        return desi;
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
  }).then(function (desi) {
 | 
			
		||||
    function getLayout(themename, layout, arr) {
 | 
			
		||||
      arr = arr || [];
 | 
			
		||||
 | 
			
		||||
      var layoutdir = 'layouts'
 | 
			
		||||
        , themepath
 | 
			
		||||
        , file
 | 
			
		||||
        ;
 | 
			
		||||
 | 
			
		||||
      if (!themename) {
 | 
			
		||||
        themename = desi.config.themes.default;
 | 
			
		||||
      }
 | 
			
		||||
      if (!layout) {
 | 
			
		||||
        layout = 'post.html';
 | 
			
		||||
    // TODO add missing metadata and resave file
 | 
			
		||||
    desi.content.collections.forEach(function (article) {
 | 
			
		||||
      if (!article.yml.permalink) {
 | 
			
		||||
        // TODO read the config for this collection
 | 
			
		||||
        article.yml.permalink = path.join(desi.urls.base_path, article.title);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
      themepath = themename + '/' + layoutdir + '/' + layout;
 | 
			
		||||
 | 
			
		||||
      desi.content.themes.some(function (theme) {
 | 
			
		||||
        // TODO what if it isn't html?
 | 
			
		||||
        if (theme.path === themepath || theme.path.match(themepath + '\\.html')) {
 | 
			
		||||
          file = theme;
 | 
			
		||||
          arr.push(theme);
 | 
			
		||||
          return true;
 | 
			
		||||
        }
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      if (!file) {
 | 
			
		||||
        console.error("could not find " + themepath);
 | 
			
		||||
        return;
 | 
			
		||||
      if (!article.yml.uuid) {
 | 
			
		||||
        // TODO only do this if it's going to be saved
 | 
			
		||||
        // article.yml.uuid = UUID.v4();
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // TODO handle possible circular dep condition page -> post -> page
 | 
			
		||||
      console.info(file);
 | 
			
		||||
      if (file.yml && file.yml.layout) {
 | 
			
		||||
        return getLayout(themename, file.yml.layout, arr);
 | 
			
		||||
      } else {
 | 
			
		||||
        // return the chain page -> posts -> default -> twitter
 | 
			
		||||
        return arr;
 | 
			
		||||
      if (!article.yml.date) {
 | 
			
		||||
        article.yml.date = article.createdDate || article.lastModifiedDate;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
      if (!article.yml.updated_at) {
 | 
			
		||||
        article.yml.updated_at = article.lastModifiedDate;
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    return desi;
 | 
			
		||||
  }).then(function (desi) {
 | 
			
		||||
    var compiled = []
 | 
			
		||||
      ;
 | 
			
		||||
 | 
			
		||||
    desi.content.collections.forEach(function (article) {
 | 
			
		||||
      // TODO process tags and categories and such
 | 
			
		||||
@ -221,19 +273,43 @@
 | 
			
		||||
 | 
			
		||||
      var child = ''
 | 
			
		||||
        , layers
 | 
			
		||||
        , view
 | 
			
		||||
        ;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
      console.log(article.path || (article.relativePath + '/' + article.name));
 | 
			
		||||
      //console.log(article.frontmatter);
 | 
			
		||||
      console.log(article.yml);
 | 
			
		||||
      layers = getLayout(article.yml.theme, article.yml.layout, [article]);
 | 
			
		||||
      layers = getLayout(desi, article.yml.theme, article.yml.layout, [article]);
 | 
			
		||||
      console.log('LAYERS');
 | 
			
		||||
      console.log(layers);
 | 
			
		||||
 | 
			
		||||
      view = {
 | 
			
		||||
        page: article.yml // data for just *this* page
 | 
			
		||||
      , content: child    // processed content for just *this* page
 | 
			
		||||
      //, data: desi.data   // data.yml
 | 
			
		||||
      // https://github.com/janl/mustache.js/issues/415
 | 
			
		||||
      , data: num2str(desi.data)
 | 
			
		||||
      , collection: {}    // data for just *this* collection
 | 
			
		||||
      , categories: []    // *all* categories in all collections
 | 
			
		||||
      , tags: []          // *all* tags in all collections
 | 
			
		||||
      , site: num2str(desi.site || {})
 | 
			
		||||
      , url: path.join(desi.urls.url, desi.urls.base_path, article.yml.permalink)
 | 
			
		||||
      , canonical_url: path.join(desi.urls.url, desi.urls.base_path, article.yml.permalink)
 | 
			
		||||
      , relative_url: path.join(desi.urls.base_path, article.yml.permalink)
 | 
			
		||||
      , urls: desi.urls
 | 
			
		||||
      };
 | 
			
		||||
      view.site.author = desi.data.author;
 | 
			
		||||
      view.site['navigation?to_pages'] = desi.data.navigation.map(function (nav) {
 | 
			
		||||
        var title = nav.replace(/^./, function ($1) { return $1.toUpperCase(); })
 | 
			
		||||
          ;
 | 
			
		||||
 | 
			
		||||
        return { path: '/' + nav, active: false, title: /*TODO*/ title };
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      layers.forEach(function (parent) {
 | 
			
		||||
        // TODO meta.layout
 | 
			
		||||
        var view
 | 
			
		||||
          , body = (parent.body || parent.contents || '').trim()
 | 
			
		||||
        var body = (parent.body || parent.contents || '').trim()
 | 
			
		||||
          , html
 | 
			
		||||
          ;
 | 
			
		||||
 | 
			
		||||
@ -249,24 +325,52 @@
 | 
			
		||||
          console.error('unknown parser for ' + (article.path));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        view = {
 | 
			
		||||
          page: article.yml // data for just *this* page
 | 
			
		||||
        , content: child    // processed content for just *this* page
 | 
			
		||||
        , data: {}          // data.yml
 | 
			
		||||
        , collection: {}    // data for just *this* collection
 | 
			
		||||
        , categories: []    // *all* categories in all collections
 | 
			
		||||
        , tags: []          // *all* tags in all collections
 | 
			
		||||
        };
 | 
			
		||||
        view.content = child;
 | 
			
		||||
 | 
			
		||||
        child = Mustache.render(html, view, desi.partials);
 | 
			
		||||
 | 
			
		||||
        child = Mustache.render(html, view);
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      console.log('child');
 | 
			
		||||
      console.log(child);
 | 
			
		||||
      //console.log(meta.mtime.valueOf(), meta.ymlsum, meta.textsum, node);
 | 
			
		||||
      console.warn('view data.author contains objects?');
 | 
			
		||||
      console.warn(JSON.stringify(view.data.author, null, '  '));
 | 
			
		||||
      console.warn(typeof view.data.author.twitter_id);
 | 
			
		||||
      console.warn(view.data.author);
 | 
			
		||||
      // TODO add html meta-refresh redirects
 | 
			
		||||
      compiled.push({ contents: child, path: path.join(desi.config.compiled_path, article.yml.permalink) });
 | 
			
		||||
      if (Array.isArray(article.yml.redirects)) {
 | 
			
		||||
        child = 
 | 
			
		||||
          '<html>'
 | 
			
		||||
            + '<head>'
 | 
			
		||||
              + '<title>Redirecting to ' + article.yml.title + '</title>'
 | 
			
		||||
              + '<meta http-equiv="refresh" content="0;URL=\'' + path.join(desi.urls.url, article.yml.permalink) + '\'" />'
 | 
			
		||||
            + '</head>'
 | 
			
		||||
            + '<body>'
 | 
			
		||||
              + '<p>This page has moved to a <a href="' + path.join(desi.urls.url, article.yml.permalink) +'">' + article.yml.title + '</a>.</p>'
 | 
			
		||||
            + '</body>'
 | 
			
		||||
        + '</html>'
 | 
			
		||||
        ;
 | 
			
		||||
 | 
			
		||||
        compiled.push({ contents: child, url: view.url, path: path.join(desi.config.compiled, article.yml.permalink) });
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    desi.compiled = compiled;
 | 
			
		||||
    return desi;
 | 
			
		||||
  }).then(function (desi) {
 | 
			
		||||
    var compiled = desi.compiled
 | 
			
		||||
      ;
 | 
			
		||||
 | 
			
		||||
    console.info('das compiled files');
 | 
			
		||||
    console.info(compiled);
 | 
			
		||||
    return fsapi.putFiles(compiled).then(function (saved) {
 | 
			
		||||
      console.info('files saved');
 | 
			
		||||
      console.info(saved);
 | 
			
		||||
    });
 | 
			
		||||
  }).catch(function (e) {
 | 
			
		||||
    console.error('The Badness is upon us...');
 | 
			
		||||
    console.error('A great and uncatchable error has befallen the land. Read ye here for das detalles..');
 | 
			
		||||
    console.error(e.message);
 | 
			
		||||
    throw e;
 | 
			
		||||
  });
 | 
			
		||||
}('undefined' !== typeof exports && exports || window));
 | 
			
		||||
 | 
			
		||||
@ -8,6 +8,7 @@
 | 
			
		||||
    <script src="./bower_components/marked/lib/marked.js"></script>
 | 
			
		||||
    <script src="./bower_components/js-yaml/dist/js-yaml.js"></script>
 | 
			
		||||
    <script src="./bower_components/path/path.js"></script>
 | 
			
		||||
    <script src="./bower_components/node-uuid/uuid.js"></script>
 | 
			
		||||
    <script src="./bower_components/forEachAsync/forEachAsync.js"></script>
 | 
			
		||||
 | 
			
		||||
    <!-- Libs -->
 | 
			
		||||
 | 
			
		||||
@ -216,8 +216,12 @@
 | 
			
		||||
 | 
			
		||||
  fsapi.getConfig = function () {
 | 
			
		||||
    return request.get('/config.yml').then(function (resp) {
 | 
			
		||||
      console.log('config');
 | 
			
		||||
      console.log(exports.YAML.parse(resp));
 | 
			
		||||
      return exports.YAML.parse(resp);
 | 
			
		||||
    });
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  fsapi.getData = function () {
 | 
			
		||||
    return request.get('/data.yml').then(function (resp) {
 | 
			
		||||
      return exports.YAML.parse(resp);
 | 
			
		||||
    });
 | 
			
		||||
  };
 | 
			
		||||
@ -230,8 +234,19 @@
 | 
			
		||||
    });
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  fsapi.getPartials = function () {
 | 
			
		||||
    return request.get('/partials.yml').then(function (resp) {
 | 
			
		||||
      var partials = exports.YAML.parse(resp)
 | 
			
		||||
        ;
 | 
			
		||||
 | 
			
		||||
      console.info('partials');
 | 
			
		||||
      console.info(partials);
 | 
			
		||||
      return partials;
 | 
			
		||||
    });
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  fsapi.putFiles = function (files) {
 | 
			
		||||
    return request.put('/api/fs/files', {
 | 
			
		||||
    return request.post('/api/fs/files', {
 | 
			
		||||
      files: files
 | 
			
		||||
    }).then(function (resp) {
 | 
			
		||||
      return JSON.parse(resp);
 | 
			
		||||
 | 
			
		||||
@ -42,6 +42,7 @@
 | 
			
		||||
    "marked": "^0.3.2",
 | 
			
		||||
    "mkdirp": "^0.5.0",
 | 
			
		||||
    "mustache": "^1.0.0",
 | 
			
		||||
    "node-uuid": "^1.4.2",
 | 
			
		||||
    "require-yaml": "0.0.1",
 | 
			
		||||
    "require-yamljs": "^1.0.1",
 | 
			
		||||
    "secret-utils": "^1.0.2",
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user