metalsmith-simple-search

metalsmith-simple-search

Include a static site search based on the contents of your published website. Based off Simple Jekyll Search but made for Metalsmith.

Metalsmith Simple Search

This makes it really easy to add Simple Jekyll Search to your Metalsmith project. Simply run all of your files through this plugin and it will generate your search.json file.

Installation

npm can do this for you.

npm install --save metalsmith-simple-search

Usage

Metadata properties are copied to the resulting JSON objects, optionally passing through filters. First, this is an example that shows the default options in the JSON format. You do not need to specify any of these unless you want to override the default.

{
    "plugins": {
        "metalsmith-simple-search": {
            "destinationJs": "simple-search.min.js",
            "destinationJson": "index.json",
            "index": {
                "title": true,
                "keywords": true,
                "contents": "html"
            },
            "match": "**/*.{htm,html}",
            "matchOptions": {},
            "skipSearchJs": false
        }
    }
}

This is how you would use it in JavaScript. Again, these are the defaults and don't need to be specified unless you want to override what they do.

// Load the plugin
var simpleSearch = require("metalsmith-simple-search");

// Use this in your list of plugins.
.use(simpleSearch())

// Alternately, you can specify options. The values shown here are the
// defaults and can be overridden.
use(simpleSearch({
    // Where to save the file that performs the JavaScript-based searches
    // in a browser. Disable with the `skipSearchJs` setting.
    destinationJs: "simple-search.min.js",

    // Where to save the resulting JSON file that contains search words.
    destinationJson: "search.json",

    // Metadata fields to index and how to index them. A lengthier
    // description follows after the example.
    index: {
        title: true,
        keywords: true
        contents: "html"
    },

    // Pattern of files to match so only some files are placed into the
    // search index.
    match: "**/*.{htm,html}",

    // Options for matching files. See metalsmith-plugin-kit.
    matchOptions: {},

    // If true, do not write the `destinationJs` to the output files.
    // When switching this on, make sure the "simple-search.min.js" file
    // is somehow included in your build.
    skipSearchJs: false,

    // Transform the filename into a URL for the search engine. The
    // result from this file is saved as the ".url" property in the
    // per-file search object.
    transformUrl: function (filename) {
        return "/" + filename;
    }
}));

This uses [metalsmith-plugin-kit] for matching files. It documents the options that can be used to control how files are matched.

The index property will determine how a particular file's metadata is indexed. It can be set to one of several values.

  • false or null - Do not index this property. Great for overriding defaults.
  • true - Index this property. If the value is an object, call .toString() on it first. If the value is an array, join with " ". Once it is a text string, index this as-is.
  • "html" - Convert the value to a string then remove all HTML tags and unescape any escaped content. This means <div class="xyz">text</div> turns into text (HTML elements removed). The HTML is scanned for changed to lowercase, made into a list of keywords and duplicates are removed.
  • "markdown" or "md" - Assume the value is markdown and remove some non-text markup. The markdown is changed to lowercase, made into a list of keywords and duplicates are removed.
  • "keywords" - Change the text into lowercase, make it into a list of keywords and remove duplicates.
  • outStr = function (inStr) - A custom function of your own that will take the string value of this metadata and convert it into a cleansed version.

You need to also use the browser/jekyll-search.js or browser/jekyll-search.min.js in the browser and configure it. Those files are included in this repository. To configure it you will need to execute some JavaScript on page load. Please see the Simple Jekyll Search site or the browser/README.md file for great instructions on how to finish setting this up.

The only reason the browser/ files exist in this repository is because the jekyll-simple-search npm module pulls in far too many dependencies (like gulp) during installation. I only want one build system, please.

Full API

metalsmith-simple-search

Metalsmith Simple Search plugin to allow client-side searching of a site.

Uses the JavaScript from a similar project that lets you search Jekyll sites as the driver behind the searching.

See: https://github.com/christian-fei/Simple-Jekyll-Search
Example

var simpleSearch = require("metalsmith-simple-search");

// Create your metalsmith instace. When that is done, add the middleware
// like this.
metalsmith.use(simpleSearch({
    // configuration here
}));

module.exports(options) ⇒ function

The Simple Search factory.

Kind: Exported function
Returns: function - middleware
Params

Example

var simpleSearch = require("metalsmith-simple-search");

// Make the metalsmith instance, then at the appropriate time, add this
// line.
metalsmith.use(simpleSearch({
    // options go here
}));

module.exports.makeKeywords(str) ⇒ string

Converts one big string into a space separated list of keywords.

All keywords are converted to lowercase, are cleaned up a bit and are deduplicated.

Kind: static method of module.exports
Params

  • str string

Example

console.log(simpleSearch.makeKeywords("One two THREE"));
// "one three two"

Example

console.log(simpleSearch.makeKeywords("Hi! ONE*two, pro- and ani- (whatever)"));
// "and anti hi one pro two whatever"

module.exports.stripHtml(str) ⇒ string

Remove HTML from some text. Adds a space wherever a tag was found. Multiple spaces together are condensed into one and the resulting string is also trimmed.

Kind: static method of module.exports
Params

  • str string

Example

console.log(simpleSearch.stripHtml("<p>Paragraph</p>");
// "Paragraph"

Example

console.log(simpleSearch.stripHtml("<div>This <i>is</i> <b>bold</b>.</div><div>hi</div>"));
// "This is bold . hi"

Example

console.log(simpleSearch.stripHtml("Arrow --&gt;"));
// "Arrow -->"

module.exports.stripMarkdown(str) ⇒ string

Remove markdown from some text. This does not convert Markdown. Instead, the goal is to only remove links from the text so the URLs don't get indexed.

Kind: static method of module.exports
Params

  • str string

Example

console.log(simpleSearch.stripMarkdown("a [link](example.com)"));
// "a link"

Example

console.log(simpleSearch.stripMarkdown("[link]: example.com"));
// ""

module.exports~buildSearchData(file, filename, options) ⇒ searchData

Creates the metadata for a single file object.

The options passed may have altered options.index values. Only booleans and functions are supported. Strings were converted into functions in the factory middleware.

Kind: inner method of module.exports
Returns: searchData - search data
Params

Example

result = {};
Object.keys(files).forEach((filename) => {
    result[filename] = buildSearchData(files[filename], filename, options);
});

module.exports~metalsmithFile : Object

Metalsmith's file object.

Kind: inner typedef of module.exports
Properties

Name Type
contents Buffer
mode string

module.exportsmetalsmithFileCollection : Object.<string, module:metalsmith-simple-search--module.exportsmetalsmithFile>

Metalsmith's collection of files.

Kind: inner typedef of module.exports

module.exports~searchData : Object.<string, string>

Data used for searching for a single file.

Kind: inner typedef of module.exports
Properties

Name Type Description
url string Associated URL in case the search finds something.

module.exports~options : Object

The options for the plugin.

Kind: inner typedef of module.exports
See: https://github.com/fidian/metalsmith-plugin-kit
Properties

Name Type Default Description
destinationJson string "search.json" The location of the final JSON document.
destinationJs string "simple-search.min.js" Where to add the associated JavaScript file.
index Object {title:true,keywords:true,contents:"html"} Fields to index for searching.
match module:metalsmith-plugin-kit~matchList Files to match, defaults to *.htm and *.html anywhere.
matchOptions module:metalsmith-plugin-kit~matchOptions {} Additional options for filename matching.
skipSearchJs boolean false If true, do not add the JavaScript to the output files.
transformUrl function Callback for converting a single file into a URL. Input is the filename, the returned string is the URL.

Development

This uses Jasmine, Istanbul and ESLint for tests.

# Install dependencies.
npm install

# Run the tests
npm run test

This plugin is licensed under the MIT License with additional clauses. See the full license text for information.