-
-
Notifications
You must be signed in to change notification settings - Fork 31
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
set tag allows data mutation at runtime with templates
- Loading branch information
1 parent
2ff8b36
commit a6735fc
Showing
3 changed files
with
211 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
'use strict' | ||
|
||
/* | ||
* edge | ||
* | ||
* (c) Harminder Virk <virk@adonisjs.com> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
const BaseTag = require('./BaseTag') | ||
const _ = require('lodash') | ||
|
||
/** | ||
* The `set` tag allows you to mutate data | ||
* object for a given template. | ||
* | ||
* @class SetTag | ||
* @extends {BaseTag} | ||
* @static | ||
*/ | ||
class SetTag extends BaseTag { | ||
/** | ||
* Tag name to be used for registering | ||
* the tag | ||
* | ||
* @method tagName | ||
* | ||
* @return {String} | ||
*/ | ||
get tagName () { | ||
return 'set' | ||
} | ||
|
||
/** | ||
* Whether or not the tag is block level | ||
* tag. Which is no in this case. | ||
* | ||
* @method isBlock | ||
* | ||
* @return {Boolean} | ||
*/ | ||
get isBlock () { | ||
return false | ||
} | ||
|
||
/** | ||
* The expressions allowed inside an if tag. | ||
* | ||
* @method allowedExpressions | ||
* | ||
* @return {Array} | ||
*/ | ||
get allowedExpressions () { | ||
return ['SequenceExpression'] | ||
} | ||
|
||
/** | ||
* Compile the template | ||
* | ||
* @method compile | ||
* | ||
* @param {Object} compiler | ||
* @param {Object} lexer | ||
* @param {Object} buffer | ||
* @param {String} options.body | ||
* @param {Array} options.childs | ||
* @param {Number} options.lineno | ||
* | ||
* @return {void} | ||
*/ | ||
compile (compiler, lexer, buffer, { body, childs, lineno }) { | ||
const [lhs, rhs] = this._compileStatement(lexer, body, lineno).toStatement() | ||
buffer.writeLine(`this.context.setValue(${lhs}, ${rhs})`) | ||
} | ||
|
||
/** | ||
* Nothing needs to be done in runtime | ||
* for an include tag | ||
*/ | ||
run (Context) { | ||
Context.macro('setValue', function (key, value) { | ||
_.set(this.$presenter.$data, key, value) | ||
}) | ||
} | ||
} | ||
|
||
module.exports = SetTag |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
'use strict' | ||
|
||
/* | ||
* edge | ||
* | ||
* (c) Harminder Virk <virk@adonisjs.com> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
const test = require('japa') | ||
const Template = require('../../../src/Template') | ||
const Loader = require('../../../src/Loader') | ||
const Context = require('../../../src/Context') | ||
const dedent = require('dedent-js') | ||
const path = require('path') | ||
const loader = new Loader(path.join(__dirname, '../../../test-helpers/views')) | ||
|
||
test.group('Tags | Set ', (group) => { | ||
group.beforeEach(() => { | ||
require('../../../test-helpers/transform-tags')(this, require('../../../src/Tags')) | ||
}) | ||
|
||
test('parse the set block which mutates the data', (assert) => { | ||
const template = new Template(this.tags, {}, {}, loader) | ||
const statement = dedent` | ||
@set('username', 'virk') | ||
` | ||
const output = template.compileString(statement) | ||
|
||
assert.equal(output, dedent` | ||
return (function templateFn () { | ||
let out = new String() | ||
this.context.setValue('username', 'virk') | ||
return out | ||
}).bind(this)() | ||
`) | ||
}) | ||
|
||
test('parse the set block with value as an array of data', (assert) => { | ||
const template = new Template(this.tags, {}, {}, loader) | ||
const statement = dedent` | ||
@set('users', ['virk']) | ||
` | ||
const output = template.compileString(statement) | ||
|
||
assert.equal(output, dedent` | ||
return (function templateFn () { | ||
let out = new String() | ||
this.context.setValue('users', ['virk']) | ||
return out | ||
}).bind(this)() | ||
`) | ||
}) | ||
|
||
test('parse the set block with value as a reference', (assert) => { | ||
const template = new Template(this.tags, {}, {}, loader) | ||
const statement = dedent` | ||
@set('users', admin.users) | ||
` | ||
const output = template.compileString(statement) | ||
|
||
assert.equal(output, dedent` | ||
return (function templateFn () { | ||
let out = new String() | ||
this.context.setValue('users', this.context.accessChild(this.context.resolve('admin'), ['users'])) | ||
return out | ||
}).bind(this)() | ||
`) | ||
}) | ||
|
||
test('set literal value at runtime', (assert) => { | ||
const template = new Template(this.tags, {}, {}, loader) | ||
const statement = dedent` | ||
@set('username', 'virk') | ||
{{ username }} | ||
` | ||
|
||
this.tags.set.run(Context) | ||
const output = template.renderString(statement) | ||
assert.equal(output.trim(), 'virk') | ||
}) | ||
|
||
test('set identifier at runtime', (assert) => { | ||
const template = new Template(this.tags, {}, {}, loader) | ||
const statement = dedent` | ||
@set('username', admin.username) | ||
{{ username }} | ||
` | ||
|
||
this.tags.set.run(Context) | ||
const output = template.renderString(statement, { admin: { username: 'virk' } }) | ||
assert.equal(output.trim(), 'virk') | ||
}) | ||
|
||
test('set array at runtime', (assert) => { | ||
const template = new Template(this.tags, {}, {}, loader) | ||
const statement = dedent` | ||
@set('users', ['virk', 'nikk']) | ||
{{ users.join(',') }} | ||
` | ||
|
||
this.tags.set.run(Context) | ||
const output = template.renderString(statement) | ||
assert.equal(output.trim(), 'virk,nikk') | ||
}) | ||
|
||
test('set array at runtime', (assert) => { | ||
const template = new Template(this.tags, {}, {}, loader) | ||
const statement = dedent` | ||
@set('users', ['virk', 'nikk']) | ||
{{ users.join(',') }} | ||
` | ||
|
||
this.tags.set.run(Context) | ||
const output = template.renderString(statement) | ||
assert.equal(output.trim(), 'virk,nikk') | ||
}) | ||
}) |