Home >Web Front-end >JS Tutorial >How to Create a Static Site with Metalsmith
The previous article discussed the reasons for whether to use a static website generator. In short, static website generators build page files that contain only HTML from templates and raw data (usually included in Markdown files). It offers some CMS benefits without the overhead of hosting, performance and security.
Static websites may be suitable for a variety of projects, including:
Essentially, a static website generator is a building tool. You can use it to run tasks or project scaffolding like you would with Grunt or Gulp.
The undisputed static website champion is Jekyll – a Ruby project launched in 2008. You don't necessarily need Ruby expertise to use Jekyll, but that will help. Fortunately, most popular languages have a wide variety of open source static website generators. JavaScript options include Hexo, Harp, and Assemble. For simpler projects, you can also use build tools like Gulp.
I chose Metalsmith for this tutorial because it:
This tutorial has built a demo website. It won't win any design awards, but it illustrates the basic concept. Metalsmith build code can be checked and installed from the GitHub repository. Alternatively, you can follow the instructions here and create your own basic site.
I've used Metalsmith a few times-please don't think this is the ultimate way to build every static website!
Make sure you have Node.js installed (for example using nvm), then create a new project directory, such as project and initialize your package.json file:
<code>cd project && cd project npm init -y </code>
Install Metalsmith now and the various plugins we will use to build the site. These are:
<code>npm install --save-dev metalsmith metalsmith-assets metalsmith-browser-sync metalsmith-collections metalsmith-feed metalsmith-html-minifier metalsmith-in-place metalsmith-layouts metalsmith-mapsite metalsmith-markdown metalsmith-permalinks metalsmith-publish metalsmith-word-count handlebars </code>
We will use the following structure as the source (src) and build (build) directory in our project.
You can create sample files as follows, or copy them directly from the demo src directory.
Page Markdown file is included in src/html. This can contain a first-level subdirectory for each website section, i.e.
Each directory contains an index.md file, which is the default page for that section. Other pages can use any unique name.
The build process converts these files into directory-based permalinks, such as
Each Markdown file provides content and meta information, called "preface" is located at the top between -- marks, e.g.
<code>--- title: My page title description: A description of this page. layout: page.html priority: 0.9 date: 2016-04-19 publish: draft --- This is a demonstration page. ## Example title Body text.</code>
Most preface questions are optional, but you can set:
HTML page template is included in src/template. Two templates have been defined:
Although other options are supported, the Handlebars template system is used. A typical template requires a {{{ contents }}} tag to contain the page content and any preface values, such as {{ title }}:
<code>cd project && cd project npm init -y </code>
The references to {{> meta }}, {{> header }} and {{> footer }} are partially...
section—or the HTML snippet file—is contained in src/partials. These are mainly used in templates, but can also be included in the content page using the following code:
<code>npm install --save-dev metalsmith metalsmith-assets metalsmith-browser-sync metalsmith-collections metalsmith-feed metalsmith-html-minifier metalsmith-in-place metalsmith-layouts metalsmith-mapsite metalsmith-markdown metalsmith-permalinks metalsmith-publish metalsmith-word-count handlebars </code>
where partialname is the name of the file in the src/partials directory.
Static assets (such as images, CSS, and JavaScript files) are included in src/assets. All files and subdirectories will be copied as is to the root of the website.
The custom plugins required to build the site are included in the lib directory.
The website will be built in the build directory. We will build the website in two ways:
You can create a basic example called build.js in the root directory of the project directory:
<code>--- title: My page title description: A description of this page. layout: page.html priority: 0.9 date: 2016-04-19 publish: draft --- This is a demonstration page. ## Example title Body text.</code>
Run it with node ./build.js and a static website will be created in the build directory. Markdown will be parsed as HTML, but it is not available because we did not include the template during the build process.
On the surface, the Metalsmith build file looks similar to the one used in Gulp (although it does not use streams). Call the plugin by passing it to the Metalsmith use method using any appropriate arguments. The plugin itself must return another function, which accepts three parameters:
This simple example logs all metadata and page information to the console (it can be defined in build.js):
<code> lang="en"> > {{> meta }} > > {{> header }} <main>></main> > {{#if title}} <h1>></h1>{{ title }}> {{/if}} {{{ contents }}} > > {{> footer }} > > </code>
Metalsmith build code can be updated to use this plugin:
<code>{{> partialname }}</code>
This debugging function can help you create your own custom plugins, but most of the features you may need are already written – there is a long list of plugins on the Metalsmith website.
The main parts of the demo site build file are explained below.
If the NODE_ENV environment variable is set to production (export NODE_ENV=production on Mac/Linux or NODE_ENV=production on Windows), the variable devBuild will be set to true:
<code>cd project && cd project npm init -y </code>
Home directory is defined in the dir object so that we can reuse them:
<code>npm install --save-dev metalsmith metalsmith-assets metalsmith-browser-sync metalsmith-collections metalsmith-feed metalsmith-html-minifier metalsmith-in-place metalsmith-layouts metalsmith-mapsite metalsmith-markdown metalsmith-permalinks metalsmith-publish metalsmith-word-count handlebars </code>
Load Metalsmith and plug-in modules. Note:
<code>--- title: My page title description: A description of this page. layout: page.html priority: 0.9 date: 2016-04-19 publish: draft --- This is a demonstration page. ## Example title Body text.</code>
siteMeta object is defined using information applied to each page. Important values are domain and rootpath, which are set based on development or production build:
<code> lang="en"> > {{> meta }} > > {{> header }} <main>></main> > {{#if title}} <h1>></h1>{{ title }}> {{/if}} {{{ contents }}} > > {{> footer }} > > </code>
also defines a templateConfig object to set the template default values. This will be used by the metalsmith-in-place and metalsmith-layouts plugins, which enable in-page and template rendering using Handlebars:
<code>{{> partialname }}</code>The
Metalsmith object is now initialized as before, but we also pass the siteMeta object to the metadata method to ensure that this information is available for each page. So we can refer to items like {{ name }} in any page to get the site name.
<code>// basic build 'use strict'; var metalsmith = require('metalsmith'), markdown = require('metalsmith-markdown'), ms = metalsmith(__dirname) // the working directory .clean(true) // clean the build directory .source('src/html/') // the page source directory .destination('build/') // the destination directory .use(markdown()) // convert markdown to HTML .build(function(err) { // build the site if (err) throw err; // and throw errors }); </code>
Our first plugin call metalsmith-publish, which removes any file whose preface publish value is set to draft, private, or future date:
<code>function debug(logToConsole) { return function(files, metalsmith, done) { if (logToConsole) { console.log('\nMETADATA:'); console.log(metalsmith.metadata()); for (var f in files) { console.log('\nFILE:'); console.log(files[f]); } } done(); }; }; </code>
setdate is a custom plugin included in lib/metalsmith-setdate.js. It ensures that each file has a "date" value set, and even if no value is defined in the previous question, it can be achieved by falling back to the release date or file creation time as much as possible:
<code>ms = metalsmith(__dirname) // the working directory .clean(true) // clean the build directory .source('src/html/') // the page source directory .destination('build/') // the destination directory .use(markdown()) // convert Markdown to HTML .use(debug(true)) // *** NEW *** output debug information .build(function(err) { // build the site if (err) throw err; // and throw errors }); </code>
metalsmith-collections is one of the most important plugins because it assigns each page to a category or taxonomy based on its location or other factors in the source directory. It can reorder files using prefaces such as dates or priorities and allows you to set custom metadata for the collection. Code definition:
<code>devBuild = ((process.env.NODE_ENV || '').trim().toLowerCase() !== 'production') </code>
The next is the Markdown to HTML conversion, followed by the metalsmith-permalinks plugin, which defines the directory structure for the build. Please note that moremeta sets :mainCollection for each file below:
<code>dir = { base: __dirname + '/', lib: __dirname + '/lib/', source: './src/', dest: './build/' } </code>
metalsmith-word-count Calculates the number of words in an article and calculates how long it takes to read it. Parameter { raw: true } Output only numbers:
<code>metalsmith = require('metalsmith'), markdown = require('metalsmith-markdown'), publish = require('metalsmith-publish'), wordcount = require("metalsmith-word-count"), collections = require('metalsmith-collections'), permalinks = require('metalsmith-permalinks'), inplace = require('metalsmith-in-place'), layouts = require('metalsmith-layouts'), sitemap = require('metalsmith-mapsite'), rssfeed = require('metalsmith-feed'), assets = require('metalsmith-assets'), htmlmin = devBuild ? null : require('metalsmith-html-minifier'), browsersync = devBuild ? require('metalsmith-browser-sync') : null, // custom plugins setdate = require(dir.lib + 'metalsmith-setdate'), moremeta = require(dir.lib + 'metalsmith-moremeta'), debug = consoleLog ? require(dir.lib + 'metalsmith-debug') : null, </code>
moremeta is another custom plugin included in lib/metalsmith-moremeta.js. It attaches other metadata to each file:
<code>cd project && cd project npm init -y </code>The metalsmith-in-place and metalsmith-layouts plugins control the in-page and template layout respectively. Pass the same templateConfig object as defined above:
<code>npm install --save-dev metalsmith metalsmith-assets metalsmith-browser-sync metalsmith-collections metalsmith-feed metalsmith-html-minifier metalsmith-in-place metalsmith-layouts metalsmith-mapsite metalsmith-markdown metalsmith-permalinks metalsmith-publish metalsmith-word-count handlebars </code>If htmlmin is set (in production build), we can compress HTML:
<code>--- title: My page title description: A description of this page. layout: page.html priority: 0.9 date: 2016-04-19 publish: draft --- This is a demonstration page. ## Example title Body text.</code>debug is the final custom plugin included in lib/metalsmith-debug.js. It is similar to the debug function described above:
<code> lang="en"> > {{> meta }} > > {{> header }} <main>></main> > {{#if title}} <h1>></h1>{{ title }}> {{/if}} {{{ contents }}} > > {{> footer }} > > </code>Start the Browsersync test server so that we can test the development build. If you haven't used it before, it looks like magic: every time you make a change, your website will magically refresh, and when you scroll or browse the website, the views in two or more browsers will Synchronization:
<code>{{> partialname }}</code>Lastly, we can use:
<code>// basic build 'use strict'; var metalsmith = require('metalsmith'), markdown = require('metalsmith-markdown'), ms = metalsmith(__dirname) // the working directory .clean(true) // clean the build directory .source('src/html/') // the page source directory .destination('build/') // the destination directory .use(markdown()) // convert markdown to HTML .build(function(err) { // build the site if (err) throw err; // and throw errors }); </code>The rest is the last .build() step to create the website:
<code>function debug(logToConsole) { return function(files, metalsmith, done) { if (logToConsole) { console.log('\nMETADATA:'); console.log(metalsmith.metadata()); for (var f in files) { console.log('\nFILE:'); console.log(files[f]); } } done(); }; }; </code>When you are done, you can run node ./build.js again to build your static website.
What to pay attention to
Incompatible plug-ins
Plugin order is crucial
Browsersync rebuild issue
People using task managers such as Gulp will notice that Metalsmith provides a familiar build process. There are plug-ins for CSS preprocessing, image compression, file connection, vilification and more with Sass. For a simpler process, it might be enough.
However, Gulp has a wider range of plugins and allows for complex build activities such as lint, deployment, and PostCSS processing using auto-prefixer. There are some Gulp/Metalsmith integration plugins, although I have some problems and they should not be necessary because Gulp tasks can run Metalsmith directly, e.g.
<code>cd project && cd project npm init -y </code>
This process prevents the Browsersync rebuild problem mentioned above. Remember to use .clean(false) to ensure that Metalsmith never clears the build folder when other tasks are active.
Metalsmith is ideal if you have simple or highly customized website needs. Maybe try using a document project and add one feature at a time. Metalsmith isn't as fully functional as alternatives like Jekyll, but it's not designed to be that way. You may need to write your own plugin, but it's easy to do so, which is a huge benefit for JavaScript developers.
Creating a Metalsmith build system takes time, and we haven't considered the amount of work involved in HTML templates and deployment. However, once you have a process available, adding, editing, and deleting Markdown files becomes very simple. It may be easier than using CMS, and you have all the benefits of a static website.
Metalsmith is a simple and easy-to-use pluggable static website generator. It is based on Node.js and uses a modular structure that allows you to add functionality as needed through plugins. This makes it incredible flexibility and customizability. You should use Metalsmith to create a static website because it allows you to build your website exactly as you wish without being restricted by traditional CMS. In addition, static websites are faster, safer, and easier to maintain than dynamic websites.
To install Metalsmith, you need to install Node.js and npm on your computer. After installing these, you can install Metalsmith by running the command npm install metalsmith in the terminal. This will install Metalsmith and all its dependencies.
To create a new Metalsmith project, first navigate in the terminal to the directory where you want to create the project. Then, run the command metalsmith to create a new project. This will create a new directory with the name of your project, and within this directory it will create a basic structure for your static website.
To add plugins to your Metalsmith project, you need to install them via npm and then reference them in your Metalsmith configuration file. For example, to add the markdown plugin, you first need to run npm install metalsmith-markdown, and then in your configuration file, you need to add var markdown = require('metalsmith-markdown'); and add .use(markdown()) Go to your Metalsmith build chain.
To build your Metalsmith website, you need to run the command metalsmith build in the terminal. This compiles all the files and outputs them to the build directory, which you can then deploy to your server.
To customize the layout of your Metalsmith website, you can use template engines such as Handlebars or Jade. These allow you to create reusable templates for different parts of your website, such as headers, footers, and individual pages.
To add content to your Metalsmith website, you can create a markdown file in the source directory. When building a website, these files are converted to HTML. You can also use CMS such as Netlify CMS to manage your content.
To deploy your Metalsmith website, you can use services such as Netlify or GitHub Pages. These services will host your static website and automatically deploy changes when you push to the repository.
To update your Metalsmith website, you simply change the source file and rebuild your website. Changes will be reflected in the build directory, which you can then deploy to your server.
Yes, Metalsmith is highly scalable and can be used for large and complex websites. Its modular structure allows you to add functionality as needed, and its use of static files means it can handle a lot of content without slowing down.
The above is the detailed content of How to Create a Static Site with Metalsmith. For more information, please follow other related articles on the PHP Chinese website!