Skip to content

Commit

Permalink
Expose fs as an option to override the default implementations
Browse files Browse the repository at this point in the history
  • Loading branch information
pmalouin authored and harttle committed Jun 27, 2019
1 parent 2ae8c37 commit edb2cc1
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 4 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,8 @@ Otherwise, undefined variables will cause an exception. Defaults to `false`.

* `greedy` is used to specify whether `trim*Left`/`trim*Right` is greedy. When set to `true`, all consecutive blank characters including `\n` will be trimed regardless of line breaks. Defaults to `true`.

* `fs` is used to override the default file-system module with a custom implementation.

## Register Filters

```javascript
Expand Down
5 changes: 4 additions & 1 deletion src/liquid-options.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import * as _ from './util/underscore'
import IFS from './fs/ifs';

export interface LiquidOptions {
/** `root` is a directory or an array of directories to resolve layouts and includes, as well as the filename passed in when calling `.renderFile()`. If an array, the files are looked up in the order they occur in the array. Defaults to `["."]` */
Expand Down Expand Up @@ -28,7 +29,9 @@ export interface LiquidOptions {
outputDelimiterLeft?: string,
outputDelimiterRight?: string,
/** `greedy` is used to specify whether `trim*Left`/`trim*Right` is greedy. When set to `true`, all consecutive blank characters including `\n` will be trimed regardless of line breaks. Defaults to `true`. */
greedy?: boolean
greedy?: boolean,
/** `fs` is used to override the default file-system module with a custom implementation */
fs?: IFS
}

interface NormalizedOptions extends LiquidOptions {
Expand Down
9 changes: 6 additions & 3 deletions src/liquid.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,22 @@ import builtinTags from './builtin/tags'
import builtinFilters from './builtin/filters'
import { LiquidOptions, NormalizedFullOptions, applyDefault, normalize } from './liquid-options'
import { FilterImplOptions } from './template/filter/filter-impl-options'
import IFS from './fs/ifs';

export default class Liquid {
public options: NormalizedFullOptions
public renderer: Render
public parser: Parser
private cache: object = {}
private tokenizer: Tokenizer
private fs: IFS

constructor (opts: LiquidOptions = {}) {
this.options = applyDefault(normalize(opts))
this.parser = new Parser(this)
this.renderer = new Render()
this.tokenizer = new Tokenizer(this.options)
this.fs = opts.fs || fs

_.forOwn(builtinTags, (conf, name) => this.registerTag(name, conf))
_.forOwn(builtinFilters, (handler, name) => this.registerFilter(name, handler))
Expand All @@ -48,14 +51,14 @@ export default class Liquid {
async getTemplate (file: string, opts?: LiquidOptions) {
const options = normalize(opts)
const roots = options.root ? [...options.root, ...this.options.root] : this.options.root
const paths = roots.map(root => fs.resolve(root, file, this.options.extname))
const paths = roots.map(root => this.fs.resolve(root, file, this.options.extname))

for (const filepath of paths) {
if (this.options.cache && this.cache[filepath]) return this.cache[filepath]

if (!(await fs.exists(filepath))) continue
if (!(await this.fs.exists(filepath))) continue

const value = this.parse(await fs.readFile(filepath), filepath)
const value = this.parse(await this.fs.readFile(filepath), filepath)
if (this.options.cache) this.cache[filepath] = value
return value
}
Expand Down
21 changes: 21 additions & 0 deletions test/integration/liquid/fs-option.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { expect } from 'chai'
import Liquid from '../../../src/liquid'

describe('LiquidOptions#fs', function () {
let engine: Liquid
const fs = {
exists: () => Promise.resolve(true),
readFile: () => Promise.resolve('test file content'),
resolve: () => 'resolved'
}
beforeEach(function () {
engine = new Liquid({
root: '/root/',
fs
})
})
it('should be used to read templates', function () {
return engine.renderFile('files/foo')
.then(x => expect(x).to.equal('test file content'))
})
})

0 comments on commit edb2cc1

Please sign in to comment.