Skip to content
Library for `#include`-ing HTML files inside other HTML files, with super simple variable substitution.
Branch: develop
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
src
test
.editorconfig
.gitattributes
.gitignore
.jshintrc
.travis.yml
LICENSE.md
README.md
gentoc.js
package.json

README.md

lb-include

Library for #include-ing HTML files inside other HTML files, with super simple variable substitution. Named because in some places # is pronounced 'pound', which is often abbreviated 'lb', hence #include -> lb-include.

Builds hosted by Travis CI: master: , develop:

Install

$ npm install --save lb-include

Plugins

There are also a few plugins that use lb-include:

Overview

Let's assume you have some folder, containing two files, index.html and nav.html. In index.html let's say you have this:

<html>
<body>
<!-- #include file="nav.html" -->
</body>
</html>

Likewise, in nav.html, let's say you have this:

<nav>
    <a href="/about">Team</a>
    <a href="/faq">FAQs</a>
    <a href="/contact">Contact</a>
</nav>

If you want to be able to do something like this, then lb-include is the right tool for you. It's a simple little tool which you can wire up into your own stuff (like a Connect middleware, or maybe a Gulp/Grunt/Broccoli plugin).

In this example, all you need to do is:

var include = require('lb-include');
include('path/to/index.html', function (err, markup)
{
    //do whatever here
});

This will asynchronously load and transform the markup.

Usage

lb-include can be used in two different asynchronous styles

var lb_include = require('lb-include');
//callback style
lb_include('path/to/file.html', options, function (err, markup) {
  //do whatever here
});
//promises style (kriskowal/q)
lb_include('path/to/file.html', options).then(function (markup) {
  //do whatever here
});

The first argument is required, and should be the path to the file to be loaded and resolved.

The second argument, options, is an optional object hash with properties described below. This may be omitted.

The third argument is a standard callback function, and it is optional. lb-include will also return a kriskowal/q-flavored Promise, even if you omit the third argument.

options.root

  • Optional: yes
  • Type: string (a path)
  • Default: process.cwd()

The root directory, from which root-relative includes are performed. Use: If you have nested folders, you may not want to have to use file-relative paths, which are fragile and will break if you move the parent file to a different folder:

<!-- #include file="../../../fragments/nav.html" -->

Instead, you might want to define root-relative paths, and then tell lb-include what the root folder is:

<!-- #include file="/fragments/nav.html" -->

options.fileContents

  • Optional: yes
  • Type: string or Buffer

If you are trying to include() a file, but you already happen to have the unprocessed source hanging around in memory (perhaps because you're writing a Gulp plugin or a Connect middleware), then you can pass it in here. For the file passed as the first argument to include, this value will be used instead of reading the file from disk.

Note that any files #included from within this file will always be read from disk. In the future, there may be some way to cache or programmatically transform the contents of other #included files.

options.varDefaults

  • Optional: yes
  • Type: object

Provide default values for variable substitutions. If a variable is set in both options.varDefaults AND in the #include directive, the variable from the #include wins. For example, if we have these files:

<!-- status.html -->
You have: ${count} ${item}
<!-- main.html -->
<!-- #include file="status.html" ${item}="bananas" -->

...and we run this code:

var include = require('lb-include');
var defaults = {
    '${count}': 5,
    '${item}': 'apples'
};
include('path/to/index.html', { varDefaults: defaults }, function (err, markup)
{
    //do whatever here
});

...will yield this output:

You have: 5 bananas

options.varOverrides

  • Optional: yes
  • Type: object

Forces specific values for variable substitutions. This overrides any values set in options.varDefaults or on the #include directive.

<!-- status.html -->
You have: ${count} ${item}
<!-- main.html -->
<!-- #include file="status.html" ${item}="bananas" -->

...and we run this code:

var include = require('lb-include');
var overrides = {
    '${count}': 5,
    '${item}': 'apples'
};
include('path/to/index.html', { varOverrides: overrides }, function (err, markup)
{
    //do whatever here
});

...will yield this output:

You have: 5 apples

Template Syntax

Let's say you have a folder structure like this:

app/
 |- pages/
 |   |- index.html
 |   \- team.html
 \- fragments/
     |- header.html
     |- nav.html
     \- footer.html

In app/pages/index.html and app/pages/team.html you might want to do something like this:

<!-- #include file="../fragments/header.html" -->
<h1>Kilo Corporation</h1>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras non accumsan arcu. Vestibulum...</p>
<!-- #include file="../fragments/footer.html" -->

Where app/fragments/header.html is something like:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>Some title</title>
    <link rel="stylesheet" href="/main.css" />
</head>
<body>
<!-- #include file="./nav.html" -->

...and app/fragments/footer.html is something like:

</body>
</html>

In this case, you can easily get the transformed markup:

var include = require('lb-include');
include('app/pages/index.html', function(err, markup)
{
    //do something here
});

Root-relative file paths

Let's say you want to move app/pages/team.html to app/pages/team/index.html. If you just do this, all your paths in #includes will need an extra ../. Depending on how deep your folders go, it can be hard to manage all of the ../s in your paths.

Instead, you can specify root-relative URLs for your #includes, like so:

<!-- #include file="/header.html" -->
<h1>Our team</h1>
<p>I don't need to write anything here because you already know our team is awesome!</p>
<!-- #include file="/footer.html" -->

Note that we don't need to change nav.html - relative #includes are always relative to the file in which they reside. However, when loading the markup, we need to tell lb-include what the root folder is:

var include = require('lb-include');
include('app/pages/team/index.html', {'root':'app/fragments/'}, function(err, markup)
{
    //do something here
});

Simple variable substitution

In addition to the file="..." part of your #include, you can have any number of other key/value pairs, which will then get substituted before the output markup is returned.

Let's imagine that when we include header.html, we might want to change the page title and meta tag description so that each page is unique. So here's header.html:

<html>
<head>
    <title>${page.title}</title>
    <meta name="description" content="${page.desc}">
</head>
<body>

Here's how we would include the header:

<!-- #include
    file="/header.html"
    ${page.title}="About our \"team\""
    ${page.desc}="BNL is a great place to work!"
-->
<p>This is our team.  We aren't very large, yet.</p>
<!-- #include file="/footer.html" -->

And this is what the final markup looks like:

<html>
<head>
    <title>About our "team"</title>
    <meta name="description" content="BNL is a great place to work!">
</head>
<body>
<p>This is our team.  We aren't very large, yet.</p>
...

The keys can be named any combination of characters other than whitespace and the equals sign. These will be replaced verbatim with their output, hence why I used identifiers armored with ${} above. You could as easily use @pageTitle or $pageTitle or whatever you want - just be aware that replacement is done via unintelligent search-and-replace.

The values are JSON-quoted single-line strings. So ${key}="apples\nbananas" will replace all instances of ${key} with a output containing a newline. This also lets you have double quotes in your substituted output.npm

Note that the replacement is not HTML-encoded before it gets stuck into the output, as it's assumed at template-time that you know what you are doing (and it might be useful to include bits and bobs of HTML in places)

Tests

To run the tests, checkout this repo and then npm install then npm test.

To rerun the tests automatically as you edit files, use npm run test-watch instead.

License

Released under the MIT license © Jeffrey Stanton

See LICENSE.md for full license text

You can’t perform that action at this time.