{"id":13451443,"url":"https://github.com/jnordberg/wintersmith","last_synced_at":"2025-05-13T18:09:22.665Z","repository":{"id":2373032,"uuid":"3337657","full_name":"jnordberg/wintersmith","owner":"jnordberg","description":"A flexible static site generator","archived":false,"fork":false,"pushed_at":"2021-07-15T14:10:26.000Z","size":1649,"stargazers_count":3495,"open_issues_count":18,"forks_count":331,"subscribers_count":86,"default_branch":"master","last_synced_at":"2025-05-10T05:34:38.610Z","etag":null,"topics":["nodejs","static-site-generator","wintersmith"],"latest_commit_sha":null,"homepage":"http://wintersmith.io/","language":"CoffeeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jnordberg.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGES.md","contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2012-02-02T18:54:12.000Z","updated_at":"2025-05-08T23:56:25.000Z","dependencies_parsed_at":"2022-08-20T16:50:53.972Z","dependency_job_id":null,"html_url":"https://github.com/jnordberg/wintersmith","commit_stats":null,"previous_names":[],"tags_count":44,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jnordberg%2Fwintersmith","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jnordberg%2Fwintersmith/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jnordberg%2Fwintersmith/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jnordberg%2Fwintersmith/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jnordberg","download_url":"https://codeload.github.com/jnordberg/wintersmith/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253457987,"owners_count":21911771,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["nodejs","static-site-generator","wintersmith"],"created_at":"2024-07-31T07:00:53.904Z","updated_at":"2025-05-13T18:09:22.632Z","avatar_url":"https://github.com/jnordberg.png","language":"CoffeeScript","funding_links":[],"categories":["CoffeeScript","Packages","包","目录","nodejs","Static site generators","static-site-generator","Uncategorized","By Language"],"sub_categories":["Static site generators","静态网站生成","静态站点生成","Uncategorized","JavaScript / Node.js"],"readme":"#![Wintersmith](http://wintersmith.io/images/wintersmith.svg)\n\nWintersmith is a simple yet flexible static site generator. It takes contents (markdown, less, scripts, etc), transforms them using plugins and outputs a static website (html, css, images, etc) that you can host anywhere.\n\nIt ships with plugins for [markdown](http://daringfireball.net/projects/markdown/) and [pug templates](https://github.com/pugjs/pug), if you need something else check the [plugin listing][plugin-listing] or [write your own][plugin-guide]!\n\n## Resources\n\n * [Project site][website]\n * [API Documentation][docs]\n * [Wiki][wiki]\n * [stackoverflow tag](http://stackoverflow.com/questions/tagged/wintersmith)\n * IRC - **#wintersmith** on freenode\n\n[website]: http://wintersmith.io \"Wintersmith project website\"\n[docs]: http://wintersmith.io/docs \"Wintersmith API Documentation\"\n[wiki]: https://github.com/jnordberg/wintersmith/wiki \"Wintersmith wiki\"\n[plugin-listing]: https://github.com/jnordberg/wintersmith/wiki/Plugins \"Wintersmith plugin listing\"\n[plugin-guide]: https://github.com/jnordberg/wintersmith/wiki/Writing-plugins \"Wintersmith plugin guide\"\n\n## Quick-start\n\nFirst install wintersmith using [npm](http://npmjs.org/):\n\n```bash\n$ npm install wintersmith -g\n```\n\nThis will install wintersmith globally on your system so that you can access the `wintersmith` command from anywhere. Once that is complete run:\n\n```bash\n$ wintersmith new \u003cpath\u003e\n```\n\nWhere `\u003cpath\u003e` is the location you want the site to be generated. This creates a skeleton site with a basic set of templates and some articles, while not strictly needed it's a good starting point.\n\nNow enter the directory and start the preview server:\n\n```bash\n$ cd \u003cpath\u003e\n$ wintersmith preview\n```\n\nAt this point you are ready to start customizing your site. Point your browser to `http://localhost:8080` and start editing templates and articles.\n\nWhen done run:\n\n```bash\n$ wintersmith build\n```\n\nThis generates your site and places it in the `build/` directory - all ready to be copied to your web server!\n\nAnd remember to give the old `--help` a look :-)\n\n## Overview\n\nA wintersmith site is built up of three main components: contents, views and templates.\n\nContents is a directory where all the sites raw material goes (markdown files, images, javascript etc). This directory is then scanned to produce what's internally called a ContentTree.\n\nThe ContentTree is a nested object built up of ContentPlugins and looks something like this:\n\n```javascript\n{\n  \"myfile.md\": {MarkdownPlugin} // plugin instance, subclass of ContentPlugin\n  \"some-dir/\": { // another ContentTree instance\n    \"image.jpg\": {StaticPlugin}\n    \"random.file\": {StaticPlugin}\n  }\n}\n```\n\n![Wintersmith](http://wintersmith.io/images/flow.svg)\n\nThis content tree is provided in full to the views when rendering. This gives you a lot of flexibility when writing plugins, you could for example write a plugin that generates a mosaic using images located in a specific directory.\n\nWintersmith comes with a default Page plugin that renders markdown content using templates. This plugin takes markdown (combined with some metadata, more on this later) compiles it and provides it to a template along with the content tree and some utility functions.\n\nThis brings us to the second component, the template directory. All templates found in this directory are loaded and are also passed to the content plugins when rendering.\n\nBy default only `.pug` templates are loaded, but you can easily add template plugins to use a template engine of your choosing.\n\nCheck the `examples/` directory for some inspiration on how you can use wintersmith or the [showcase](https://github.com/jnordberg/wintersmith/wiki/Showcase) to see what others are doing.\n\n## Configuration\n\nConfiguration can be done with command-line options, a config file or both. The config file will be looked for as `config.json` in the root of your site (you can set a custom path using `--config`).\n\n### Options\n\nName         | Default         | Description\n-------------|-----------------|-----------------------------------------------\ncontents     | `./contents`    | contents directory location\ntemplates    | `./templates`   | templates directory location\nviews        | `null`          | views directory location, optional\nlocals       | `{}`            | global site variables, can also be a path to a json file\nrequire      | `{}`            | modules to load and add to locals. e.g. if you want underscore as `_` you would say `{\"_\": \"underscore\"}`\nplugins      | `[]`            | list of plugins to load\nignore       | `[]`            | list of files or pattern to ignore\noutput       | `./build`       | output directory, this is where the generated site is output when building\nfilenameTemplate | `:file.html`| outputs filenames and paths according to a template. ([documentation](https://github.com/jnordberg/wintersmith/wiki/Page-Plugin#filename-templating))\nintroCutoffs | `['\u003cspan class=\"more', '\u003ch2', '\u003chr']` | list of strings to search for when determining if a page has an intro\nbaseUrl      | `/`             | base url that site lives on, e.g. `/blog/`.\nhostname     | `null`          | hostname to bind preview server to, null = INADDR_ANY\nport         | `8080`          | port preview server listens on\n\nAll paths can either be relative or absolute. Relative paths will be resolved from the working directory or `--chdir` if set.\n\n## Content Plugins\n\nContentPlugins transform content, each item in the content tree is represented by a ContentPlugin instance. Content plugins can be created from files matching a glob pattern or by generators.\n\nThe ContentPlugin class is that all content plugins inherit from. Subclasses have to implement the `getFilename` and `getView` instance methods and the `fromFile` class method - more info in the [plugin guide][plugin-guide].\n\nAll content plugins have the following properties (a property in wintersmith is simply a shortcut to a getter. i.e. `item.filename` is the same as calling `item.getFilename()`)\n\nProperty     | Getter signature | Description\n-------------|------------------|---------------------\nfilename     | `getFilename()`  | filename content will be rendered to\nview         | `getView()`      | function used to render the plugin, e.g. the page plugin uses a view that passes the plugin and locals to a template\nurl          | `getUrl(base)`   | url for the content. *base* is from where this url will be resolved and defaults to `config.baseUrl`. for example you can call `content.getUrl('http://myiste.com')` to get a permalink to that content\n\n## The Page plugin\n\nWintersmith ships with a page plugin. This plugin is what the markdown page and many other content plugins build upon.\n\n### Model\n\nThe Page model (inherits from ContentPlugin)\n\nProperties:\n\nName         | Description\n-------------|------------\nmetadata     | object containing the pages metadata\ntitle        | `metadata.title` or `Untitled`\ndate         | Date object created from `metadata.date` if set, unix epoch time if not\nrfc822date   | a rfc-822 formatted string made from `date`\nbody         | markdown source\nhtml         | parsed markdown as html\n\n\nA MarkdownPage is either a markdown file with metadata on top or a json file located in the contents directory.\n\n```markdown\n---\ntitle: My first post\ndate: 2012-12-12 12:12\nauthor: John Hjort \u003cfoo@bar.com\u003e\ntemplate: article.pug\n----\n\n# Hello friends!\n\nLife is wonderful, isn't it?\n\n```\n\nor use json to simply pass metadata to a template:\n\n```json\n{\n  \"template\": \"template.pug\",\n  \"stuff\": {\n  \t\"things\": 123,\n  \t\"moar\": [1, 2, 3]\n  }\n}\n```\n\nPages are by default rendered using the `template` view. This view passes the page to the template provided in the metadata. Omitting the template key or setting it to `none` will cause the page not to be rendered.\n\n### Links\n\nAll relative links in the markdown will be resolved correctly when rendering. This means you can just place *image.png* in the same directory and simply include it in your markdown as `![my image](image.png)`\n\nThis is especially convenient when using a markdown editor (read [Mou](http://mouapp.com/) if you're on a mac).\n\n### Metadata\n\nMetadata is parsed using [js-yaml](https://github.com/nodeca/js-yaml) and will be accessible in the template as `page.metadata`.\n\nThere are two special metadata keys, The first one is `template` which specifies what template to render the page with. If the key is omitted or set to `none` the page will not be rendered (but still available in the content tree).\n\nThe second one is `filename` which can be used to override the output filename of the page. See [filename templating](https://github.com/jnordberg/wintersmith/wiki/Page-Plugin#filename-templating) for advanced usage.\n\n### Templates\n\nWhen a page is rendered to a template the page instance is available as `page` in the template context. The content tree is also available as `contents` and `config.locals` is the root object.\n\n## Plugins\n\nA plugin is a function that's called with the wintersmith environment and a callback.\n\nPlugins are loaded by adding a \"require id\" to `config.plugins`. This can be a path, local- or global module.\nIt works just like you would expect a `require()` call to.\n\nPlugin example:\n\n```coffeescript\nfs = require 'fs'\n\nmodule.exports = (env, callback) -\u003e\n\n  class SimonSays extends env.ContentPlugin\n\n    constructor: (@filepath, text) -\u003e\n      @text = \"Simon says: #{ text }\"\n\n    getFilename: -\u003e @filepath.relative # relative to content directory\n\n    getView: -\u003e (env, locals, contents, templates, callback) -\u003e\n      callback null, new Buffer @text\n\n  SimonSays.fromFile = (filepath, callback) -\u003e\n    fs.readFile filepath.full, (error, buffer) -\u003e\n      if error\n        callback error\n      else\n        callback null, new SimonSays filepath, buffer.toString()\n\n  env.registerContentPlugin 'text', '**/*.txt', SimonSays\n  callback() # tell the plugin manager we are done\n```\n\nSee the [plugin guide][plugin-guide] for more info.\n\n## Using wintersmith programmatically\n\nexample:\n\n```javascript\n\nvar wintersmith = require('wintersmith');\n\n// create the sites environment, can also be called with a config object. e.g.\n// {contents: '/some/contents', locals: {powerLevel: 10}}, ..}\nvar env = wintersmith('/path/to/my/config.json');\n\n// build site\nenv.build(function(error) {\n  if (error) throw error;\n  console.log('Done!');\n});\n\n// preview\nenv.preview(function(error, server) {\n  if (error) throw error;\n  console.log('Server running!');\n});\n\n// do something with the content tree\nenv.load(function(error, result) {\n  if (error) throw error;\n  console.log('Contents loaded!');\n});\n\n```\n\nCheck the source or [api docs][docs] for a full list of methods.\n\n## Contributing\n\nTo run a development that compiles the coffee script files on the fly use the `./bin/dev/cli` command. The chdir `-C \u003cpath\u003e` flag is handy for pointing it to a test project to experiment with.\n\n## About\n\nWintersmith is written by [Johan Nordberg](http://johan-nordberg.com) using [CoffeeScript](http://coffeescript.org/) and licensed under the [MIT-license](http://en.wikipedia.org/wiki/MIT_License).\n\nThe name is a nod to [blacksmith](https://github.com/flatiron/blacksmith) which inspired this project.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjnordberg%2Fwintersmith","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjnordberg%2Fwintersmith","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjnordberg%2Fwintersmith/lists"}