静态方法创建静态map_如何使用Metalsmith创建静态站点

静态方法创建静态map

我以前的文章讨论了为什么应该不应该考虑使用静态网站生成器的原因。 总而言之,静态网站生成器会通过Markdown文件中通常包含的模板和原始数据来构建仅HTML页面文件。 它提供了CMS的一些优点,而没有托管,性能和安全性开销。

静态站点可能适用于一系列项目,包括:

  • 小型网站或个人博客。 最好是只有几十页,很少发帖,只有一两个作者的网站。
  • 技术文档,例如REST API。
  • 需要一系列网页视图的应用程序原型。
  • 电子书— Markdown文件可以转换为PDF或其他格式以及HTML。

本质上,静态站点生成器是构建工具。 您可以像使用GruntGulp一样使用它来运行任务或项目支架。

为什么选择金属匠?

毫无疑问,静态站点冠军是Jekyll,这是2008年启动的Ruby项目。使用Jekyll不一定需要Ruby专业知识,但它会有所帮助。 幸运的是,对于大多数流行的语言,有各种各样的开源静态站点生成器 。 JavaScript选项包括HexoHarpAssemble 。 您也可以使用诸如Gulp之类的构建工具来简化项目。

我选择本教程的Metalsmith是因为:

  1. 不针对特定项目类型,例如博客
  2. 支持多种模板和数据格式选项
  3. 轻巧
  4. 很少有依赖
  5. 使用模块化结构
  6. 提供了一个简单的插件架构,并且
  7. 很容易上手。

本教程已建立了一个演示网站 。 它不会赢得任何设计大奖,但可以说明基本概念。 可以从GitHub存储库中检查和安装Metalsmith构建代码。 或者,您可以按照此处的说明创建自己的基本站点。

我已经使用过Metalsmith两次,请不要以为这是构建每个静态站点的明确方法!

安装Metalsmith

确保已安装Node.js (例如, 使用nvm ),然后创建一个新的项目目录,例如project并初始化package.json文件:

cd project && cd project
npm init -y

现在安装Metalsmith和我们将用来构建站点的各种插件。 这些是:

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

项目结构

我们将在项目内的源( src )和构建( build )目录中使用以下结构。

您可以按照以下说明创建示例文件,也可以直接从demos src目录复制它们。

页数

页面Markdown文件包含在src/html 。 每个网站部分可以包含一个子目录级别,即

  • src/html/start —以特定顺序描述项目的页面
  • src/html/article —按相反的时间顺序排列的各种文章
  • src/html/contact —单个联系页面

每个目录都包含一个index.md文件,这是该部分的默认页面。 其他页面可以使用任何唯一名称。

构建过程会将这些文件转换为基于目录的永久链接,例如

  • src/html/start/index.md变成/start/index.html
  • src/html/start/installation.md变为/start/installation/index.html

每个Markdown文件在---标记之间的顶部提供称为“前题”的内容和元信息,例如

---
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.

大多数前端是可选的,但您可以设置:

  • priority :0(低)和1(高)之间的数字,我们将使用它来排序菜单和定义XML网站地图。
  • publish :可以设置为draftprivate或将来的日期,以确保直到需要时才发布。
  • date :文章的日期。 如果未设置,则将使用以后的任何发布日期或文件创建日期。
  • layout :要使用HTML模板。

范本

HTML页面模板包含在src/template 。 定义了两个模板:

  • src/html/template/page.html 默认布局
  • src/html/template/article.md一种文章布局,显示日期,下一个/后退链接等。

尽管支持其他选项,但仍使用Handlebars模板系统。 一个典型的模板需要一个{{{ contents }}}标签来包含页面内容以及诸如{{ title }}类的所有前值:

<!DOCTYPE html>
<html lang="en">
  <head>
    {{> meta }}
  </head>
  <body>

  {{> header }}

  <main>
    <article>

      {{#if title}}
        <h1>{{ title }}</h1>
      {{/if}}

      {{{ contents }}}

    </article>
  </main>

  {{> footer }}

</body>
</html>

{{> meta }}{{> header }}{{> footer }}引用是局部的…

部分

免费学习PHP!

全面介绍PHP和MySQL,从而实现服务器端编程的飞跃。

原价$ 11.95 您的完全免费

部分(或HTML片段文件)包含在src/partials 。 这些主要用于模板中,但也可以使用以下代码包含在内容页面中:

{{> partialname }}

其中, partialnamesrc/partials目录中文件的名称。

静态资产

静态资源(例如图像,CSS和JavaScript文件)包含在src/assets 。 所有文件和子目录将原样复制到网站的根目录。

自定义插件

建立站点所需的自定义插件包含在lib目录中。

建立目录

该网站将建立在build目录中。 我们将以两种方式构建站点:

  • 开发模式:不会缩小HTML并将启动测试Web服务器。
  • 生产模式:如果将NODE_ENV设置为production ,那么将擦除build目录并生成最终的最小文件。

定义您的第一个构建文件

可以在项目目录的根目录中创建一个名为build.js的基本示例:

// 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
    });

使用node ./build.js运行此node ./build.js ,将在build目录中创建一个静态站点。 Markdown将被解析为HTML,但是将无法使用,因为我们没有在构建过程中包含模板。

Metalsmith插件

从表面上看,Metalsmith构建文件看起来类似于Gulp中使用的文件(尽管它不使用流)。 通过use任何适当的参数将插件传递给Metalsmith use方法来调用插件。 插件本身必须返回另一个接受三个参数的函数:

  • 一个files数组,其中包含有关每个页面的信息
  • 包含全局信息(例如元数据)的metalsmith对象,以及
  • 插件完成工作后必须调用的done函数

这个简单的示例将所有元和页面信息记录到控制台(可以在build.js定义):

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();
  };
};

可以更新Metalsmith构建代码以使用此插件:

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
  });

该调试功能可以帮助您创建自己的自定义插件,但是您可能需要的大多数功能已经编写完毕-Metalsmith网站上的插件列表很长。

进行更好的构建

下面说明了演示站点构建文件的关键部分。

如果将NODE_ENV环境变量设置为production (在Mac / Linux上为export NODE_ENV=production或在Windows上为set NODE_ENV=production ), NODE_ENV名为devBuild的变量设置为true

devBuild = ((process.env.NODE_ENV || '').trim().toLowerCase() !== 'production')

主目录在dir对象中定义,因此我们可以重复使用它们:

dir = {
  base:   __dirname + '/',
  lib:    __dirname + '/lib/',
  source: './src/',
  dest:   './build/'
}

Metalsmith和插件模块已加载。 注意:

  • 仅在创建开发版本时才需要出色的Browsersync测试服务器
  • 通过引用HTML minifier模块htmlmin创建生产版本时,才需要
  • 定义了三个自定义插件: setdatemoremetadebug (下面有更详细的解释)
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,

用适用于每个页面的信息定义siteMeta对象。 重要值是domainrootpath ,它们是根据开发或生产版本设置的:

siteMeta = {
  devBuild: devBuild,
  version:  pkg.version,
  name:     'Static site',
  desc:     'A demonstration static site built using Metalsmith',
  author:   'Craig Buckler',
  contact:  'https://twitter.com/craigbuckler',
  domain:    devBuild ? 'http://127.0.0.1' : 'https://rawgit.com',            // set domain
  rootpath:  devBuild ? null  : '/sitepoint-editors/metalsmith-demo/master/build/' // set absolute path (null for relative)
}

还定义了templateConfig对象来设置模板默认值。 这将由metalsmith-in-place metalsmith-layouts插件和metalsmith-layouts插件一起使用,这些插件可使用Handlebars实现页内和模板渲染:

templateConfig = {
  engine:     'handlebars',
  directory:  dir.source + 'template/',
  partials:   dir.source + 'partials/',
  default:    'page.html'
}

Metalsmith对象现在像以前一样启动,但是我们还将siteMeta对象传递给metadata方法,以确保每个页面上的信息都可用。 因此,我们可以在任何页面中引用诸如{{ name }}项目来获取站点名称。

var ms = metalsmith(dir.base)
  .clean(!devBuild)               // clean build before a production build
  .source(dir.source + 'html/')   // source directory (src/html/)
  .destination(dir.dest)          // build directory (build/)
  .metadata(siteMeta)             // add meta data to every page

我们的第一个插件调用调用metalsmith-publish ,它将删除其前值publish值设置为draftprivate或将来日期的任何文件:

.use(publish())                    // draft, private, future-dated

setdatelib / metalsmith-setdate.js中包含的自定义插件。 通过在可能的情况下回退到publish日期或文件创建时间,即使在开头没有定义任何文件,它也可以确保为每个文件设置一个“日期”值:

.use(setdate())                    // set date on every page if not set in front-matter

metalsmith-collections是最重要的插件之一,因为它根据页面在源目录中的位置或其他因素将每个页面分配到类别或分类法。 它可以使用datepriority等最重要的内容对文件重新排序,并允许您为该集合设置自定义元数据。 该代码定义:

  • src/html/start目录中每个文件的启动集合。 它按照文件前部设置的priority值对它们进行排序。
  • src/html/article目录中每个文件的文章集合。 它按date按相反的时间顺序排序
  • 每个名为index.*默认页面的页面集合。 它按照文件前部设置的priority值对它们进行排序。
.use(collections({                  // determine page collection/taxonomy
   page: {
     pattern:    '**/index.*',
     sortBy:     'priority',
     reverse:    true,
     refer:      false
   },
   start: {
     pattern:    'start/**/*',
     sortBy:     'priority',
     reverse:    true,
     refer:      true,
     metadata: {
       layout:   'article.html'
     }
   },
   article: {
     pattern:    'article/**/*',
     sortBy:     'date',
     reverse:    true,
     refer:      true,
     limit:      50,
     metadata: {
       layout:   'article.html'
     }
   }
 }))

接下来是Markdown到HTML的转换,接着是metalsmith-permalinks插件,该插件定义了构建的目录结构。 注意:mainCollection是通过下面的moremeta为每个文件设置的:

.use(markdown())                        // convert Markdown
 .use(permalinks({                       // generate permalinks
   pattern: ':mainCollection/:title'
 }))

metalsmith-word-count计数文章中的单词数,并计算大约需要花费多长时间。 参数{ raw: true }仅输出数字:

.use(wordcount({ raw: true }))          // word count

moremetalib / metalsmith-moremeta.js中包含的另一个自定义插件。 它将其他元数据附加到每个文件:

  • root :到根目录的绝对或计算的相对文件路径
  • isPage :为名为index.*默认节页面设置true index.*
  • mainCollection :主要集合名称, startarticle
  • layout :如果未设置,则可以从主集合的元数据中确定布局模板
  • navmain :顶级导航对象的数组
  • navsub :二级导航对象的数组

插件代码相对复杂,因为它可以处理导航。 如果您需要更简单的层次结构,则可以使用更简单的选项。

.use(moremeta())                          // determine root paths and navigation

metalsmith-in-placemetalsmith-layouts插件分别控制页面内和模板布局。 传递了上面定义的相同templateConfig对象:

.use(inplace(templateConfig))             // in-page templating
.use(layouts(templateConfig));            // layout templating

如果设置了htmlmin (在生产版本中),我们可以缩小HTML:

if (htmlmin) ms.use(htmlmin());           // minify production HTML

debuglib / metalsmith-debug.js中包含的最后一个自定义插件。 它类似于上述debug功能:

if (debug) ms.use(debug());               // output page debugging information

Browsersync测试服务器已启动,因此我们可以测试开发版本。 如果您从未使用过它,那么它看起来就像是魔术:每次进行更改时,站点都会神奇地刷新,并且在您滚动或浏览站点时,两个或多个浏览器中的视图将同步:

if (browsersync) ms.use(browsersync({     // start test server
  server: dir.dest,
  files:  [dir.source + '**/*']
}));

最后,我们可以使用:

  • metalsmith-mapsite生成XML网站地图
  • metalsmith-feed生成RSS提要,其中包含文章集中的页面
  • metalsmith-assets直接从src/assets复制文件和目录以进行build而无需修改。
ms
  .use(sitemap({                          // generate sitemap.xml
    hostname:     siteMeta.domain + (siteMeta.rootpath || ''),
    omitIndex:    true
  }))
  .use(rssfeed({                          // generate RSS feed for articles
    collection:   'article',
    site_url:     siteMeta.domain + (siteMeta.rootpath || ''),
    title:        siteMeta.name,
    description:  siteMeta.desc
  }))
  .use(assets({                            // copy assets: CSS, images etc.
    source:       dir.source + 'assets/',
    destination:  './'
  }))

剩下的就是创建站点的最后一个.build()步骤:

.build(function(err) {                   // build
   if (err) throw err;
 });

完成后,您可以运行node ./build.js再次构建您的静态站点。

陷阱

我在建立一个简单的Metalsmith网站方面学到了很多,但是要注意以下问题:

不兼容的插件

插件可能会与其他人冲突。 例如,计算相对根路径的metalsmith-rootpath与创建自定义构建目录结构的metalsmith-permalinks不能很好地配合。 我通过在lib / metalsmith-moremeta.js插件中编写自定义root路径计算代码来解决此问题。

插件顺序至关重要

如果放置顺序错误,插件可能会相互依赖或冲突。 例如,必须在metalsmith布局之后调用生成RSS的metalsmith-feed插件,以确保不会在页面模板内生成RSS XML。

Browsersync重建问题

在运行Browsersync并编辑文件时,将重新解析集合,但似乎保留了旧数据。 自定义的lib / metalsmith-moremeta.js插件可能是一个问题,但菜单和next / back链接却失去了同步性。 要解决此问题,请使用Ctrl / Cmd + C停止构建,然后重新启动构建。

您还需要吞咽吗?

使用Gulp等任务管理器的人会注意到Metalsmith提供了熟悉的构建过程。 有一些用于CSS预处理的插件, 包括Sass图像缩小文件串联uglification等。 对于简单的工作流程可能就足够了。

但是,Gulp拥有范围更广的插件,并允许使用自动前缀对linting ,部署和PostCSS处理等复杂的构建活动。 有几个Gulp / Metalsmith集成插件,尽管我遇到了几个问题,但它们不是必需的,因为Gulp任务可以直接运行Metalsmith,例如

var
  gulp       = require('gulp'),
  metalsmith = require('metalsmith'),
  publish    = require('metalsmith-publish'),
  markdown   = require('metalsmith-markdown');

// build HTML files using Metalsmith
gulp.task('html', function() {

  var ms = metalsmith(dir.base)
    .clean(false)
    .source('src/html/')
    .destination('build')
    .use(publish())
    .use(markdown())
    .build(function(err) {
      if (err) throw err;
    });

});

此过程可防止上面提到的Browsersync重建问题。 请记住使用.clean(false)以确保Metalsmith在其他任务处于活动状态时从不擦除build文件夹。

Metalsmith适合您吗?

如果您有简单或高度定制的网站要求,Metalsmith是理想的选择。 也许尝试使用一个文档项目并一次添加一个功能。 Metalsmith的功能不如Jekyll这样的替代品完整,但并非如此。 您可能必须编写自己的插件,但是这样做的简便性对JavaScript开发人员来说是巨大的好处。

创建Metalsmith构建系统需要花费时间,我们还没有考虑HTML模板和部署中涉及的工作。 但是,一旦有了工作流程,添加,编辑和删除Markdown文件就变得非常简单。 它比使用CMS更容易,并且您拥有静态站点的所有好处

翻译自: https://www.sitepoint.com/create-static-site-metalsmith/

静态方法创建静态map

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值