lb-include
v0.3.2
Published
Library for `#include`-ing HTML files inside other HTML files, with super simple variable substitution.
Downloads
49
Maintainers
Readme
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
:
connect-lb-include
- Connect/Express middleware that can process static or dynamic responsesgulp-lb-include
- Uselb-include
as part of a gulp task
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
orBuffer
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 #include
d 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 #include
d 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 #include
s 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 #include
s, 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 #include
s 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