Skip to content

Instantly share code, notes, and snippets.

@stephanebachelier
Created May 9, 2014 16:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save stephanebachelier/2afc4c29c2e9a30b6e9d to your computer and use it in GitHub Desktop.
Save stephanebachelier/2afc4c29c2e9a30b6e9d to your computer and use it in GitHub Desktop.
Draftable articles for winter smith blog
{
"plugins": [
"./plugins/paginator.coffee",
"./plugins/draftable_page.coffee",
"wintersmith-livereload"
],
"paginator": {
"perPage": 3
}
}
# file should be placed under plugins directory
module.exports = (env, callback) ->
class DraftablePage extends env.plugins.MarkdownPage
isDraft: -> @metadata.draft is true
getView: ->
return 'none' if @isDraft()
return super()
env.registerContentPlugin 'pages', '**/*.*(markdown|mkd|md)', DraftablePage
callback()
# file should be placed under plugins directory
module.exports = (env, callback) ->
### Paginator plugin. Defaults can be overridden in config.json
e.g. "paginator": {"perPage": 10} ###
defaults =
template: 'index.jade' # template that renders pages
articles: 'articles' # directory containing contents to paginate
first: 'index.html' # filename/url for first page
filename: 'page/%d/index.html' # filename for rest of pages
perPage: 2 # number of articles per page
# assign defaults any option not set in the config file
options = env.config.paginator or {}
for key, value of defaults
options[key] ?= defaults[key]
getArticles = (contents) ->
# helper that returns a list of articles found in *contents*
# note that each article is assumed to have its own directory in the articles directory
articles = contents[options.articles]._.directories.map (item) -> item.index
articles = articles.filter (article) ->
return false if article.metadata.draft is true
article
articles.sort (a, b) -> b.date - a.date
return articles
class PaginatorPage extends env.plugins.Page
### A page has a number and a list of articles ###
constructor: (@pageNum, @articles) ->
getFilename: ->
if @pageNum is 1
options.first
else
options.filename.replace '%d', @pageNum
getView: -> (env, locals, contents, templates, callback) ->
# simple view to pass articles and pagenum to the paginator template
# note that this function returns a funciton
# get the pagination template
template = templates[options.template]
if not template?
return callback new Error "unknown paginator template '#{ options.template }'"
# setup the template context
ctx = {@articles, @prevPage, @nextPage}
# extend the template context with the enviroment locals
env.utils.extend ctx, locals
# finally render the template
template.render ctx, callback
# register a generator, 'paginator' here is the content group generated content will belong to
# i.e. contents._.paginator
env.registerGenerator 'paginator', (contents, callback) ->
# find all articles
articles = getArticles contents
# populate pages
numPages = Math.ceil articles.length / options.perPage
pages = []
for i in [0...numPages]
pageArticles = articles.slice i * options.perPage, (i + 1) * options.perPage
pages.push new PaginatorPage i + 1, pageArticles
# add references to prev/next to each page
for page, i in pages
page.prevPage = pages[i - 1]
page.nextPage = pages[i + 1]
# create the object that will be merged with the content tree (contents)
# do _not_ modify the tree directly inside a generator, consider it read-only
rv = {pages:{}}
for page in pages
rv.pages["#{ page.pageNum }.page"] = page # file extension is arbitrary
rv['index.page'] = pages[0] # alias for first page
# callback with the generated contents
callback null, rv
# add the article helper to the environment so we can use it later
env.helpers.getArticles = getArticles
# tell the plugin manager we are done
callback()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment