Skip to content

Commit

Permalink
Update docs
Browse files Browse the repository at this point in the history
  • Loading branch information
DylanPiercey committed Jan 18, 2019
1 parent 020764c commit 22056e6
Show file tree
Hide file tree
Showing 9 changed files with 159 additions and 166 deletions.
4 changes: 2 additions & 2 deletions docs/components.md
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,7 @@ class {
<div>
<h1 key="header">Hello</h1>
<ul>
<for(color in ['red', 'green', 'blue'])>
<for|color| of=['red', 'green', 'blue']>
<li key="colors[]">${color}</li>
</for>
</ul>
Expand Down Expand Up @@ -382,7 +382,7 @@ The `key` attribute can be used to pair HTML elements or UI components that are

```marko
<ul>
<for(user in input.users)>
<for|user| of=input.users>
<li key=user.id>${user.name}</li>
</for>
</ul>
Expand Down
203 changes: 93 additions & 110 deletions docs/core-tags.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,28 +38,24 @@ And support complex expressions:

### `<for>`

The `<for>` tag allows iterating over an array of items:
The `<for>` tag allows you to map an iterable, object properties or a range of numbers into a template. Like some of the other core tags, `<for>` relies on [tag parameters](./syntax.md#tag-body-parameters) to provide data about the current iteration to its body.

```marko
<ul>
<for(color in colors)>
<li>${color}</li>
</for>
</ul>
```
#### Iterating over a list

It may also be applied as an attribute:
Much like the [`for...of`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of) loop in javascript, providing an `of` attribute will iterate over the provided array/iterable. For convenience both the current item, index, and the current list will be provided as [tag parameters](./syntax.md#tag-body-parameters).

```marko
<ul>
<li for(color in colors)>${color}</li>
<for|color, index| of=colors>
<li>${index}: ${color}</li>
</for>
</ul>
```

With either of the above templates, and the following value for `colors`:
With the following value for `colors`:

```js
var colors = ["red", "green", "blue"];
const colors = ["red", "green", "blue"];
```

The output HTML would be the following:
Expand All @@ -72,123 +68,72 @@ The output HTML would be the following:
</ul>
```

#### Loop Status Variable
> **Pro Tip**: The `<for>` tag with an `of` attribute can iterate over any iterable just like the JavaScript [`for...of`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of) loop. In order to iterate over other "array like" objects (ones that just have a `length` property for example) you can use [`Array.from`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from).
>
> ```
> <for|letter, index| of=Array.from({ 0: "a", 1: "b", length: 2 })>
> ${index + 1}: ${letter}
> </for>
> ```
#### Iterating over an objects properties

The `for` directive also supports a loop status variable in case you need to know the current loop index. For example:
Much like the [`for...in`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in) loop in javascript, providing an `in` attribute will iterate over the provided objects properties. For convenience both the current property name and its value will be provided as [tag parameters](./syntax.md#tag-body-parameters).

```marko
<ul>
<li for(color in colors | status-var=loop)>
${color}
${loop.getIndex()+1}) of ${loop.getLength()}
<if(loop.isFirst())> - FIRST</if>
<if(loop.isLast())> - LAST</if>
</li>
<for|name, enabled| in=settings>
<li>${name}: ${enabled ? "on" : "off"}</li>
</for>
</ul>
```

##### Loop Status Methods

###### `getLength()`

Returns the length of the array

###### `getIndex()`

Returns the current loop index

###### `isFirst()`

Returns `true` if the current index is the first index, otherwise `false`

###### `isLast()`

Returns `true` if the current index is the last index, otherwise `false`

#### Loop Separator
With the following value for `settings`:

Used for separating values in a loop by characters. The first element will not
be prefixed and the last element will not be suffixed with the `separator`:

```marko
<div>
<!-- Output: red, green, blue -->
<span for(color in colors | separator=", ") style="color: ${color}">
${color}
</span>
</div>
```js
const settings = {
"Dark Mode": false,
Fullscreen: true
};
```

#### Range Looping

A range can be provided in the following format; `<var-name> from <from> to <to>[ step <step>]`.

The `from`, `to` and `step` values must be numerical expressions. If not specified, step defaults to 1.
The output HTML would be the following:

```marko
```html
<ul>
<li for(i from 0 to 10)>
${i}
</li>
<li>Dark Mode: off</li>
<li>Fullscreen: on</li>
</ul>
```

#### Iterating between a range of numbers

The final variant allows you to iterate between two numbers. You must provide a `from` and `to` attribute, along side an optional `step` attribute. If not specified, `step` defaults to 1. For convenience both the current number in the range will be provided as [tag parameters](./syntax.md#tag-body-parameters).

```marko
<ul>
<li for(i from 0 to 10 step 2)>
${i}
</li>
<for|i| from=0 to=10>
<li>${i}</li>
</for>
</ul>
```

```marko
<ul>
<li for(i from 0 to myArray.length-1)>
${myArray[i]}
</li>
<for|i| from=0 to=10 step=2>
<li>${i}</li>
</for>
</ul>
```

#### Property Looping

```marko
<ul>
<li for(name, value in settings)>
<b>${name}</b>: ${value}
</li>
<for|i| from=0 to=(myArray.length - 1)>
<li>${myArray[i]}</li>
</for>
</ul>
```

#### Native JavaScript for-loop

```marko
<for(var i=1; i<=3; i++)>
${i}
</for>
```

#### Custom Iterator

```marko
static function reverseIterator(arrayList, callback) {
for(var i=arrayList.length-1; i>=0; i--){
callback(arrayList[i]);
}
}
<div for(item in ['a', 'b', 'c'] | iterator=reverseIterator)>
${item}
</div>
```

Output:

```html
<div>c</div>
<div>b</div>
<div>a</div>
```

### `<while>`

Any element can be repeated until a condition is met by using the `while` directive. The directive can be applied as an element or as an attribute.
Expand Down Expand Up @@ -356,28 +301,66 @@ Special HTML characters will _not_ be escaped since the file is expected to be a

### `<macro>`

Parameterized macros allow for reusable fragments within an HTML template.
A macro can be defined using the `<macro>` directive.
Macro's allow for reusable fragments within an HTML template.
A macro can be defined using the `<macro>` tag, with a `name` attribute.

```marko
<macro greeting(name, count)>
Hello ${name}! You have ${count} new messages.
<macro name="greeting">
<span>Welcome!</span>
</macro>
```

The above macro can then be invoked as part of any expression. The following
sample template shows how to use macro functions inside expressions:
The above macro can then be used as if it was a regular `greeting` tag.

```marko
<macro greeting(name, count)>
Hello ${name}! You have ${count} new messages.
<greeting/>
<greeting/>
// Becomes
<span>Welcome!</span>
<span>Welcome!</span>
```

Macro's become more useful when combined with [tag parameters](./syntax.md#tag-body-parameters), allowing for more complex templates like so:

```marko
<macro|{ name, count }| name="greeting">
<span>Hello ${name}! You have ${count} new messages.</span>
</macro>
```

This time the `<greeting>` macro is able to receive parameters from the outside, in this case `name` and `count`.

```marko
<greeting name="Frank" count=20/>
// Becomes
<span>
Hello Frank! You have 10 new messages.
</span>
```

Macro's receive input similar to the root template, including a `renderBody` for displaying any provided body content.

```marko
<macro|{ renderBody }| name="special-heading">
<h1>
<${renderBody}/>!
</h1>
</macro>
<p>
<greeting("John", 10)/>
<special-heading>
Hello
</special-heading>
</p>
// Becomes
<p>
<!-- Or, using named attributes: -->
<greeting name="Frank" count=20/>
<h1>
Hello!
</h1>
</p>
```

Expand Down
12 changes: 6 additions & 6 deletions docs/marko-vs-react.md
Original file line number Diff line number Diff line change
Expand Up @@ -397,8 +397,8 @@ JSX is syntactic sugar on top of JavaScript, but it requires expressions, so
simple things like an `if/else/for` statement don’t work on their own within a JSX element. As
a result, you must either use a ternary expression, an immediately invoked
function expression, function call expression, or the experimental `do {}` expression
(stage 0 at the time of writing). This is not an issue for Marko, and directives
such as `if()` and `for()` can be used anywhere as shown below:
(stage 0 at the time of writing). This is not an issue for Marko, and tags
such as `if()` and `for` can be used anywhere as shown below:

#### React JSX

Expand Down Expand Up @@ -474,7 +474,7 @@ function renderColors(colors) {

```marko
<ul>
<for(color in colors)>
<for|color| of=colors>
<li.color style={ backgroundColor: color }>
${color}
</li>
Expand Down Expand Up @@ -508,7 +508,7 @@ favor of indentation. Here’s how the Marko syntax options compare:

```marko
<ul>
<for(color in colors)>
<for|color| of=colors>
<li>${color}</li>
</for>
</ul>
Expand All @@ -518,15 +518,15 @@ favor of indentation. Here’s how the Marko syntax options compare:

```marko
ul
for(color in colors)
for|color| of=colors
li -- ${color}
```

#### Marko mixed syntax

```marko
ul
for(color in colors)
for|color| of=colors
<li>${color}</li>
```

Expand Down
Loading

0 comments on commit 22056e6

Please sign in to comment.