Compare commits
10 Commits
Author | SHA1 | Date |
---|---|---|
|
85da6d3325 | 3 years ago |
|
d9b13ea1fd | 3 years ago |
|
e2b4b078f6 | 3 years ago |
|
f4692b8a82 | 3 years ago |
|
2549f0d0e9 | 3 years ago |
|
6885c4ab3b | 3 years ago |
|
7c6783a2a3 | 3 years ago |
|
777d69e2a0 | 3 years ago |
|
8f35cc913a | 3 years ago |
|
4e76faa35a | 3 years ago |
4 changed files with 206 additions and 16 deletions
@ -1 +1,100 @@ |
|||
# staples |
|||
# Staples |
|||
|
|||
Staples is a minimal library that provides the power to allow you to create simple semantic templates and customize them with the addition of custom helpers. Staples is widely compatible with the basic Mustache and Handlebars models. |
|||
|
|||
|
|||
|
|||
## Installation |
|||
|
|||
```bash |
|||
npm i @dslak/staples |
|||
``` |
|||
|
|||
or, using YARN |
|||
|
|||
```bash |
|||
yarn add @dslak/staples |
|||
``` |
|||
|
|||
|
|||
|
|||
## Usage |
|||
|
|||
Once installed, the library must be included as well |
|||
|
|||
```javascript |
|||
const staples = require('@dslak/staples') |
|||
staples.printVersion() |
|||
``` |
|||
|
|||
|
|||
|
|||
Example of use with a basic template and a test input |
|||
|
|||
```javascript |
|||
const staples = require('@dslak/staples'); |
|||
|
|||
const input = { |
|||
"sections": [ |
|||
{ |
|||
"name": "section1", |
|||
"elements": { |
|||
"val1": "value 1", |
|||
"val2": "value 2", |
|||
"val_html": "<b class=\"aaa\">HTML</b>" |
|||
} |
|||
}, |
|||
{ |
|||
"name": "section2", |
|||
"elements": { |
|||
"if": true, |
|||
"unless": false |
|||
} |
|||
} |
|||
] |
|||
}; |
|||
|
|||
const template = `<span class="value">{{sections.0.elements.val1}}</span> |
|||
<span class="value">{{sections.0.elements.val2}}</span> |
|||
<div class="html">{{sections.0.elements.val_html}}</div> |
|||
<span class="value">{{sections.0.elements.val2}}</span> |
|||
{{#if sections.1.elements.if}} |
|||
<span class="value">{{sections.0.elements.val1}}</span> |
|||
{{/if}} |
|||
{{#unless sections.1.elements.unless}} |
|||
<span class="value">{{sections.0.elements.val2}}</span> |
|||
{{/unless}}`; |
|||
|
|||
const compiled = staples.compile(template, input); |
|||
``` |
|||
|
|||
|
|||
|
|||
## Custom helpers |
|||
|
|||
Creating custom helpers |
|||
|
|||
```javascript |
|||
staples.addHelper('ellipsis', (string, words = 10) => { |
|||
return `${string.split(' ').slice(0, words).join(' ')}...` |
|||
}) |
|||
``` |
|||
|
|||
Usage: |
|||
|
|||
```javascript |
|||
const staples = require('@dslak/staples'); |
|||
|
|||
staples.addHelper('ellipsis', (string, words = 10) => { |
|||
return `${string.split(' ').slice(0, words).join(' ')}...` |
|||
}); |
|||
|
|||
const input = { |
|||
"value": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua." |
|||
}; |
|||
|
|||
const template = `<span class="value">{{ellipsis value 5}}</span>`; |
|||
|
|||
const compiled = staples.compile(template, input); |
|||
``` |
|||
|
|||
|
@ -0,0 +1,9 @@ |
|||
exports.helpers = [] |
|||
|
|||
exports.addHelper = (name, fun) => { |
|||
this.helpers[name] = fun |
|||
} |
|||
|
|||
this.addHelper('ellipsis', (string, words = 10) => { |
|||
return `${string.split(' ').slice(0, words).join(' ')}...` |
|||
}) |
@ -1,31 +1,113 @@ |
|||
exports.printVersion = () => { |
|||
console.log('Staples v0.0.1') |
|||
const pjson = require('./package.json') |
|||
console.log(`Staples ${pjson.version}`) |
|||
} |
|||
|
|||
exports.compile = (template, input) => { |
|||
let index = 0 |
|||
|
|||
const getValue = (tagContent) => { |
|||
let tagContentSplit = tagContent.split('.') |
|||
let varLevel = null |
|||
tagContentSplit.forEach( (level) => { |
|||
const isIndex = Number.isInteger(parseInt(level)) |
|||
if(!varLevel) varLevel = input |
|||
varLevel = isIndex ? varLevel[parseInt(level)] : varLevel[level] |
|||
}) |
|||
return typeof varLevel === 'string' ? varLevel.trim() : varLevel |
|||
} |
|||
|
|||
// Find all tags ####################################################
|
|||
let tags = [] |
|||
while(index < template.length) { |
|||
const nextOpen = template.indexOf('{{', index + 1) |
|||
if(nextOpen == index || nextOpen == -1) { |
|||
let nextOpen = template.indexOf('{{', index) |
|||
let tagType = null |
|||
if(template.substring(nextOpen,nextOpen+3) == '{{{') { tagType = 'HTML' |
|||
} else if(template.substring(nextOpen,nextOpen+5) == '{{#if') { tagType = 'IF' |
|||
} else if(template.substring(nextOpen,nextOpen+9) == '{{#unless') { tagType = 'UNLESS' |
|||
} else { tagType = 'DEFAULT' } |
|||
|
|||
if(nextOpen == -1) { |
|||
index = template.length |
|||
} else { |
|||
index = nextOpen |
|||
const nextClose = template.indexOf('}}', index + 1) |
|||
let nextClose = index |
|||
|
|||
switch(tagType) { |
|||
case 'DEFAULT': |
|||
nextClose = template.indexOf('}}', index) |
|||
index = nextClose+2 |
|||
break |
|||
case 'HTML': |
|||
nextClose = template.indexOf('}}}', index) |
|||
index = nextClose+3 |
|||
break |
|||
case 'IF': |
|||
nextClose = template.indexOf('{{/if}}', index) |
|||
index = nextClose+7 |
|||
break |
|||
case 'UNLESS': |
|||
nextClose = template.indexOf('{{/unless}}', index) |
|||
index = nextClose+11 |
|||
break |
|||
} |
|||
|
|||
if(nextClose == index || nextClose == -1) { |
|||
index = template.length |
|||
} else { |
|||
index = nextOpen+2 |
|||
const tagContent = template.substring(nextOpen+2, nextClose) |
|||
const tagContentSplit = tagContent.split('.') |
|||
let varLevel = input |
|||
tagContentSplit.forEach( (level) => { |
|||
const isIndex = Number.isInteger(parseInt(level)) |
|||
varLevel = isIndex ? varLevel[parseInt(level)] : varLevel[level] |
|||
tags.push({ |
|||
tag: template.substring(nextOpen, index), |
|||
type: tagType |
|||
}) |
|||
template = template.replace(tagContent, varLevel) |
|||
} |
|||
|
|||
} |
|||
} |
|||
console.log(template) |
|||
|
|||
// Replace tags ####################################################
|
|||
let contentStart = 0 |
|||
let contentEnd = 0 |
|||
let content = 0 |
|||
let value = 0 |
|||
|
|||
tags.forEach( (tag, i) => { |
|||
switch(tag.type) { |
|||
case 'DEFAULT': |
|||
const split = tag.tag.split(' ') |
|||
if(split.length == 1) { |
|||
template = template.replace(tag.tag, getValue(tag.tag.substring(2, tag.tag.length-2))) |
|||
} else { |
|||
const funct = split[0].substring(2) |
|||
const val1 = split.length == 2 ? split[1].substring(0,split[1].length-2) : split[1] |
|||
const val2 = split.length == 3 ? split[2].substring(0,split[2].length-2) : null |
|||
template = val2 ? template.replace(tag.tag, this.helpers.helpers[funct](getValue(val1), val2)) : |
|||
template.replace(tag.tag, this.helpers.helpers[funct](getValue(val1))) |
|||
} |
|||
break |
|||
case 'HTML': |
|||
template = template.replace(tag.tag, getValue(tag.tag.substring(3, tag.tag.length-3))) |
|||
break |
|||
case 'IF': |
|||
contentStart = tag.tag.indexOf('}}')+2 |
|||
contentEnd = tag.tag.indexOf('{{/if}}',contentStart) |
|||
content = tag.tag.substring(contentStart, contentEnd) |
|||
value = tag.tag.substring(6, contentStart-2) |
|||
template = template.replace(tag.tag, getValue(value) ? content : '') |
|||
break |
|||
case 'UNLESS': |
|||
contentStart = tag.tag.indexOf('}}')+2 |
|||
contentEnd = tag.tag.indexOf('{{/unless}}',contentStart) |
|||
content = tag.tag.substring(contentStart, contentEnd) |
|||
value = tag.tag.substring(10, contentStart-2) |
|||
template = template.replace(tag.tag, getValue(value) ? '' : content) |
|||
break |
|||
} |
|||
|
|||
}) |
|||
|
|||
return template |
|||
} |
|||
|
|||
|
|||
|
|||
exports.helpers = require('./helpers.js') |
|||
|
Loading…
Reference in new issue