2

I've been setting up a site with Wintersmith and am loving it for the most part, but I cannot wrap my head around some of the under-the-hood mechanics. I started with the "blog" skeleton that adds the paginator.coffee plugin.

The question requires some details, so up top, what I'm trying to accomplish:

  1. Any files (markdown, html, json metadata) will be picked up either in /contents/article/<file> or /contents/articles/<subdir>/<file>
  2. Output files are at /articles/YYYY/MM/DD/title-slug/
  3. /blog.html lists all articles, paginated.
  4. Files just under /contents (not in articles) are not treated as blog posts. Markdown and JSON metadata are still processed, but no permalinked URLs, not included in blog listings, file/directory structure is more directly copied over.

So, I solved #1 with this suggestion: How can I have articles in Wintersmith not in their own subdirectory? So far, great, and #3 is working -- the paginated listing includes all posts. #4 has not been an issue, it's the default behavior.

On #2 I found this solution: http://andrewphilipclark.com/2013/11/08/removing-the-boilerplate-from-wintersmith-blog-posts/ . As the author mentions, his solution was (sort of) subsequently incorporated into Wintersmith master, so I tried just setting the filenameTemplate accordingly. Unfortunately this applies to all content, not just that under /articles, so the rest of my site gets hosed (breaks #4). So then I tried the author's approach, adding a blogpost.coffee plugin using his code. This generates all the files out of /contents/articles into the correct permalink URLs, however the paginator now for some reason will no longer see files directly under /articles (point #1).

I've tried a lot of permutations and hacking. Tried changing the order of which plugin gets loaded first. Tried having PaginatorPage extend BlogpostPage instead of Page. Tried a lot of things. I finally realize, even after inspecting many of the core classes in Wintersmith source, that I do not understand what is happening.

Specifically, I cannot figure out how contents['articles']._.pages and .directories are set, which seems relevant. Nor do I understand what that underscore is.

Ultimately, Jade/CoffeeScript/Markdown are a great combo for minimizing coding and enhancing clarity except when you want to understand what's happening under the hood and you don't know these languages. It took me a bit to get the basics of Jade and CoffeeScript (Markdown is trivial of course) enough to follow what's happening. When I've had to dig into the wintersmith source, it gets deeper. I confess I'm also a node.js newbie, but I think the big issue here is just a magic framework. It would be helpful, for instance, if some of the core "plugins" were included in the skeleton site as opposed to buried in node_modules, just so curious hackers could see more quickly how things interconnect. More verbose docs would of course be helpful too. It's one thing to understand conceptually content trees, generators, views, templates, etc., but understanding the code flow and relations at runtime? I'm lost.

Any help is appreciated. As I said, I'm loving Wintersmith, just wish I could dispel magic.

Community
  • 1
  • 1
Jason Boyd
  • 1,192
  • 1
  • 9
  • 19

1 Answers1

2

Because coffee script is rubbish, this is extremely hard to do. However, if you want to, you can destroy the paginator.coffee and replace it with a simple javascript script that does a similar thing:

module.exports = function (env, callback) {

  function Page() {
    var rtn = new env.plugins.Page();

    rtn.getFilename = function() {
      return 'index.html';
    },

    rtn.getView = function() {
      return function(env, locals, contents, templates, callback) {
        var error = null;
        var context = {};
        env.utils.extend(context, locals);
        var buffer = new Buffer(templates['index.jade'].fn(context));
        callback(error, buffer);
      };
    };
    return rtn;
  };

  /** Generates a custom index page */
  function gen(contents, callback) {
    var p = Page();
    var pages = {'index.page': p};
    var error = null;
    callback(error, pages);
  };

  env.registerGenerator('magic', gen);
  callback();
};

Notice that due to 'coffee script magic', there are a number of hoops to jump through here, such as making sure you return a buffer from getView(), and 'manually' overriding rather than using the obscure coffee script extension semantics.

Wintersmith is extremely picky about how it handles these functions. If callbacks are not invoked, for the returned value is not a Stream or Buffer, generated files will appear in the content summary, but not be rendered to disk during a build. Enable verbose logging and check of 'skipping foo' messages to detect this.

Doug
  • 32,844
  • 38
  • 166
  • 222
  • Good tips, thanks. Since I've yet to ever sit down and "learn" coffee script, just curious -- why do you say it's rubbish? Too much magic, sounds like? – Jason Boyd Jan 06 '15 at 12:29