CFCamp Notes - Static Site Generation Using Node.JS, David Boyer

October 25, 2015

Not specific to node.js could use CF or whatever else to build a static site too.

the architecture (stuff you're hosting) is static
normal HTML, images, javascript, css

could use client-side JS to modify the pages when you need a "tiny bit" of dynamic content

generation by script or app
front dynamic sources
the generation process can go talk to a DB or a flat file system (a blog built from markdown-based files, etc) then re-render the generation process

why not dynamically serve via php or cf?
speed - most important reason
with dynamic tech there is some latency all the time
Amazon did research on this in 2006
-- every 100ms of delays cost 1% of sales (quite a bit of money for Amazon sized companies)

Obama's election website
improved page load time by 60% resulted in an increase in donations to the campaign

dynamic resources add latency
databases
web services
server-side processing to glue it all together

security
if there's no server side component, there's less of an attack vector. Only the web server (apache) would be available for attacking (if you don't use PHP, CF, etc).
have to worry about keeping server up to date
3rd party bits of code have to be updated as well.
plus keeping all your own code secure

points of failure
databases going down
app server locked up
(some services display a "status" page when your site is down, but it's still down.)

running costs
log files to check
additional CPU power needed to host all the back-end code
(David's blog is entirely hosted on GitHub -- no cost)

static sites -- improves on those dynamic downsides
more secure, only a web server to attack
faster, no database or server-side processing to construct the page
fewer points of failure
easily cacheable or hosted across multiple servers
easier to debut the HTML served only change when you regenerate
-- the bug is probably in the generation process, probably easy to fix too

it doesn't fit every situation
if you're building a big web app for handling customer data, reports, very dynamic interfaces, etc, it's probably not a good fit
but if you're serving a lot of pages that don't change, then static could be a solution

client-side dynamic code
areas of your static pages can still be dynamic using JS
recent tweets
visitor comments
analytics
social media sharing

suggested usages
project scaffolder -- you have your initial template, can just tweak the style and spit out an initial copy of the project. could have CF code in your templates
build tool
ebook generator -- render the final book as a PDF, doesn't have to be HTML output
technical docs -- build a folder of markdown based files for all the instructions and build a Bootstrap based website
article / blog based sites
startup / product based sites

Metalsmith -- David's tool of choice (various other solutions out there already too)
Node.js based app
recursive read of all files in the ./src directory
write your code in JS for your site
to generate site -- node build mySite.js

to install
install node
npm install metalsmith
(can do global install making it available at the command line)
better to install locally and have a build object instead

manipulate file data thru a series of plugins

writes the results to a ./build directory -- that's your static output -- the site HTML, the final PDF for the customer, etc.

MetalSmith plugins
provided to metalsmith via the .use(fn) method
plugin is provided w/ a list of files found and parsed by metalsmith
a reference to the metalsmith instance
callback function to signal plugin is complete, useful for async operations

Markdown plugin
YAML based

metalsmith-layouts jade plugin
supports a wide range of template systems (don't HAVE to use Jade!)

metalsmith-collections
robust plugin
you point it to a folder, it will group together all the markdown files it finds
can filter them by attributes, etc.
can sort by the meta data
supports multiple groups -- /blog, /pages, etc, all defined separately however you like
array based -- easy to say "slice off the top 5 entires and do something with them"

metalsmith-pagination plugin
generates all the "prev" and "next" links for all your pages

metalsmith-permalinks plugin
set rules to form URLs for your pages
use metadata collected from the parsed files
example:
{pattern: ':date/:title'}
creates a file within the path and provides a new `.path` attribute in the file data

(nothing stopping you from writing your own plugin if you want to customize how the URLs are formatted)

loads of other plugins in the Metalsmith website, or can just google for them

metalsmith-more
can add a "summary" of a page with a "more" link that points to the full detailed page

www.metalsmith.io

metalsmith-feed -- create feeds of a site

metalsmith-lunr
- builds a data file, you use that with some client-side JS to build a search engine for the site. (wouldn't want to cover ALL the content in the site, just the main content. tell the plugin about the important content and it will search your site.)

metalsmith-prism
code highlighting

metalsmith-redirect
to forward people to new content rather than them getting 404's on old pages that have been deleted
loops over original URLs and creates redirect files
also informs the search engines about the new locations for that content

plenty you can to do built out your site and make it feel more expansive
paginated blog posts
search support (gouge custom, lunr.js)
comments (disqus, discourse, isso)
rss feeds
contact form (google docs, wufoo)
highlight code (prism, highlight.js)
sitemap
etc