Git Product home page Git Product logo

blacksmith's Introduction

blacksmith

A generic static site generator built using flatiron, plates, and marked.

Creating a site with blacksmith

Blacksmith sites have a specific directory structure for storing the various parts of your site: settings, layout, partials, pages, and content. Content exists in two forms:

  • Markdown files that blacksmith will render.
  • Supporting content such as css and images.

All content will be rendered into /public. To render a blacksmith site:

Install Blacksmith

  $ npm install blacksmith -g

Render a Site

  #
  # Defaults to `cwd`
  #
  $ blacksmith /path/to/your/site

Here's an example of a simple blog that blacksmith would render.

/site-name
  #
  # Settings for this blacksmith site.
  #
  .blacksmith
  /content
    #
    # Actual Markdown content to render.
    #
    /posts
      a-post.md
      another-post.md
  /layouts
    #
    # Layouts to use for pages. You can specify 
    # multiple layouts, but default.html is ... the default.
    #
    default.html
  /metadata
    #
    # Metadata entities which can be reference in content metdata
    #
    /authors
      author-name.json
  /partials
    #
    # HTML for partials inside of pages
    #
    post.html
    sidebar.html
  /pages
    #
    # Metadata for rendering specific pages
    #
    index.json
    post.json
  /public
    #
    # Any additional files for viewing the site. All
    # rendered HTML will be placed here. e.g.:
    #
    /css
      styles.css
    /img
      favicon.png

Components of a blacksmith site

Each blacksmith site defines a hierarchical set of components which can be composed to create any type of site you want! A couple of examples:

  • A Blog
  • A Documentation Site
  • A Custom Splash Page or Content Site

Lets examine each of these components and where they are stored in your filesystem:

Site Settings

The settings for a given blacksmith site are stored in the .blacksmith file located in the root directory of your site.

  {
    //
    // Default Layout. Specifying a name here will cause Blacksmith to attempt to read
    // /layouts/layout-name.json for rendering info. If no layout-name.json file is found
    // blacksmith will use `/layouts/layout-name.html`
    //
    // Default: default
    //
    "layout": "layout-name",
    "pages": {
      //
      // These settings will be used for all content in
      // /content/posts
      //
      "post": {
        "layout": "custom-layout-for-posts",
        "partials": {
          "html-id": "additional-partials",
          "another-id": "for-this-page-only"
        }
      }
    }
  }

You can define settings for all components of your site in the .blacksmith file or break them out into individual files within component directories. For example, the above example is equivalent to:

/.blacksmith

  {
    "layout": "layout-name"
  }

/pages/post.json

 {
  "layout": "custom-layout-for-posts",
  "partials": {
    "html-id": "additional-partials",
    "another-id": "for-this-page-only"
  }
}

Layouts

Layouts are fully-formed HTML files; they are the top of the rendering hierarchy. All content will be inserted into a layout inside of the HTML element with the id="content". Lets look at the worlds simplest layout:

  <html>
  <head>
  	<title>Simple Layout</title>
  	<link rel="stylesheet" href="css/styles.css">
  </head>
  <body>
    <div id="content">
      <!-- All rendered content place here-->
    </div>
  </body>
  </html>  

Settings for a layout may be specified in your .blacksmith file or in /layouts/layout-name.json. Lets look at an example:

/layouts/layout-name.json NOTE: These properties are not yet supported. See Roadmap for more details.

  {
    //
    // The "template" property specifies which HTML file within the /layouts directory
    // to use when rendering this layout. In this way a single HTML file can be reused with 
    // different partials.
    //
    // If no template is specified then blacksmith will look for /layouts/layout-name.html
    // when rendering.
    //
    "template": "shared-layout.html",
    //
    // The "partials" property specifies which HTML partial (or partials) to insert at a given
    // id within the layout. These partials will be rendered with the metadata for a given
    // individual page with content.
    //
    "partials": {
      "sidebar-container": "sidebar",
      //
      // Multiple partials can be concatentated into a single HTML id.
      //
      "multi-container": ["partial1", "partial2"]
    }
  }

Pages

Pages allows you to specify what type of content you wish to render and where to render it within a given layout. As with layouts, pages may be specified in your .blacksmith file or in /pages/page-name.json. Lets look at two examples from our blog:

/pages/index.json

The above example demonstrates particular interest: index.json will always be used to render index.html. The following example specifies that blacksmith should render a list of post content, which should be truncated and limited to a maximum of 20 posts. Note: All lists are sorted descending by the date the content was created.

  {
    //
    // The "content" property specifies what blacksmith should render
    // inside the HTML element with id="content"
    //
    "content": {
      "list": "post",
      "truncate": true,
      "limit": 20
    }
  }

/pages/post.json

The rendering information for an individual post is much simpler than our index.json. By creating this file, blacksmith will:

  1. Render all Markdown files in /content/posts using the partial found at /partials/post.html.
  2. Render the partial found at /partials/sidebar.html with the metadata for each Markdown file in /content/posts and append it to the HTML element with id="content"
  {
    "partials": {
      "content": "sidebar"
    }
  }

It is important to take note of the convention:

  Convention: By default, page content will be rendered in a partial of the same name. 

Alternatively we could have specified an explicit partial to use. If no partial is specified and the default partial is not found then no metadata would be rendered (in this case author name, date of post, etc).

All Page Options

A list of all available options that can be specified in a page.json file are listed below:

  {
    //
    // Specifies the layout for the page. 
    // Default: Layout for the site.
    //
    "layout": "custom-layout-for-page",
    
    //
    // Specifies a mapping of HTML ids to partial(s). If "content" is specified
    // then it is appended after the rendered markdown content.
    //
    "partials": {
      "html-id": "partial-name",
      "another-id": ["multiple-partials"]
    },
    
    //
    // Case 1: Rendering content with a partial
    //
    "content": "custom-partial"
    
    //
    // Case 2: Consolidating multiple content sources in a list.
    //
    "content": {
      "list": "post",
      "truncate": true,
      "limit": 20
    }
  }

Content

In blacksmith, "content" is raw Markdown and supporting files (e.g. images) located within the /content directory. Content for individual pages should be placed under /content/page-name.

In our example all content for the post page should be placed under /content/posts. It is important to take note of the convention:

  Convention: Page names are always singular, but their content folder will always be plural.

The content for an individual page may also be a directory where supporting files (such as images can be placed). For example if we wanted to create a post with images, the directory structure would be:

/site-name
  /content
    /posts
      /post-with-supporting-files
        content.md
        an-image.png
        another-image.png
        some-code.js

The directory structure will be respected, but the /content prefix will be dropped. So the full-url for an-image.png would be http://your-site.com/post-with-supporting-files/an-image.png.

Specifying Metadata

All metadata associated with content is stored within the individual Markdown files as link definitions prefixed with 'meta:'. Because of a small limitation in the Markdown format you must use the following syntax to specify metadata:

  [meta:author] <> (Author Name)
  [meta:title] <> (A Really Long Title Different from the Filename)
  [meta:nested:values] <> (Are also supported)

Content Snippets

In large content pages it is often useful to have examples or references to other files to be inserted later in rendering. A classic example is code samples in a blog post. This is easy in blacksmith using Content Snippets. Consider the content:

  /content
    /dir-post
      index.md
      whatever.js
  This is a piece of markdown content to be rendered later. It has a reference to the file "whatever.js"
  
  <whatever.js>

In this example <whatever.js> in index.md would be replaced with the contents of /content/dir-post/whatever.js. Note: Only files with text extensions (.js, .rb, .txt, etc) less than 1MB will be inserted.

Code Highlighting

Because blacksmith uses marked we get the benefit of Github Flavored Markdown through highlight.js. By default code highlighting is enabled. All you need to do is add some CSS for your site. For example:

  pre {
    border: 1px solid #e0ded3;
    border-radius: 4px;
    margin: 10px 10px 40px 10px;
    padding: 10px;
    background-color: #f0efe8;
    overflow: auto;
    font-size: 14px;
    font-family: Consolas, "Liberation Mono", Courier, monospace;
  }

  code {
    white-space: pre;
    color: rgba(0,0,0, 1);
  }

  code .keyword              { font-weight: bold; color: #6089d4; }
  code .string, code .regexp { color: green }
  code .class, code .special { color: #6089d4 }
  code .number               { color: red }
  code .comment              { color: grey }

Truncated Content

It is necessary to truncate large content pages when rendering them within compilations (i.e. lists). This is supported by blacksmith with a special identifier in your Markdown files. For example:

/content/posts/dir-post/index.markdown

  A simple post that is truncated with content snippets and metadata that is not used in the post.

  ##!!truncate

  <file1.js>
  A second file reference with spaces
  < file2.js  >

  [meta:author]: <> (Charlie index)

When rendered in a page like index.json with { truncate: true } only the content above ##!!truncate will be rendered.

Partials

Partials are HTML fragments which are inserted into a layout, a page, or another partial. All partials are rendered with plates.

Default Metadata

  {
    "page-details": {
      "author": {
        //
        // Contents of /metdata/authors/author-name.json
        //
      },
      "href": "/full/path/to/page",
      "date": "Fully qualified date page was published",
      "files": {
        "js": [{ "filename": "file1.js", "url": "/full/path/to/file1.js" }],
        "img": [{ "filename": "img1.png", "url": "/full/path/to/img1.png" }]
      }
    }
  }

Customizing Partials

All metadata is placed into partials using a set of simple plates conventions. In the future it may be possible to customize these conventions but that is not currently planned.

  • Map URL-like string keys to href="keyname": map.where('href').is(key).use(key).as('href');
  • Insert "content" into class="content": map.class('content').use('content').as('value');
  • Map string keys to class="keyname": map.class(key).use(key)
  • Map everything else to class="keyname": map.class(key).use(key);
  • Recursively map Array keys: exports.map(metadata[key][0], map);
  • Recursively map Object keys: exports.map(metadata[key], map);

Conditional Metadata

Some content should only exist in partials when a given key is present in the metadata. This is supported by blacksmith in the following way: The keys in remove must be specified at the fully qualified path into an Object.

/partials/partial-name.json

  {
    "remove": {
      "page-details": {
        "author": ["github", "twitter"]
      }
    }
  }

In the corresponding HTML file for the partial any elements with "class=if-[keyname]" will be removed if there is no value for keyname. In the above example using the following template:

/partials/partial-name.html

  <div class="page-details">
    <div class="author">
      <h3>About the author</h3>
      <div class="name">Author Name</div>
      <div class="if-github">
        <a href="github-url" class="github">Author Github</a>
      </div>
      <div class="if-twitter">
        <a href="twitter-url" class="twitter">Author Twitter</a>  
      </div>
    </div>
  </div>

and this set of metadata:

  {
    "page-details": {
      "author": {
        "name": "Charlie Robbins",
        "github": "indexzero",
        "github-url": "https://github.com/indexzero"
      }
    }
  }

The output would be the following. Notice how everything inside if-twitter has been removed.

  <div class="page-details">
    <div class="author">
      <h3>About the author</h3>
      <div class="name">Charlie Robbins</div>
      <div class="if-github">
        <a href="https://github.com/indexzero" class="github">indexzero</a>
      </div>
    </div>
  </div>

Metadata References

It is useful when writing a content page to use a key to reference a larger section of metadata stored elsewhere. These other sections of metadata are called metadata references and are loaded by blacksmith from /metadata. For example:

/metdata/dogs/sparky-mcpherson.json

  {
    "name": "sparky-mcpherson",
    "breed": "labridoodle",
    "color": "brown",
    "age": "3",
    "temperment": "friendly"
  }

/content/posts/a-post.md

  (... Rest of Content ...)  
  [meta:dog] <> (Sparky McPherson)

When the content for this page finally gets rendered to a partial the metadata will not be { 'dog': 'sparky' }, it will be the entire object stored in /metadata/dogs/sparky.json. By convention:

  Convention: For a given `key:value` blacksmith will lookup metadata references for the `value`
  in the directory named with the plural of that `key`. 

In the above example the key:value pair is dog:Sparky Mcpherson so we attempt to lookup sparky-mcpherson within /metadata/dogs/sparky-mcpherson.json.

Note: "Authors" is a special metadata reference which will always be within the metadata.page-details.

How does blacksmith render my Site?

It's safe to skip this if you're not tinkering with blacksmith internals.

Rendering Process

In order to render list pages with all options supported by blacksmith it is necessary to perform multiple rendering passes on a given site to fully render it. Lets examine that process start to finish:

  • 1. Rendering starts

Rendering starts when blacksmith('/full/path/to/your/site', function () { ... }) is invoked. This tells blacksmith where the root directory for a given site is.

  • 2. Load all HTML and rendering settings

Inside Site.prototype.load will load all HTML and rendering settings stored in:

  • .blacksmith
  • /layouts/*.json || *.html
  • /pages/*.json
  • /partials/*.html

We need to load all of these files before any rendering can begin because they store the necessary settings for rendering.

  • 3. Read everything under /content

Before layout, page, and partial rendering can take place all content (i.e. Markdown and supporting files) must be known to blacksmith. In our example how can we render the page represented by /pages/index.json without all rendered content? Site.prototype.readContent recursively reads /content building this data structure:

/content
  /posts
    a-post.md
    another-post.md
    /dir-post
      file1.js
      file2.js
      index.markdown
{
  posts: {
    "a-post": { _content: { html: "..", markdown: "..", metadata: { ... } } },
    "another-post": { _content: { html: "..", markdown: "..", metadata: { ... } } }
    "dir-post": {
      _content: {
        html: "HTML rendered from Markdown", 
        markdown: "Markdown in index.markdown",
        metadata: {
          "page-details": {
            source: "/dir-post/index.markdown",
            title: "Title of page in metadata" || "href of page",
            date: "Saturday, November 10, 2012",
            href: "/dir-post",
            "files": {
              "js": [{ "filename": "file1.js", "url": "/full/path/to/file1.js" }],
              "img": [{ "filename": "img1.png", "url": "/full/path/to/img1.png" }]
            }
          }
        }
      },
      _files: ['file1.js', 'file2.js']
    }
  }
}
    1. Render all pages

Rendering Data Structure

As we discussed blacksmith uses hierarchical rendering components. Each component inherits the relevant properties from its parent entity. The full hierarchy is:

  • Site
    • Layout
      • Partial
      • Page
        • Content
        • Partial

Notice that partials can be specified by both layouts and pages. In the event of a conflict the partials specified by the page will always be preferred.

Lets examine a fully-formed data structure for rendering each of our rendering data structures:

Page

  {
    //
    // There are all inherited from Site and Layout that this 
    // page is associated with
    //
    "layout": "layout-name"
    "html": {
      "layouts": { ... },
      "partials": { ... }
    },
    "partials": {
      "html-id": "sidebar",
      "another-id": "breadcrumbs",
      "multiple-partials": ["that-can", "be-overridden"]
    },
    //
    // Metadata is extracted from link definitions on the page prefixed,
    // with "meta:{key}". The {key} is what is stored in the metadata property.
    //
    // e.g. [meta:author] <> (indexzero)  
    //
    "metadata": {
      "author": "indexzero"
    }
  }

Tests

All tests are written with vows and can be run with npm:

  $ npm test

Roadmap

  1. RSS Feed
  2. Only render "dirty" files (i.e. those not modified since last render).
  3. Customize list sorting by key and direction.
  4. Support nested partials.
  5. Support rendering page depths greater than 1.
  6. Support "template" and "partials" in layouts.
  7. Investigate this bug: flatiron/plates#93

License: MIT

blacksmith's People

Contributors

ad-si avatar adammw avatar avianflu avatar bmeck avatar coderarity avatar creatovisguru avatar deanlandolt avatar dscape avatar fb55 avatar hamtie avatar indexzero avatar jfhbrook avatar jfromaniello avatar joeybaker avatar julianduque avatar learningjs avatar marak avatar max-giro avatar mmalecki avatar morganrallen avatar pksunkara avatar polotek avatar saadiq avatar thejh avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

blacksmith's Issues

Include all link definitions in truncated content

Because of the way ##!!truncate is implemented all link definitions in the truncated portion must be defined there. We should grab all link definitions and include them in the Markdown parsing of truncated content

[feature] Categories and tags

Many bloggers want categories and/or tags. There is a sense of tags (ie, meta tags), but that's all they're being used for.

Are "page.json" and "content.md" the best names?

Originally, it was something like article.md and metadata.json, but they were changed to the current state of affairs in order to be more general and descriptive. However, maybe index.json and index.md are better choices?

Requesting feedback.

Windows support?

Hi!

I installed Blacksmith via npm and when I tried to run blacksmith preview on a newly created blog I get errors like Winston trying to use process.getuid() which isn't supported in Windows. Is Windows support planned for Blacksmith?

Add an ignore flag for the ToC

For example, on a blog with some extra pages, the extra pages (such as "archive", "about", etc.) will show up in the ToC.

Maybe the page.json can look like:

{
  "toc": {
    "index": false
  }
}

Commentary appreciated!

The "after the break" algorithm should be more clever.

Currently, the "after the break" algorithm simply looks for the first header smaller than or equal to an h2. However, if the author doesn't have this in mind the results can, well, be surprising.

A smarter algorithm could clip after a certain number of paragraphs and up to/including the last header. Alternately, an "after the break" tag (similar to the snippets tag) could be used.

Move logic for file-system based resources to Resourceful project

Blacksmith currently has it's logic for reading and writing Article resources hard-coded into blacksmith itself.

This is wrong. We should have generic logic available for handling file-system based resources. This logic should be pulled out of blacksmith and added to the Resourceful project.

We also should re-think how the file-system resource logic currently works, it's not exactly ideal yet, particularly in regards to smart updates based on mtime and ctime.

See:

https://github.com/flatiron/blacksmith/blob/master/lib/fs2.js
https://github.com/flatiron/resourceful/

blacksmith doesn't work out of the box

System info:

przemoc@debian:~$ uname -a
Linux debian 3.2.0-2-amd64 #1 SMP Fri Jun 1 17:49:08 UTC 2012 x86_64 GNU/Linux
przemoc@debian:~$ lsb_release -drc
Description:    Debian GNU/Linux testing (wheezy)
Release:    testing
Codename:   wheezy
przemoc@debian:~$ nodejs --version
v0.6.19

blacksmith installation:

przemoc@debian:~$ sudo npm install blacksmith -g
[sudo] password for przemoc: 
npm http GET https://registry.npmjs.org/blacksmith
npm http 200 https://registry.npmjs.org/blacksmith
npm http GET https://registry.npmjs.org/blacksmith/-/blacksmith-0.0.11.tgz
npm http GET https://registry.npmjs.org/blacksmith-sites
npm http GET https://registry.npmjs.org/marked
npm http GET https://registry.npmjs.org/traverse
npm http GET https://registry.npmjs.org/mkdirp
npm http GET https://registry.npmjs.org/http-server/0.2.4
npm http GET https://registry.npmjs.org/jsdom
npm http GET https://registry.npmjs.org/weld/0.2.1
npm http GET https://registry.npmjs.org/findit
npm http GET https://registry.npmjs.org/flatiron/0.1.5-1
npm http GET https://registry.npmjs.org/nconf/0.4.3
npm http GET https://registry.npmjs.org/ncp
npm http GET https://registry.npmjs.org/colors
npm http GET https://registry.npmjs.org/optimist
npm http GET https://registry.npmjs.org/wordwrap
npm http GET https://registry.npmjs.org/rss
npm http GET https://registry.npmjs.org/hashish
npm http GET https://registry.npmjs.org/prompt
npm http GET https://registry.npmjs.org/winston
npm http GET https://registry.npmjs.org/cliff
npm http GET https://registry.npmjs.org/utile/0.0.10
npm http GET https://registry.npmjs.org/alists
npm http GET https://registry.npmjs.org/async
npm http 200 https://registry.npmjs.org/http-server/0.2.4
npm http GET https://registry.npmjs.org/http-server/-/http-server-0.2.4.tgz
npm http 200 https://registry.npmjs.org/blacksmith-sites
npm http GET https://registry.npmjs.org/blacksmith-sites/-/blacksmith-sites-0.0.3.tgz
npm http 200 https://registry.npmjs.org/mkdirp
npm http GET https://registry.npmjs.org/mkdirp/-/mkdirp-0.0.7.tgz
npm http 200 https://registry.npmjs.org/weld/0.2.1
npm http GET https://registry.npmjs.org/weld/-/weld-0.2.1.tgz
npm http 200 https://registry.npmjs.org/traverse
npm http GET https://registry.npmjs.org/traverse/-/traverse-0.4.6.tgz
npm http 200 https://registry.npmjs.org/flatiron/0.1.5-1
npm http GET https://registry.npmjs.org/flatiron/-/flatiron-0.1.5-1.tgz
npm http 200 https://registry.npmjs.org/findit
npm http GET https://registry.npmjs.org/findit/-/findit-0.1.2.tgz
npm http 200 https://registry.npmjs.org/nconf/0.4.3
npm http GET https://registry.npmjs.org/nconf/-/nconf-0.4.3.tgz
npm http 200 https://registry.npmjs.org/marked
npm http GET https://registry.npmjs.org/marked/-/marked-0.1.9.tgz
npm http 200 https://registry.npmjs.org/colors
npm http GET https://registry.npmjs.org/colors/-/colors-0.6.0-1.tgz
npm http 200 https://registry.npmjs.org/ncp
npm http 200 https://registry.npmjs.org/jsdom
npm http GET https://registry.npmjs.org/ncp/-/ncp-0.2.6.tgz
npm http GET https://registry.npmjs.org/jsdom/-/jsdom-0.2.14.tgz
npm http 200 https://registry.npmjs.org/optimist
npm http 200 https://registry.npmjs.org/wordwrap
npm http GET https://registry.npmjs.org/optimist/-/optimist-0.2.8.tgz
npm http 200 https://registry.npmjs.org/rss
npm http GET https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz
npm http GET https://registry.npmjs.org/rss/-/rss-0.0.3.tgz
npm http 200 https://registry.npmjs.org/hashish
npm http 200 https://registry.npmjs.org/prompt
npm http GET https://registry.npmjs.org/hashish/-/hashish-0.0.4.tgz
npm http GET https://registry.npmjs.org/prompt/-/prompt-0.1.12.tgz
npm http 200 https://registry.npmjs.org/utile/0.0.10
npm http GET https://registry.npmjs.org/utile/-/utile-0.0.10.tgz
npm http 200 https://registry.npmjs.org/cliff
npm http GET https://registry.npmjs.org/cliff/-/cliff-0.1.8.tgz
npm http 200 https://registry.npmjs.org/alists
npm http GET https://registry.npmjs.org/alists/-/alists-0.0.2.tgz
npm http 200 https://registry.npmjs.org/winston
npm http GET https://registry.npmjs.org/winston/-/winston-0.5.11.tgz
npm http 200 https://registry.npmjs.org/async
npm WARN excluding symbolic link test/symlinks/dir1/dangling-symlink -> does-not-exist
npm WARN package.json [email protected] 'contributers' should probably be 'contributors'
npm http GET https://registry.npmjs.org/seq
npm http GET https://registry.npmjs.org/rimraf
npm http GET https://registry.npmjs.org/xml
npm http GET https://registry.npmjs.org/logging
npm http GET https://registry.npmjs.org/director/1.0.8
npm http GET https://registry.npmjs.org/pkginfo/0.2.2
npm http GET https://registry.npmjs.org/broadway/0.1.4
npm http GET https://registry.npmjs.org/prompt/0.1.11
npm http GET https://registry.npmjs.org/pkginfo
npm http GET https://registry.npmjs.org/eyes
npm http GET https://registry.npmjs.org/winston
npm http GET https://registry.npmjs.org/ini
npm http GET https://registry.npmjs.org/pkginfo
npm http GET https://registry.npmjs.org/loggly
npm http GET https://registry.npmjs.org/stack-trace
npm http GET https://registry.npmjs.org/htmlparser
npm http GET https://registry.npmjs.org/request
npm http GET https://registry.npmjs.org/cssom
npm http GET https://registry.npmjs.org/contextify
npm http 200 https://registry.npmjs.org/director/1.0.8
npm http GET https://registry.npmjs.org/director/-/director-1.0.8.tgz
npm http 200 https://registry.npmjs.org/xml
npm http GET https://registry.npmjs.org/xml/-/xml-0.0.7.tgz
npm http 200 https://registry.npmjs.org/pkginfo/0.2.2
npm http GET https://registry.npmjs.org/pkginfo/-/pkginfo-0.2.2.tgz
npm http 200 https://registry.npmjs.org/rimraf
npm http 200 https://registry.npmjs.org/logging
npm http GET https://registry.npmjs.org/rimraf/-/rimraf-1.0.9.tgz
npm http GET https://registry.npmjs.org/logging/-/logging-2.0.16.tgz
npm http 200 https://registry.npmjs.org/broadway/0.1.4
npm http GET https://registry.npmjs.org/broadway/-/broadway-0.1.4.tgz
npm http 200 https://registry.npmjs.org/prompt/0.1.11
npm http GET https://registry.npmjs.org/prompt/-/prompt-0.1.11.tgz
npm http 200 https://registry.npmjs.org/seq
npm http GET https://registry.npmjs.org/seq/-/seq-0.3.5.tgz
npm http 304 https://registry.npmjs.org/winston
npm http GET https://registry.npmjs.org/winston/-/winston-0.6.1.tgz
npm http 200 https://registry.npmjs.org/pkginfo
npm http GET https://registry.npmjs.org/pkginfo/-/pkginfo-0.2.3.tgz
npm http 200 https://registry.npmjs.org/eyes
npm http GET https://registry.npmjs.org/eyes/-/eyes-0.1.7.tgz
npm http 200 https://registry.npmjs.org/ini
npm http GET https://registry.npmjs.org/ini/-/ini-1.0.2.tgz
npm http 200 https://registry.npmjs.org/pkginfo
npm http 200 https://registry.npmjs.org/stack-trace
npm http GET https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.6.tgz
npm http 200 https://registry.npmjs.org/loggly
npm http GET https://registry.npmjs.org/loggly/-/loggly-0.3.11.tgz
npm http 200 https://registry.npmjs.org/cssom
npm http GET https://registry.npmjs.org/cssom/-/cssom-0.2.3.tgz
npm http 200 https://registry.npmjs.org/htmlparser
npm http GET https://registry.npmjs.org/htmlparser/-/htmlparser-1.7.6.tgz
npm http 200 https://registry.npmjs.org/contextify
npm http GET https://registry.npmjs.org/contextify/-/contextify-0.1.3.tgz
npm http 200 https://registry.npmjs.org/request
npm http GET https://registry.npmjs.org/request/-/request-2.9.202.tgz
npm http GET https://registry.npmjs.org/chainsaw
npm http GET https://registry.npmjs.org/eventemitter2/0.4.1
npm http GET https://registry.npmjs.org/nconf/0.5.0
npm http GET https://registry.npmjs.org/winston/0.5.9
npm http GET https://registry.npmjs.org/utile/0.0.9
npm http GET https://registry.npmjs.org/cycle
npm http GET https://registry.npmjs.org/pkginfo
npm http GET https://registry.npmjs.org/request
npm http 200 https://registry.npmjs.org/chainsaw
npm http GET https://registry.npmjs.org/chainsaw/-/chainsaw-0.0.9.tgz
npm http GET https://registry.npmjs.org/timespan
npm http 200 https://registry.npmjs.org/utile/0.0.9
npm http GET https://registry.npmjs.org/utile/-/utile-0.0.9.tgz
npm http 200 https://registry.npmjs.org/cycle
npm http GET https://registry.npmjs.org/cycle/-/cycle-1.0.0.tgz
npm http 304 https://registry.npmjs.org/pkginfo
npm http 200 https://registry.npmjs.org/nconf/0.5.0
npm http GET https://registry.npmjs.org/nconf/-/nconf-0.5.0.tgz
npm http 304 https://registry.npmjs.org/request
npm http 200 https://registry.npmjs.org/eventemitter2/0.4.1
npm http GET https://registry.npmjs.org/eventemitter2/-/eventemitter2-0.4.1.tgz
npm http 200 https://registry.npmjs.org/timespan
npm http GET https://registry.npmjs.org/timespan/-/timespan-2.2.0.tgz
npm http 200 https://registry.npmjs.org/winston/0.5.9
npm http GET https://registry.npmjs.org/winston/-/winston-0.5.9.tgz
npm http GET https://registry.npmjs.org/traverse
npm WARN package.json [email protected] 'contributers' should probably be 'contributors'
npm http 304 https://registry.npmjs.org/traverse
npm http GET https://registry.npmjs.org/traverse/-/traverse-0.3.9.tgz
npm http GET https://registry.npmjs.org/bindings
npm http GET https://registry.npmjs.org/rimraf
npm http GET https://registry.npmjs.org/ini
npm http GET https://registry.npmjs.org/eyes
npm http GET https://registry.npmjs.org/loggly
npm http GET https://registry.npmjs.org/stack-trace
npm http 304 https://registry.npmjs.org/loggly
npm http 304 https://registry.npmjs.org/stack-trace
npm http 200 https://registry.npmjs.org/bindings
npm http GET https://registry.npmjs.org/bindings/-/bindings-0.3.0.tgz
npm http 304 https://registry.npmjs.org/rimraf
npm http 304 https://registry.npmjs.org/ini
npm http 304 https://registry.npmjs.org/eyes
npm http GET https://registry.npmjs.org/request
npm http GET https://registry.npmjs.org/timespan

> [email protected] install /usr/lib/node_modules/blacksmith/node_modules/jsdom/node_modules/contextify
> node-gyp rebuild

npm http 304 https://registry.npmjs.org/timespan
npm http 304 https://registry.npmjs.org/request
gyp WARN install got an error, rolling back install
gyp ERR! rebuild error Error: EACCES, stat '/root/.node-gyp/0.6.19'
gyp ERR! not ok 
npm WARN optional dep failed, continuing [email protected]
/usr/bin/blacksmith -> /usr/lib/node_modules/blacksmith/bin/blacksmith
[email protected] /usr/lib/node_modules/blacksmith/node_modules/alists

[email protected] /usr/lib/node_modules/blacksmith/node_modules/colors

[email protected] /usr/lib/node_modules/blacksmith/node_modules/hashish

[email protected] /usr/lib/node_modules/blacksmith/node_modules/mkdirp

[email protected] /usr/lib/node_modules/blacksmith/node_modules/weld

[email protected] /usr/lib/node_modules/blacksmith/node_modules/marked

[email protected] /usr/lib/node_modules/blacksmith/node_modules/wordwrap

[email protected] /usr/lib/node_modules/blacksmith/node_modules/async

[email protected] /usr/lib/node_modules/blacksmith/node_modules/ncp

[email protected] /usr/lib/node_modules/blacksmith/node_modules/optimist

[email protected] /usr/lib/node_modules/blacksmith/node_modules/traverse

[email protected] /usr/lib/node_modules/blacksmith/node_modules/http-server

[email protected] /usr/lib/node_modules/blacksmith/node_modules/blacksmith-sites

[email protected] /usr/lib/node_modules/blacksmith/node_modules/utile/node_modules/rimraf

[email protected] /usr/lib/node_modules/blacksmith/node_modules/utile

[email protected] /usr/lib/node_modules/blacksmith/node_modules/rss/node_modules/logging

[email protected] /usr/lib/node_modules/blacksmith/node_modules/rss/node_modules/xml

[email protected] /usr/lib/node_modules/blacksmith/node_modules/rss

[email protected] /usr/lib/node_modules/blacksmith/node_modules/prompt/node_modules/pkginfo

[email protected] /usr/lib/node_modules/blacksmith/node_modules/prompt

[email protected] /usr/lib/node_modules/blacksmith/node_modules/nconf/node_modules/ini

[email protected] /usr/lib/node_modules/blacksmith/node_modules/nconf/node_modules/pkginfo

[email protected] /usr/lib/node_modules/blacksmith/node_modules/nconf

[email protected] /usr/lib/node_modules/blacksmith/node_modules/cliff/node_modules/eyes

[email protected] /usr/lib/node_modules/blacksmith/node_modules/cliff/node_modules/winston/node_modules/cycle

[email protected] /usr/lib/node_modules/blacksmith/node_modules/cliff/node_modules/winston/node_modules/stack-trace

[email protected] /usr/lib/node_modules/blacksmith/node_modules/cliff/node_modules/winston/node_modules/pkginfo

[email protected] /usr/lib/node_modules/blacksmith/node_modules/cliff/node_modules/winston/node_modules/request

[email protected] /usr/lib/node_modules/blacksmith/node_modules/cliff/node_modules/winston

[email protected] /usr/lib/node_modules/blacksmith/node_modules/cliff

[email protected] /usr/lib/node_modules/blacksmith/node_modules/winston/node_modules/eyes

[email protected] /usr/lib/node_modules/blacksmith/node_modules/winston/node_modules/stack-trace

[email protected] /usr/lib/node_modules/blacksmith/node_modules/winston/node_modules/pkginfo

[email protected] /usr/lib/node_modules/blacksmith/node_modules/winston/node_modules/loggly/node_modules/timespan

[email protected] /usr/lib/node_modules/blacksmith/node_modules/winston/node_modules/loggly/node_modules/request

[email protected] /usr/lib/node_modules/blacksmith/node_modules/winston/node_modules/loggly

[email protected] /usr/lib/node_modules/blacksmith/node_modules/winston

[email protected] /usr/lib/node_modules/blacksmith/node_modules/findit/node_modules/seq/node_modules/chainsaw/node_modules/traverse

[email protected] /usr/lib/node_modules/blacksmith/node_modules/findit/node_modules/seq/node_modules/chainsaw

[email protected] /usr/lib/node_modules/blacksmith/node_modules/findit/node_modules/seq

[email protected] /usr/lib/node_modules/blacksmith/node_modules/findit

[email protected] /usr/lib/node_modules/blacksmith/node_modules/flatiron/node_modules/pkginfo

[email protected] /usr/lib/node_modules/blacksmith/node_modules/flatiron/node_modules/prompt

[email protected] /usr/lib/node_modules/blacksmith/node_modules/flatiron/node_modules/director

[email protected] /usr/lib/node_modules/blacksmith/node_modules/flatiron/node_modules/broadway/node_modules/eventemitter2

[email protected] /usr/lib/node_modules/blacksmith/node_modules/flatiron/node_modules/broadway/node_modules/utile/node_modules/rimraf

[email protected] /usr/lib/node_modules/blacksmith/node_modules/flatiron/node_modules/broadway/node_modules/utile

[email protected] /usr/lib/node_modules/blacksmith/node_modules/flatiron/node_modules/broadway/node_modules/nconf/node_modules/ini

[email protected] /usr/lib/node_modules/blacksmith/node_modules/flatiron/node_modules/broadway/node_modules/nconf

[email protected] /usr/lib/node_modules/blacksmith/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/eyes

[email protected] /usr/lib/node_modules/blacksmith/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/stack-trace

[email protected] /usr/lib/node_modules/blacksmith/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/loggly/node_modules/timespan

[email protected] /usr/lib/node_modules/blacksmith/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/loggly/node_modules/request

[email protected] /usr/lib/node_modules/blacksmith/node_modules/flatiron/node_modules/broadway/node_modules/winston/node_modules/loggly

[email protected] /usr/lib/node_modules/blacksmith/node_modules/flatiron/node_modules/broadway/node_modules/winston

[email protected] /usr/lib/node_modules/blacksmith/node_modules/flatiron/node_modules/broadway

[email protected] /usr/lib/node_modules/blacksmith/node_modules/flatiron

[email protected] /usr/lib/node_modules/blacksmith/node_modules/jsdom/node_modules/cssom

[email protected] /usr/lib/node_modules/blacksmith/node_modules/jsdom/node_modules/request

[email protected] /usr/lib/node_modules/blacksmith/node_modules/jsdom/node_modules/htmlparser

[email protected] /usr/lib/node_modules/blacksmith/node_modules/jsdom

Blog creation:

przemoc@debian:~$ blacksmith init
info: Executing command init
info: init can create any of these site types:
info: 
info:     * doc: A docs site for blacksmith
info:     * blog: A simple blacksmith blog using Scribbish
info: 
prompt: Choose your website type: blog
info: Selecting website type blog...
prompt: Name your website: blog
warn: blacksmith is about to write a blog site to ./blog!
prompt: Is this okay? [y/N]: y
info: * Created `./blog`.

Generation:

przemoc@debian:~$ cd blog/
przemoc@debian:~/blog$ blacksmith generate
info: Executing command generate
{
  "process": {
    "pid": 5516,
    "uid": 1000,
    "gid": 1000,
    "cwd": "/home/przemoc/blog",
    "execPath": "/usr/bin/node",
    "version": "v0.6.19",
    "argv": [
      "node",
      "/usr/bin/blacksmith",
      "generate"
    ],
    "memoryUsage": {
      "rss": 32608256,
      "heapTotal": 30156288,
      "heapUsed": 13121912
    }
  },
  "os": {
    "loadavg": [
      0.98583984375,
      1.05078125,
      1.06005859375
    ],
    "uptime": 3726.38355848
  },
  "trace": [
    {
      "column": 59,
      "file": "/usr/lib/node_modules/blacksmith/node_modules/jsdom/lib/jsdom.js",
      "function": null,
      "line": 171,
      "method": null,
      "native": false
    },
    {
      "column": 5,
      "file": "/usr/lib/node_modules/blacksmith/node_modules/jsdom/lib/jsdom.js",
      "function": "Object.env",
      "line": 262,
      "method": "env",
      "native": false
    },
    {
      "column": 9,
      "file": "/usr/lib/node_modules/blacksmith/lib/blacksmith.js",
      "function": "Object.generate",
      "line": 83,
      "method": "generate",
      "native": false
    },
    {
      "column": 11,
      "file": "/usr/lib/node_modules/blacksmith/lib/commands/generate.js",
      "function": null,
      "line": 22,
      "method": null,
      "native": false
    },
    {
      "column": 19,
      "file": "/usr/lib/node_modules/blacksmith/node_modules/flatiron/lib/flatiron/plugins/cli.js",
      "function": "executeCommand",
      "line": 176,
      "method": null,
      "native": false
    },
    {
      "column": 5,
      "file": "/usr/lib/node_modules/blacksmith/node_modules/flatiron/lib/flatiron/plugins/cli.js",
      "function": "",
      "line": 221,
      "method": null,
      "native": false
    },
    {
      "column": 21,
      "file": "Object].dispatch (/usr/lib/node_modules/blacksmith/node_modules/flatiron/node_modules/director/lib/director/cli.js",
      "function": "[object",
      "line": 50,
      "method": null,
      "native": false
    },
    {
      "column": 18,
      "file": "/usr/lib/node_modules/blacksmith/node_modules/flatiron/lib/flatiron/plugins/cli.js",
      "function": null,
      "line": 58,
      "method": null,
      "native": false
    },
    {
      "column": 12,
      "file": "Object].<anonymous> (/usr/lib/node_modules/blacksmith/node_modules/flatiron/node_modules/broadway/lib/broadway/app.js",
      "function": "[object",
      "line": 74,
      "method": null,
      "native": false
    },
    {
      "column": 31,
      "file": "Object].init (/usr/lib/node_modules/blacksmith/node_modules/flatiron/lib/flatiron/app.js",
      "function": "[object",
      "line": 31,
      "method": null,
      "native": false
    }
  ],
  "stack": [
    "TypeError: Cannot read property 'implementation' of undefined",
    "    at /usr/lib/node_modules/blacksmith/node_modules/jsdom/lib/jsdom.js:171:59",
    "    at Object.env (/usr/lib/node_modules/blacksmith/node_modules/jsdom/lib/jsdom.js:262:5)",
    "    at Object.generate (/usr/lib/node_modules/blacksmith/lib/blacksmith.js:83:9)",
    "    at /usr/lib/node_modules/blacksmith/lib/commands/generate.js:22:11",
    "    at executeCommand (/usr/lib/node_modules/blacksmith/node_modules/flatiron/lib/flatiron/plugins/cli.js:176:19)",
    "    at Object.<anonymous> (/usr/lib/node_modules/blacksmith/node_modules/flatiron/lib/flatiron/plugins/cli.js:221:5)",
    "    at [object Object].dispatch (/usr/lib/node_modules/blacksmith/node_modules/flatiron/node_modules/director/lib/director/cli.js:50:21)",
    "    at /usr/lib/node_modules/blacksmith/node_modules/flatiron/lib/flatiron/plugins/cli.js:58:18",
    "    at [object Object].<anonymous> (/usr/lib/node_modules/blacksmith/node_modules/flatiron/node_modules/broadway/lib/broadway/app.js:74:12)",
    "    at [object Object].init (/usr/lib/node_modules/blacksmith/node_modules/flatiron/lib/flatiron/app.js:31:31)"
  ],
  "level": "error",
  "message": "uncaughtException"
}

Did I forget about something?

blacksmith init -- TypeError: Object #<Object> has no method 'help'

jd:Desktop jmonster$ blacksmith init

info: Executing command init
{
  "process": {
    "pid": 17290,
    "uid": 501,
    "gid": 20,
    "cwd": "/Users/jmonster/Desktop",
    "execPath": "/usr/local/Cellar/node/0.6.9/bin/node",
    "version": "v0.6.9",
    "argv": [
      "node",
      "/usr/local/bin/blacksmith",
      "init"
    ],
    "memoryUsage": {
      "rss": 27594752,
      "heapTotal": 17694080,
      "heapUsed": 10891440
    }
  },
  "os": {
    "loadavg": [
      0.421875,
      0.60205078125,
      0.51025390625
    ],
    "uptime": 132447
  },
  "trace": [
    {
      "column": 15,
      "file": "/usr/local/lib/node_modules/blacksmith/lib/commands/init.js",
      "function": "getType",
      "line": 41,
      "method": null,
      "native": false
    },
    {
      "column": 5,
      "file": "/usr/local/lib/node_modules/blacksmith/lib/commands/init.js",
      "function": null,
      "line": 67,
      "method": null,
      "native": false
    },
    {
      "column": 5,
      "file": "/usr/local/lib/node_modules/blacksmith/node_modules/blacksmith-sites/index.js",
      "function": "Object.oncomplete",
      "line": 27,
      "method": "oncomplete",
      "native": false
    }
  ],
  "stack": [
    "TypeError: Object #<Object> has no method 'help'",
    "    at getType (/usr/local/lib/node_modules/blacksmith/lib/commands/init.js:41:15)",
    "    at /usr/local/lib/node_modules/blacksmith/lib/commands/init.js:67:5",
    "    at Object.oncomplete (/usr/local/lib/node_modules/blacksmith/node_modules/blacksmith-sites/index.js:27:5)"
  ],
  "level": "error",
  "message": "uncaughtException"
}

Bug in page titles

For example:

:: Mad Science at Nodejitsu

Something before the join is 0 characters long.

Remove unnecessary reading and writing of files

Based on the logs and generation time, it seems that we are reading and writing files that have not been modified.

We should change the generation code to be more intelligent ( i.e., check mtimes on all files before read and write )

Read all data only once

Right now, aside from the "content" loader, fs reads also occur in the toc loader and the snippets loader. Really, all of this should take place in the content loading step.

Switch from marked to faster parser written in C (sundown): Robotskirt

Currently blacksmith uses marked, which is fine and relatively fast. But there is a faster one, Robotskirt based on the parser written in C: sundown, the one internally used by GitHub. As marked by default uses GitHub Flavored Markdown, it should be possible to perform the switch transparently I guess.

The only problem atm is that Robotskirt is in the process of making some changes to upgrade to recent sundown version (see Issue 16) and do some other improvements (see last comments of Issue 11), thus such switch possibly shouldn't happen before.

./post1/post1 static hosting on s3

I am hosting my blog in static files on s3, when I am on index.html, clicking on the title of a blog post works properly by resolving to mysite.com/post1 . If I am on the specific post page and click the title again, it tries to resolve to mysite.com/post1/post1

This only happens when I upload to s3, not from

blacksmith preview

Blacksmith should not assume index.html completion

Quote from Bradley:

Currently we assume index.html completion for servers, which while using Apache, node-http-server, etc. is viable, pushing content to a CDN for static sites is a common solution that may not support directory forwarding to index.html.

I'm not actually sure what needs to change in blacksmith to allow for this use case.

cannot deploy to nodejitsu

error:  Error running command deploy
error:  Nodejitsu Error (500): Internal Server Error
error:  
error:  There was an error while attempting to start your application.
error:  Error spawning drone
error:  Script prematurely exited
error:  
error:  This type of error is usually a user error.
error:  Error output from your application:
error:  
error:  node.js:201
error:          throw e; // process.nextTick error, or 'error' event on first tick
error:                ^
error:  TypeError: undefined is not a function
error:      at Object.<anonymous> (/usr/local/src/domino/blacksmith-blog/domino/bin/server:3:18)
error:      at Module._compile (module.js:432:26)
error:      at Object..js (module.js:450:10)
error:      at Module.load (module.js:351:31)
error:      at Function._load (module.js:310:12)
error:      at Function.runMain (module.js:470:10)
error:      at Array.1 (/root/haibu-orchestra/node_modules/haibu/node_modules/haibu-carapace/lib/carapace.js:190:30)
error:      at EventEmitter._tickCallback (node.js:192:40)
info:   Nodejitsu not ok

Sort ToC by date

I need to add code to the ToC to make it sorted in reverse chrono. order. At this time, the ToC isn't sorted with respect to date at all.

[feature] Exposed hooks for postprocessing

At least one user has an interest in running their blacksmith-generated site through tools like js and css minifiers. I think this will be relatively easy to do once the rendering refactor is done.

Integrating LESS and reducing template duplication?

So i know microtemplating is avoided with blacksmith. However, how would i go about integrating LESS so that .less stylesheets are compiled into css in the public folder?

I really dig how blacksmith is setup, but LESS is a bit part of my workflow and i'd love to get it integrated.
Also, if i wanted to breakdown the templates so that code isn't duplicated in every template file, how would i go about it in a way that doesn't bloat blacksmith? Is there a way? Or would i have to resort to a microformat?

Code duplication and lack of Less are the only issues i have and would love to come up with work arounds for them.

All commands should run from 'site' directory

After blacksmith init, blacksmith preview and generate are run from the root directory. But running blacksmith post is required to be run from root/pages. I feel it should be aware of where the site content directory so all the commands can be run the root.

Features needed

I really think I'll used Blacksmith instead on Octopress ... Anyway some keys features are needed to have an awesome blog :

  • categories
  • pagination
  • tags

For optimizing speed adding a CSS+JS compressor, and ask for URI encoded IMG :)

Thank's

Invalid HTML generated

Blacksmith does not generate valid HTML. Main problems are as follow:

  • missing doctype declaration
  • nav missess <ul> tag
  • time is in wrong format (inside <time> tag)

On all other pages than index doctype and ul are present and in correct place.

To reproduce just:

  • blacksmith init
  • blackmith generate
  • open file public/index.html

Relative links should be allowed

Quote from Bradley:

Right now links assume that a blacksmith site lives at the root of a server. Since some people may put a blacksmith site at a path other than root, we should respect this and use relative links starting with '.' or '..' instead.

Working with paths in blacksmith is a little bit messy, so path handling should probably get a makeover before this issue is fixed.

support http-server 0.4.x

Though using 'blacksmith preview works', however node./bin/server gives TypeError: undefined is not a function in ./bin/server:3. when using http-server >=0.3.0.

This causes a problem running 'jitsu deploy' with the dependency in package.json set for http-server as "*" which was until recently the default. I see it has been set to specifically 0.2.4 as of a few days ago.

The current version of http-server is 0.4.0 and dependency has to be set as "0.2.4" to deploy on nodejitsu or run locally using node./bin/server.

Simplifying ./bin/server to something like the following and using default port 8080 and public dir allows 'node ./bin/server to start the app locally with version 0.4.0 of http-server. Have not tested this with nodejitsu or am I sure this is a good way to do it.

var httpServer = require('http-server');

httpServer.start();

process.on('SIGINT', function() {
httpServer.log('http-server stopped.'.red);
return process.exit();
});

Incorrect markup generated on front page

Using both the master and refactored branches, the initial "blacksmith init" creates a post entitled "First post".

Upon "blacksmith generate", the rendered HTML lists the post title as "My awesome blog" on the front page.
On the article page itself, the post title is correct.

Posts created using "blacksmith post" also generates an incorrect front page. Again, the post title is corrected on the article page.

Any idea what could be causing this?

Add way to do includes

This would be something that coopts some div class (or other tag if there is a more appropriate one) to allow for text insertion of files relative to content's root.

Proper article previews

Basically, the article previews use jquery. This is the right idea, but the selectors/algorithm are wrong right now.

lstat > stat

lstat is symlink-aware, and as such is a better fit than stat for most (if not all) cases of its use in blacksmith.

Add an "after the break" tag

This would work similarly to snippet embeds in blacksmith now. This would break wheat compatibility, which breaks on the first <h2>.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.