Skip to content

Commit

Permalink
Merge pull request #11 from chocolateboy/rcfile-etc
Browse files Browse the repository at this point in the history
rcfile support + fix dependency tracking + add documentation
  • Loading branch information
Matthew McCune committed Oct 18, 2018
2 parents 8dd2831 + a7ea5ca commit c93584d
Show file tree
Hide file tree
Showing 3 changed files with 231 additions and 34 deletions.
177 changes: 173 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,176 @@
# parcel-plugin-nunjucks
[Parcel](https://parceljs.org/) plugin to compile [Nunjucks](https://mozilla.github.io/nunjucks/) templates.

## Installation
`npm i parcel-plugin-nunjucks` or `yarn add parcel-plugin-nunjucks`
[![NPM Version](https://img.shields.io/npm/v/parcel-plugin-nunjucks.svg)](https://www.npmjs.org/package/parcel-plugin-nunjucks)

Parcel will now render nunjucks template files with an `.njk` extension.
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->

- [NAME](#name)
- [INSTALLATION](#installation)
- [SYNOPSIS](#synopsis)
- [DESCRIPTION](#description)
- [CONFIGURATION](#configuration)
- [Options](#options)
- [data](#data)
- [env](#env)
- [filters](#filters)
- [options](#options)
- [root](#root)
- [COMPATIBILITY](#compatibility)
- [SEE ALSO](#see-also)
- [VERSION](#version)
- [AUTHOR](#author)
- [COPYRIGHT AND LICENSE](#copyright-and-license)

<!-- END doctoc generated TOC please keep comment here to allow auto update -->

# NAME

parcel-plugin-nunjucks - [Parcel](https://parceljs.org/) support for [nunjucks](https://mozilla.github.io/nunjucks/) templates

# INSTALLATION

$ npm install nunjucks # peer dependency
$ npm install parcel-plugin-nunjucks

# SYNOPSIS

```
$ cat src/html/index.njk
```

```jinja
{% extends "layout.njk" %}
{% block body %}
<h1>Hello, {{ name }}!</h1>
{% endblock %}
```

```
$ cat nunjucks.config.js
```

```javascript
module.exports = {
root: "./src/html",
data: { name: process.env.USER },
}
```

```
$ parcel build src/html/index.njk
```

# DESCRIPTION

This is a Parcel plugin which uses nunjucks to translate templates with an `.njk` extension into HTML assets.

As with HTML assets, nunjucks templates can be top-level entries, or dependencies referenced from other documents or templates.

# CONFIGURATION

An [environment](https://mozilla.github.io/nunjucks/api.html#environment) for each (or every) nunjucks template
known to Parcel can be configured by creating a `nunjucks` entry in the project's package.json file,
or by exporting a configuration object from one of the following files:

- nunjucks.config.js
- .nunjucks.js
- .nunjucksrc

The configuration object has the following type:

```typescript
type NunjucksConfiguration = {
data?: Object | string => Object;
env?: Environment | string => Environment;
filters?: Object;
options?: Object;
root?: string | Array<string>;
}
```
## Options
The following options can be defined.
### data
Data to expose as the "context" in nunjucks [assets](https://parceljs.org/assets.html). Can be defined as a function,
in which case it is called with the absolute path/URI of the template being processed and its return value is used as the data.
```javascript
module.exports = { data: { name: process.env.USER } }
```

### env

The [Environment](https://mozilla.github.io/nunjucks/api.html#environment) instance to use. Can be defined as a function,
in which case it is called with the absolute path/URI of the template being processed and its return value is used as the environment.

```javascript
const nunjucks = require('nunjucks')
const env = nunjucks.configure('./src/html')

env.addFilter('uc', value => value.toUpperCase())

module.exports = { env }
```

### filters

A map (object) of name/function pairs to add as filters to the environment. Ignored if the `env` option is supplied.

```javascript
module.exports = {
filters: {
uc: value => value.toUpperCase(),
lc: value => value.toLowerCase(),
}
}
```

### options

Options to pass to the [`nunjucks#configure`](https://mozilla.github.io/nunjucks/api.html#configure) method,
which is used to construct the Environment instance. Ignored if the `env` option is supplied.

```javascript
module.exports = {
options: { noCache: true }
}
```

### root

The base template directory or directories. If not supplied, it defaults to the project root.
Ignored if the `env` option is supplied.

```javascript
module.exports = { root: "./src/html" }
```

# COMPATIBILITY

* Node.js >= v7.6.0

# SEE ALSO

* [nunjucks](https://www.npmjs.com/package/nunjucks) - a Jinja2-inspired templating engine with support for template inheritance
* [posthtml-extend](https://www.npmjs.com/package/posthtml-extend) - a PostHTML plugin which supports Jade-like template inheritance
* [posthtml-include](https://www.npmjs.com/package/posthtml-include) - a PostHTML plugin which supports HTML transclusion

# VERSION

1.0.0

# AUTHOR

[Matthew McCune](mailto:matthew@matthew.cx)

# COPYRIGHT AND LICENSE

Copyright © 2017-2018 by Matthew McCune.

This is free software; you can redistribute it and/or modify it under the
terms of the [MIT license](https://opensource.org/licenses/MIT).
25 changes: 17 additions & 8 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,37 @@
"description": "Parcel plugin to compile Nunjucks templates.",
"main": "index.js",
"scripts": {},
"files": [
"index.js",
"src/NunjucksAsset.js"
],
"repository": {
"type": "git",
"url": "git+https://github.com/devmattrick/parcel-plugin-nunjucks.git"
},
"keywords": [
"asset",
"build",
"nunjucks",
"parcel",
"parcel-plugin",
"plugin",
"nunjucks",
"asset",
"build"
"template"
],
"author": "Matthew McCune <git@mattrick.me>",
"license": "MIT",
"engines": {
"node": ">= 7.6"
},
"bugs": {
"url": "https://github.com/devmattrick/parcel-plugin-nunjucks/issues"
},
"homepage": "https://github.com/devmattrick/parcel-plugin-nunjucks#readme",
"peerDependencies": {
"nunjucks": "~3",
"parcel-bundler": "~1"
},
"dependencies": {
"klaw-sync": "^3.0.2"
"nunjucks-parser": "^0.0.3"
},
"peerDependencies": {
"nunjucks": "^3.0.0",
"parcel-bundler": "^1.0.0"
}
}
63 changes: 41 additions & 22 deletions src/NunjucksAsset.js
Original file line number Diff line number Diff line change
@@ -1,31 +1,50 @@
'use strict';

const nunjucks = require('nunjucks');
const path = require('path');
const klawSync = require('klaw-sync');
const HTMLAsset = require('parcel-bundler/src/assets/HTMLAsset');
const HTMLAsset = require('parcel-bundler/lib/assets/HTMLAsset');
const { parseFile } = require('nunjucks-parser');

const CONFIG_FILE = [
['.nunjucksrc', '.nunjucks.js', 'nunjucks.config.js'],
{ packageKey: 'nunjucks' }
];

// if a config setting is lazy (i.e. a function), force its value by calling it
// with the supplied parameters
function force(value, ...args) {
return (typeof value === 'function') ? value.apply(this, args) : value;
}

class NunjucksAsset extends HTMLAsset {
constructor(name, pkg, options) {
super(name, pkg, options);
async load() {
const config = (await this.getConfig.apply(this, CONFIG_FILE)) || {};
const templateDirs = config.root || this.options.rootDir;
const templatePath = this.name;

// Set nunjucks to resolve paths relative to current asset's path
nunjucks.configure(path.dirname(name));
this.nunjucksDir = path.dirname(name);
}
const env = force(config.env, templatePath) || nunjucks.configure(
templateDirs,
config.options || {}
);

async getDependencies() {
await super.getDependencies();
// Walk nunjucks directory and add any templates to dependencies
const paths = klawSync(this.nunjucksDir, { nodir: true });
const filesList = paths.filter(p =>
path.extname(p.path).toLowerCase() === '.njk');
filesList.forEach(dep => {
this.addDependency(dep.path, { includedInParent: true });
});
}
if (config.filters && !config.env) {
for (const [name, fn] of Object.entries(config.filters)) {
env.addFilter(name, fn);
}
}

const data = force(config.data, templatePath) || {};
const { content, dependencies } = await parseFile(env, templatePath, { data });

for (const dependency of dependencies) {
if (dependency.parent) { // exclude self
this.addDependency(dependency.path, {
resolved: dependency.path,
includedInParent: true,
});
}
}

parse(code) {
// Parse Nunjucks into an HTML file and pass it on to the HTMLAsset
return super.parse(nunjucks.renderString(code));
return content;
}
}

Expand Down

0 comments on commit c93584d

Please sign in to comment.