mirror of
https://github.com/marko-js/marko.git
synced 2025-12-08 19:26:05 +00:00
Fixes #357 - Deprecate empty/notEmpty in Marko v3
This commit is contained in:
parent
78a73e573e
commit
bd488be548
39
README.md
39
README.md
@ -12,7 +12,7 @@ Marko is a [_really_ fast](https://github.com/marko-js/templating-benchmarks) an
|
||||
|
||||
# Get Involved
|
||||
|
||||
- **Contributing**: Pull requests are welcome!
|
||||
- **Contributing**: Pull requests are welcome!
|
||||
- Read [`CONTRIBUTING.md`](.github/CONTRIBUTING.md) and check out our [bite-sized](https://github.com/marko-js/marko/issues?q=is%3Aissue+is%3Aopen+label%3Adifficulty%3Abite-sized) and [help-wanted](https://github.com/marko-js/marko/issues?q=is%3Aissue+is%3Aopen+label%3Astatus%3Ahelp-wanted) issues
|
||||
- Submit github issues for any feature enhancements, bugs or documentation problems
|
||||
- **Support**: Join our [gitter chat](https://gitter.im/marko-js/marko) to ask questions to get support from the maintainers and other Marko developers
|
||||
@ -42,7 +42,38 @@ Marko supports _both_ a familiar HTML syntax, as well as a more concise indentat
|
||||
Hello ${data.name}!
|
||||
</h1>
|
||||
|
||||
<ul if(notEmpty(data.colors))>
|
||||
<if(data.colors.length)>
|
||||
<ul>
|
||||
<for(color in data.colors)>
|
||||
<li>
|
||||
${color}
|
||||
</li>
|
||||
</for>
|
||||
</ul>
|
||||
</if>
|
||||
<else>
|
||||
<div>
|
||||
No colors!
|
||||
</div>
|
||||
</else>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
Alternatively, you can choose to apply rendering logic as "attributes":
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Marko Templating Engine</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>
|
||||
Hello ${data.name}!
|
||||
</h1>
|
||||
|
||||
<ul if(data.colors.length)>
|
||||
<li for(color in data.colors)>
|
||||
${color}
|
||||
</li>
|
||||
@ -65,7 +96,7 @@ html lang="en"
|
||||
title - Marko Templating Engine
|
||||
body
|
||||
h1 - Hello ${data.name}!
|
||||
ul if(notEmpty(data.colors))
|
||||
ul if(data.colors.length)
|
||||
li for(color in data.colors)
|
||||
${color}
|
||||
div else
|
||||
@ -86,7 +117,7 @@ html lang="en"
|
||||
<h1>
|
||||
Hello ${data.name}!
|
||||
</h1>
|
||||
ul if(notEmpty(data.colors))
|
||||
ul if(data.colors.length)
|
||||
li for(color in data.colors)
|
||||
${color}
|
||||
div else
|
||||
|
||||
@ -46,8 +46,6 @@ require('marko/compiler').compileFile(path, function(err, src) {
|
||||
```javascript
|
||||
function create(__helpers) {
|
||||
var str = __helpers.s,
|
||||
empty = __helpers.e,
|
||||
notEmpty = __helpers.ne,
|
||||
escapeXml = __helpers.x,
|
||||
forEach = __helpers.f,
|
||||
escapeXmlAttr = __helpers.xa;
|
||||
@ -57,7 +55,7 @@ function create(__helpers) {
|
||||
escapeXml(data.name) +
|
||||
'! ');
|
||||
|
||||
if (notEmpty(data.colors)) {
|
||||
if (data.colors.length) {
|
||||
out.w('<ul>');
|
||||
|
||||
forEach(data.colors, function(color) {
|
||||
|
||||
@ -11,13 +11,13 @@ _Applying directives using attributes:_
|
||||
|
||||
```xml
|
||||
<!-- Colors available -->
|
||||
<ul if(notEmpty(colors))>
|
||||
<ul if(colors.length)>
|
||||
<li for(color in colors)>
|
||||
${color}
|
||||
</li>
|
||||
</ul>
|
||||
<!-- No colors available-->
|
||||
<div if(empty(colors))>
|
||||
<div else>
|
||||
No colors!
|
||||
</div>
|
||||
```
|
||||
@ -26,7 +26,7 @@ _Applying directives using elements:_
|
||||
|
||||
```xml
|
||||
<!-- Colors available -->
|
||||
<if(notEmpty(colors))>
|
||||
<if(colors.length)>
|
||||
<ul>
|
||||
<for(color in colors)>
|
||||
<li>
|
||||
@ -37,11 +37,11 @@ _Applying directives using elements:_
|
||||
</if>
|
||||
|
||||
<!-- No colors available -->
|
||||
<if(empty(colors))>
|
||||
<else>
|
||||
<div>
|
||||
No colors!
|
||||
</div>
|
||||
</if>
|
||||
</else>
|
||||
```
|
||||
|
||||
The disadvantage of using elements to control structural logic is that they change the nesting of the elements which can impact readability. For this reason it is often more suitable to apply directives as attributes.
|
||||
@ -851,9 +851,11 @@ Usage inside template:
|
||||
|
||||
Aside from custom helpers that can be built per-project, Marko has some built-in helpers with support for common tasks.
|
||||
|
||||
__empty()/notEmpty()__
|
||||
## `empty()`/`notEmpty()`
|
||||
|
||||
To deal with "empty" data, Marko provides the empty() and notEmpty() helpers. Both helpers can be used to check for empty objects (objects, that are set to null), arrays of length zero or empty strings; empty() returns true for these cases exclusively. Therefore, not all "falsy" JavaScript values are reported as "empty" - e.g.: a boolean value that is set to "false" is not empty, hence notEmpty() would return "true". As their name already suggests, both helpers are contrary to each other.
|
||||
___DEPRECATED - Do not use (removed in Marko v4)___
|
||||
|
||||
To deal with "empty" data, Marko automatically provides the `empty()` and `notEmpty()` helpers. Both helpers can be used to check for empty objects (objects, that are set to null), arrays of length zero or empty strings; `empty()` returns `true` for these cases exclusively. Therefore, not all "falsey" JavaScript values are reported as "empty" - e.g.: a boolean value that is set to "false" is not empty, hence `notEmpty()` would return "true". As their name already suggests, both helpers are contrary to each other.
|
||||
|
||||
# Miscellaneous
|
||||
|
||||
|
||||
@ -127,7 +127,7 @@ Source: https://github.com/marko-js/templating-benchmarks
|
||||
<!-- Welcome to Marko! -->
|
||||
<app-hello name=data.name/>
|
||||
|
||||
<ul if(notEmpty(data.colors))>
|
||||
<ul if(data.colors.length)>
|
||||
<li for(color in data.colors)>
|
||||
${color}
|
||||
</li>
|
||||
@ -151,7 +151,7 @@ html lang="en"
|
||||
body
|
||||
// Welcome to Marko!
|
||||
app-hello name=data.name
|
||||
ul if(notEmpty(data.colors))
|
||||
ul if(data.colors.length)
|
||||
li for(color in data.colors)
|
||||
${color}
|
||||
div else
|
||||
@ -171,7 +171,7 @@ html lang="en"
|
||||
body
|
||||
// Welcome to Marko!
|
||||
<app-hello name=data.name/>
|
||||
ul if(notEmpty(data.colors))
|
||||
ul if(data.colors.length)
|
||||
li for(color in data.colors)
|
||||
${color}
|
||||
div else
|
||||
@ -852,7 +852,7 @@ Usage:
|
||||
```xml
|
||||
<my-custom-tag name="World"/>
|
||||
|
||||
<ul if(notEmpty(data.colors))>
|
||||
<ul if(data.colors.length)>
|
||||
<li for(color in data.colors)>
|
||||
${color}
|
||||
</li>
|
||||
@ -877,7 +877,7 @@ function create(__helpers) {
|
||||
name: "World"
|
||||
}, out);
|
||||
|
||||
if (notEmpty(data.colors)) {
|
||||
if (data.colors.length) {
|
||||
out.w("<ul>");
|
||||
|
||||
forEach(data.colors, function(color) {
|
||||
|
||||
@ -36,7 +36,7 @@ Syntax highlighting is available in the following editors and IDEs:
|
||||
Hello ${data.name}!
|
||||
</h1>
|
||||
|
||||
<ul if(notEmpty(data.colors))>
|
||||
<ul if(data.colors.length)>
|
||||
<li for(color in data.colors)>
|
||||
${color}
|
||||
</li>
|
||||
@ -59,7 +59,7 @@ html lang="en"
|
||||
title - Marko Templating Engine
|
||||
body
|
||||
h1 - Hello ${data.name}!
|
||||
ul if(notEmpty(data.colors))
|
||||
ul if(data.colors.length)
|
||||
li for(color in data.colors)
|
||||
${color}
|
||||
div else
|
||||
@ -80,7 +80,7 @@ html lang="en"
|
||||
<h1>
|
||||
Hello ${data.name}!
|
||||
</h1>
|
||||
ul if(notEmpty(data.colors))
|
||||
ul if(data.colors.length)
|
||||
li for(color in data.colors)
|
||||
${color}
|
||||
div else
|
||||
@ -95,7 +95,7 @@ _hello-world.marko:_
|
||||
|
||||
```xml
|
||||
<h2>Hello ${data.name}!</h2>
|
||||
<ul if(notEmpty(data.colors))>
|
||||
<ul if(data.colors.length)>
|
||||
<li style="color: ${color}" for(color in data.colors)>
|
||||
${color}
|
||||
</li>
|
||||
@ -195,7 +195,7 @@ __Marko:__
|
||||
|
||||
```xml
|
||||
<h2>Hello ${data.name}!</h2>
|
||||
<ul if(notEmpty(data.colors))>
|
||||
<ul if(data.colors.length)>
|
||||
<li class="color" for(color in data.colors)>
|
||||
${color}
|
||||
</li>
|
||||
|
||||
@ -109,7 +109,7 @@ The code snippets below show how each syntax variant compares.
|
||||
Hello ${data.name}!
|
||||
</h1>
|
||||
|
||||
<ul if(notEmpty(data.colors))>
|
||||
<ul if(data.colors.length)>
|
||||
<li for(color in data.colors)>
|
||||
${color}
|
||||
</li>
|
||||
@ -133,7 +133,7 @@ html lang="en"
|
||||
body
|
||||
// Welcome to Marko!
|
||||
h1 - Hello ${data.name}!
|
||||
ul if(notEmpty(data.colors))
|
||||
ul if(data.colors.length)
|
||||
li for(color in data.colors)
|
||||
${color}
|
||||
div else
|
||||
@ -186,7 +186,7 @@ html lang="en"
|
||||
<h1>
|
||||
Hello ${data.name}!
|
||||
</h1>
|
||||
ul if(notEmpty(data.colors))
|
||||
ul if(data.colors.length)
|
||||
li for(color in data.colors)
|
||||
${color}
|
||||
div else
|
||||
@ -894,7 +894,7 @@ For example, given the following input template:
|
||||
```xml
|
||||
<my-custom-tag name="World"/>
|
||||
|
||||
<ul if(notEmpty(data.colors))>
|
||||
<ul if(data.colors.length)>
|
||||
<li for(color in data.colors)>
|
||||
${color}
|
||||
</li>
|
||||
@ -921,7 +921,7 @@ function create(__helpers) {
|
||||
name: "World"
|
||||
}, out);
|
||||
|
||||
if (notEmpty(data.colors)) {
|
||||
if (data.colors.length) {
|
||||
out.w("<ul>");
|
||||
|
||||
forEach(data.colors, function(color) {
|
||||
|
||||
4
helpers/README.md
Normal file
4
helpers/README.md
Normal file
@ -0,0 +1,4 @@
|
||||
Marko Helpers
|
||||
=============
|
||||
|
||||
This directory contains helpers that were deprecated in Marko v3.
|
||||
5
helpers/empty.js
Normal file
5
helpers/empty.js
Normal file
@ -0,0 +1,5 @@
|
||||
var notEmpty = require('./notEmpty');
|
||||
|
||||
module.exports = function (o) {
|
||||
return !notEmpty(o);
|
||||
};
|
||||
11
helpers/notEmpty.js
Normal file
11
helpers/notEmpty.js
Normal file
@ -0,0 +1,11 @@
|
||||
module.exports = function notEmpty(o) {
|
||||
if (o == null) {
|
||||
return false;
|
||||
} else if (Array.isArray(o)) {
|
||||
return !!o.length;
|
||||
} else if (o === '') {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
23
runtime/deprecate.js
Normal file
23
runtime/deprecate.js
Normal file
@ -0,0 +1,23 @@
|
||||
var logger = typeof console !== 'undefined' && console.warn && console;
|
||||
|
||||
module.exports = function(o, methodName, message) {
|
||||
if (!logger) {
|
||||
return;
|
||||
}
|
||||
|
||||
var originalMethod = o[methodName];
|
||||
|
||||
var maxWarn = 20;
|
||||
var currentWarn = 0;
|
||||
|
||||
o[methodName] = function() {
|
||||
if (currentWarn < maxWarn) {
|
||||
if (++currentWarn === maxWarn) {
|
||||
o[methodName] = originalMethod;
|
||||
}
|
||||
logger.warn(message, 'Stack: ' + new Error().stack);
|
||||
}
|
||||
|
||||
return originalMethod.apply(o, arguments);
|
||||
};
|
||||
};
|
||||
@ -1,18 +1,20 @@
|
||||
var copyProp;
|
||||
|
||||
var maxWarn = 50;
|
||||
var maxWarn = 20;
|
||||
var currentWarn = 0;
|
||||
|
||||
var logger = typeof console !== 'undefined' && console.warn && console;
|
||||
|
||||
function deprecateWarning(deprecatedName) {
|
||||
console.warn('Deprecated: Use the unhyphenated name instead for reading "' + deprecatedName +
|
||||
'" - WARNING: This will not be allowed in the future.');
|
||||
logger.warn('Deprecated: Use the unhyphenated name instead for reading "' + deprecatedName +
|
||||
'" - WARNING: This will not be allowed in the future. Stack: ' + new Error().stack);
|
||||
}
|
||||
|
||||
function copyPropNoWarn(obj, deprecatedName, targetName) {
|
||||
obj[deprecatedName] = obj[targetName];
|
||||
}
|
||||
|
||||
if (Object.defineProperty) {
|
||||
if (logger && Object.defineProperty) {
|
||||
copyProp = function(obj, deprecatedName, targetName) {
|
||||
Object.defineProperty(obj, deprecatedName, {
|
||||
get: function() {
|
||||
|
||||
@ -19,23 +19,13 @@ var escapeXml = require('raptor-util/escapeXml');
|
||||
var escapeXmlAttr = escapeXml.attr;
|
||||
var runtime = require('./'); // Circular dependency, but that is okay
|
||||
var attr = require('raptor-util/attr');
|
||||
var notEmpty = require('../helpers/notEmpty');
|
||||
|
||||
var isArray = Array.isArray;
|
||||
var STYLE_ATTR = 'style';
|
||||
var CLASS_ATTR = 'class';
|
||||
var escapeEndingScriptTagRegExp = /<\//g;
|
||||
|
||||
function notEmpty(o) {
|
||||
if (o == null) {
|
||||
return false;
|
||||
} else if (Array.isArray(o)) {
|
||||
return !!o.length;
|
||||
} else if (o === '') {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function classListHelper(arg, classNames) {
|
||||
var len;
|
||||
|
||||
@ -114,7 +104,7 @@ function LoopStatus(getLength, isLast, isFirst, getIndex) {
|
||||
this.getIndex = getIndex;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
module.exports = exports = {
|
||||
/**
|
||||
* Internal helper method to prevent null/undefined from being written out
|
||||
* when writing text that resolves to null/undefined
|
||||
@ -188,7 +178,7 @@ module.exports = {
|
||||
* Internal method to check if an object/array is empty
|
||||
* @private
|
||||
*/
|
||||
e: function (o) {
|
||||
e: function empty(o) {
|
||||
return !notEmpty(o);
|
||||
},
|
||||
/**
|
||||
@ -398,3 +388,8 @@ module.exports = {
|
||||
return classList(arguments);
|
||||
}
|
||||
};
|
||||
|
||||
var deprecate = require('./deprecate');
|
||||
var emptyNotEmptyDeprecationUrl = 'https://github.com/marko-js/marko/issues/357';
|
||||
deprecate(exports, 'e', 'empty() helper is deprecated. See: ' + emptyNotEmptyDeprecationUrl);
|
||||
deprecate(exports, 'ne', 'notEmpty() helper is deprecated. See: ' + emptyNotEmptyDeprecationUrl);
|
||||
@ -0,0 +1 @@
|
||||
<div>0</div><div>1</div><div>2</div><div>3</div><div>4</div><div>5</div><div>6</div><div>7</div><div>8</div><div>9</div><div>10</div><div>11</div><div>12</div><div>13</div><div>14</div><div>15</div><div>16</div><div>17</div><div>18</div><div>19</div><div>20</div><div>21</div><div>22</div><div>23</div><div>24</div><div>25</div><div>26</div><div>27</div><div>28</div><div>29</div><div>30</div><div>31</div><div>32</div><div>33</div><div>34</div><div>35</div><div>36</div><div>37</div><div>38</div><div>39</div><div>40</div><div>41</div><div>42</div><div>43</div><div>44</div><div>45</div><div>46</div><div>47</div><div>48</div><div>49</div><div>50</div>
|
||||
@ -0,0 +1,5 @@
|
||||
<for(var i=0; i<51; i++)>
|
||||
<div if(notEmpty(['a', 'b', 'c']))>
|
||||
${i}
|
||||
</div>
|
||||
</for>
|
||||
@ -0,0 +1,3 @@
|
||||
exports.templateData = {
|
||||
"name": "John"
|
||||
};
|
||||
@ -0,0 +1 @@
|
||||
<div>notEmpty-YES</div><div>empty-YES</div>
|
||||
@ -0,0 +1,12 @@
|
||||
<div if(notEmpty(['a', 'b', 'c']))>
|
||||
notEmpty-YES
|
||||
</div>
|
||||
<div if(notEmpty([]))>
|
||||
notEmpty-NO
|
||||
</div>
|
||||
<div if(empty(['a', 'b', 'c']))>
|
||||
empty-NO
|
||||
</div>
|
||||
<div if(empty([]))>
|
||||
empty-YES
|
||||
</div>
|
||||
@ -0,0 +1,3 @@
|
||||
exports.templateData = {
|
||||
"name": "John"
|
||||
};
|
||||
@ -0,0 +1 @@
|
||||
<div>notEmpty-YES</div><div>empty-YES</div>
|
||||
@ -0,0 +1,17 @@
|
||||
<script marko-init>
|
||||
var notEmpty = require('marko/helpers/notEmpty');
|
||||
var empty = require('marko/helpers/empty');
|
||||
</script>
|
||||
|
||||
<div if(notEmpty(['a', 'b', 'c']))>
|
||||
notEmpty-YES
|
||||
</div>
|
||||
<div if(notEmpty([]))>
|
||||
notEmpty-NO
|
||||
</div>
|
||||
<div if(empty(['a', 'b', 'c']))>
|
||||
empty-NO
|
||||
</div>
|
||||
<div if(empty([]))>
|
||||
empty-YES
|
||||
</div>
|
||||
@ -0,0 +1,3 @@
|
||||
exports.templateData = {
|
||||
"name": "John"
|
||||
};
|
||||
Loading…
x
Reference in New Issue
Block a user