npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

metalsmith-taxonomy

v0.6.0

Published

Metalsmith plugin that organizes files into taxonomy trees in global metadata and auto-generates taxonomy page objects

Downloads

12

Readme

Metalsmith taxonomy

Metalsmith plugin that organizes files into taxonomy trees in global metadata and auto-generates taxonomy page objects.

metalsmith: plugin npm: version ci: build code coverage license: LGPL-3.0

Features

  • can pre-filter files by pattern
  • adds taxonomies tree to global metadata
  • supports multiple taxonomy namespaces (e.g. blog, products, etc.)
  • works well in combination with metalsmith-filemetadata, collections and permalinks
  • automatically generates overview, taxonomy & taxonomy term pages (e.g. taxonomies > categories > category)

Install

NPM:

npm i -D metalsmith-taxonomy

Yarn:

yarn add metalsmith-taxonomy

Usage

Quickstart

Simplest usage without parameters or with default parameters (all examples below yield the same results).

var default_taxonomy_set = {
  pattern: '**/*.{md,html}',
  namespace: null,
  pages: ['index', 'taxonomy', 'term'],
  taxonomies: ['tags', 'category']
};

metalsmith.use(taxonomy());

// is the same as
metalsmith.use(taxonomy(default_taxonomy_set));

// or the same as
metalsmith.use(taxonomy([default_taxonomy_set]);

Options

Pass one or more taxonomy sets to the plugin. A taxonomy set is an object with the following properties:

| Property | Type | Default | Description | | :----------- | :-------------- | :-------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | pattern | string\|array | **/*.{md,html} | One or more glob patterns supported by multimatch. | | namespace | string | null | Subkey in metadata.taxonomies[namespace] in which the taxonomy tree of this set will be stored. | | pages | boolean | true | If true, a taxonomy set index page, pages for each taxonomy in the set, and each term of each taxonomy in the set will be generated. If false, no pages will be generated. | | | array | | An array with one or more of: index, taxonomy, term allows limiting the type of pages generated. | | taxonomies | array | ['category','tags'] | An array containing all file metadata keys to use as taxonomies | | | Object | | Passing an object allows more flexibility in mapping taxonomy terms and values. The object's keys will become the taxonomy names, and its values will match metadata file keys. The file metadata key can also be a keypath (e.g. meta.keywords), and the file metadata value can also be an array. |

Global metadata

If you had two files with the following content:

The Quickstart example will generate the following results in global metadata:

  {
    ...metadata,
    taxonomies: {
      tags: {
        tag1: [article1],
        tag2: [article1, article2]
      },
      category: {
        category1: [article1],
        category2: [article2]
      }
    }
  }

Auto-generated index, taxonomy, and term pages

If the pages property of a taxonomy set is not an empty array, or false, metalsmith-taxonomy will auto-generate pages at the following paths:

| Page type | Path | Example | | :--------- | :-------------------------------- | :---------------------------- | | index | :namespace.html | blog.html | | taxonomy | :namespace/:taxonomy.html | blog/category.html | | term | :namespace/:taxonomy/:term.html | blog/category/metalsmith.html |

If namespace is not defined, the index page path will default to index.html.

With the Quickstart example, metalsmith-taxonomy will generate:

{
  'index.html',
  'category.html',
  'category/category1.html',
  'category/category2.html',
  'tags.html',
  'tags/tag1.html',
  'tags/tag2.html',
  ...other_files
};

Generated file objects get the following metadata:

Index page metadata

| Property | Type | Description | | :----------- | :----------------- | :------------------------------------------------------------------------------------------------------ | | type | 'taxonomy:index' | Page type | | path | string | Destination path of the page | | namespace | null\|string | Namespace passed in taxonomy set | | taxonomies | object | Copy of the object at metadata.taxonomies[namespace] (or metadata.taxonomies if namespace===null) | | contents | string | Empty string |

Taxonomy page metadata

| Property | Type | Description | | :----------- | :-------------------- | :------------------------------------------------------------------------------------------------------ | | type | 'taxonomy:taxonomy' | Page type | | path | string | Destination path of the page | | namespace | null\|string | Namespace passed in taxonomy set | | taxonomy | string | Name of the current taxonomy | | terms | array | Array with the terms found for the current taxonomy | | taxonomies | object | Copy of the object at metadata.taxonomies[namespace] (or metadata.taxonomies if namespace===null) | | contents | string | Empty string |

Term page metadata

| Property | Type | Description | | :----------- | :---------------- | :------------------------------------------------------------------------------------------------------ | | type | 'taxonomy:term' | Page type | | path | string | Destination path of the page | | namespace | null\|string | Namespace passed in taxonomy set | | taxonomy | string | Name of the current taxonomy | | terms | array | Array with the terms found for the current taxonomy | | taxonomies | object | Copy of the object at metadata.taxonomies[namespace] (or metadata.taxonomies if namespace===null) | | contents | string | Empty string |

Adding extra metadata to the generated pages

If a file already exists at the target path of a generated page, the generated metadata will be merged into the existing metadata of that file. Extra metadata can also be added with plugins like metalsmith-filemetadata further in the plugin chain.

Sorting the term matches

By default, the files will be sorted as they are read from the filesystem (alphabetically by file name).

The data available to metadata is a reference to the items under taxonomies[namespace][taxonomy][term], so you could use metalsmith-keymaster or a custom plugin to sort the data:

metalsmith.use(taxonomy).use(function (files, metalsmith) {
  var taxonomies = metalsmith.metadata().taxonomies;

  Object.keys(taxonomies.tags).forEach(function (tagName) {
    taxonomies.tags[tagName].sort(function (a, b) {
      return a.order < b.order ? -1 : a.order > b.order ? 1 : 0;
    });
  });
});

The example above shows how to sort all term collections under the tag taxonomy by an order property defined in each file's metadata.

Custom metadata & rendering with metalsmith-layouts/filemetadata/default-values

You can use metalsmith-filemetadata to add custom data to the generated file objects by pattern, e.g. to specify a layout property to be used later in the chain by metalsmith-layouts.

var taxonomy = require('metalsmith-taxonomy')({
  namespace: 'taxonomies',
  taxonomies: ['category', 'tags']
});

var filemetadata = require('metalsmith-filemetadata')([
  {
    pattern: 'taxonomies/**/*.html',
    metadata: { layout: 'taxonomy-term.hbs' }
  },
  {
    pattern: 'taxonomies/*.html',
    metadata: { layout: 'taxonomy.hbs' }
  },
  {
    pattern: 'taxonomies.html',
    metadata: { layout: 'taxonomy-index.hbs' }
  }
]);

var layouts = require('metalsmith-layouts')({
  directory: 'src/layouts',
  default: 'default.hbs',
  pattern: '**/*.{md,html}'
});

metalsmith.use(taxonomy).use(filemetadata).use(layouts);

metalsmith-default-values works exactly the same as above.

Custom or nested page paths with metalsmith-permalinks

You can use metalsmith-permalinks to move or nest taxonomy pages:

var taxonomy = require('metalsmith-taxonomy')({
  pages: ['index', 'taxonomy', 'term'],
  taxonomies: ['category', 'tags']
});

var collections = require('metalsmith-collections')({
  posts: 'posts/**/*.md'
});

var permalinks = {
  linksets: [
    {
      match: { collection: 'posts' },
      pattern: 'posts/:category/:title'
    },
    {
      match: { type: 'taxonomy:index' },
      pattern: 'posts'
    },
    {
      match: { type: 'taxonomy:term', taxonomy: 'category', namespace: 'blog' },
      pattern: 'posts/:category'
    },
    {
      match: { type: 'taxonomy:taxonomy' },
      pattern: 'posts/:taxonomy'
    },
    {
      match: { type: 'taxonomy:term', namespace: 'blog' },
      pattern: 'posts/:category'
    }
  ]
};

metalsmith.use(taxonomy).use(collections).use(permalinks);

with the example files from Global metadata would result in a directory tree like:

└── posts
    ├── index.html --> index page
    ├── tags
    |    ├── index.html --> taxonomy page
    |    ├── tag1
    |    |    └── index.html --> term page
    |    └── tag2
    |         └── index.html --> term page
    ├── category
    |    └── index.html --> taxonomy page
    ├── category1
    |    ├── index.html --> term page
    |    └── article-1
    |         └── index.html
    └── category2
         ├── index.html --> term page
         └── article-2
              └── index.html

Examples

Clone this repository and navigate to the example/licenses or more advanced example/blog directory, run npm install & npm start.

License

LGPL v0.3