# fields

field_name: text
field_value:
Indexer modules maintain indexes of tiddlers organized in a manner that's more efficient for different types of access, typically to speed up things like certain filter operators.  An example of this would be the tag indexer - it's much faster to maintain a lookup table listing which tiddlers have a given tag than to iterate over //all// of the tiddlers in a wiki and ask each of them if they have the tag you're interested in!

Indexer modules have a `module-type` of `indexer`, and the indexers that are included with TiddlyWiki can be found under `core/modules/indexers`.

! Methods

Indexer modules must export a constructor function, which takes the current wiki object as its only argument.  The object built by the construction function must implement the following methods:

!! `init()`

This performs any initial setup required by an indexer.

!! `rebuild()`

This rebuilds an index from scratch, usually after a large number of changes have happened to a wiki.

!! `update(updateDescriptor)`

This is called every time a tiddler is added, changed, or deleted.  The `updateDescriptor` value is an object with two fields - `old` and `new` - which represent the pre-update and post-update state of the tiddler, respectively.  Each of these has three fields of their own:

  * `tiddler` - the state of the tiddler (may be `null`)
  * `shadow` - a boolean indicating whether or not the tiddler is a shadow
  * `exists` - a boolean indicating whether or not the tiddler exists

For example, let's say you have an indexer `idx` and you create a tiddler T with the text "test" - that would result in your indexer's `update` method being called like this:

```javascript
idx.update({
  old: { tiddler: null, shadow: false, exists: false },
  new: { tiddler: new $tw.Tiddler({title: 'T', text: 'test'}), shadow: false, exists: true }
});
```

If you then change the text from "test" to "testing", `update` would be called like this:

```javascript
idx.update({
  old: { tiddler: new $tw.Tiddler({title: 'T', text: 'test'}), shadow: false, exists: true },
  new: { tiddler: new $tw.Tiddler({title: 'T', text: 'testing'}), shadow: false, exists: true }
});
```

And finally, if you delete T, `update` will be called like this:

```javascript
idx.update({
  old: { tiddler: new $tw.Tiddler({title: 'T', text: 'testing'}), shadow: false, exists: true },
  new: { tiddler: null, shadow: false, exists: false }
});
```


field_name: text
field_value:
\define showTrees(wikitext)
<table>
<thead>
<tr><th>wiki text</th><th>html</th><th>renders as</th></tr>
</thead>
<tbody>
<tr>
<td>`$wikitext$`</td>
<td>
<$wikify name=html text="""$wikitext$""" output=html mode=inline>
<$text text=<<html>>/>
</$wikify>
</td>
<td>$wikitext$</td>
</tr>
</tbody>
</table>

<table>
<thead>
<tr><th>parse tree</th><th>widget tree</th></tr>
</thead>
<tbody>
<tr>
<td style="vertical-align: text-top">
<pre><code>
<$wikify name=parsetree text="""$wikitext$""" output=parsetree mode=inline>
<<parsetree>>
</$wikify>
</code></pre>
</td>
<td style="vertical-align: text-top">
<pre><code>
<$wikify name=widgettree text="""$wikitext$""" output=widgettree mode=inline>
<<widgettree>>
</$wikify>
</code></pre>
</td>
</tr>
</tbody>
</table>
\end

! Introduction

Until now the examples have covered only simple, leaf widgets, but widgets can be arranged into a hierarchy. Compared to a leaf-only widget, widget classes which support having children must contain code to instantiate the children.

Not all widgets need to support having children. Widgets whose only purpose is to integrate third party javascript libraries, for example may not need it.

! wiki text ⇨ parse tree ⇨ widget tree ⇨ DOM tree

# [[wiki text|https://tiddlywiki.com/#WikiText]] - Users write content in tiddlers using wiki text.
# [[parse tree|https://tiddlywiki.com/dev/#ParsingMechanism]] - A parse tree is a JSON data structure describing the wiki text. Wiki text can be converted into a parse tree using `this.wiki.parseText`.
# ''widget tree'' - Most items in the parse tree correspond to one or more items in the widget tree. The `this.makeChildWidgets` method is used to convert the parse tree into a widget tree.
# [[DOM tree|https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model/Introduction]] - A DOM tree is a standard javascript datastructure used by browsers to display a web page. The `this.renderChildren` method is used to instantiate the widget class and then render each widget in the widget tree. If a given widget will be visible in the browser, then one or more DOM nodes will be created.

!Examples

!! Simple trees without nesting

[[Widgets in wiki text|https://tiddlywiki.com/#Widgets%20in%20WikiText]] have a syntax similar to html (i.e. `<$list/>`). But all [[wiki markup|https://tiddlywiki.com/#WikiText]] is seen by the tiddlywiki code as widgets.

Even a simple string with no special syntax will be treated as a widget. In this case a widget of type `text`:

<<showTrees """hello""">>

The above bare string of text is mostly just a synonym for this widget syntax:

<<showTrees """<$text text=hello/>""">>

Some of the details of the parseTree and widgetTree are different in the two examples, but the general structure is the same and the rendered output is the same.

In these two simple examples, there is no nesting and so no child widgets are created. 

!! Trees with one level of nesting

This next example shows the structure for bold wiki syntax. It is still simple, but does introduce one level of nesting: `element`→`text`

The wiki syntax for bold converts to the standard html element `strong`. Any standard html element is represented in tiddlywiki as a widget of type `element`:

<<showTrees """''bold''""">>

Another example showing one level of nesting (`link`→`text`):

<<showTrees """<$link to=atiddler>link</$link>""">>

!!Widgets with no DOM contribution
Not all widgets contribute items to the DOM. The purpose of some widgets is to affect the display of descendant widgets by changing some state. The `$set` widget for example sets a variable which will be accessible to the descendant widgets:

<<showTrees """<$set name=myvar value=hi/>""">>

Nothing is rendered and there is no html, but the parse tree and widget tree contain information about the variable.

!! Dynamic widget children using this.wiki.parseText

In all the examples so far, there has been a close mapping between the nesting structure of the parse tree and the widget tree. If the item is in the parse tree, then it is in the widget tree. If the parse tree item has children, then the widget tree has the same number of children.

However, there are several examples of widgets in which more levels of nesting are created dynamically during the widget rendering process

The `$macrocall` widget is one example:

<<showTrees """<$macrocall $name=now/>""" >>

The parse tree has just a single type=$macrocall element with no children. The widget tree has that same type=$macrocall element, but it also has a child widget which wasn't in the parse tree.

In all cases, the `$macrocall` widget calls the given macro and then calls `this.wiki.parseText` on the output. This results in a new parse tree which is used to make the child widgets.

In this particular case, the `now` macro is called. It returns a simple string of text, so when it is parsed the result causes the creation of a single child text widget containing the current date and time.

!! Widgets which do not support nesting

Just as some widgets can cause widget trees to have more nesting than the parse tree, some widgets can cause widget trees to have less nesting.

This happens when there is no use for the widget to have any children. The `$text` widget, for example, has no use for displaying any descendants.

This behavior is accomplished by not calling the `makeChildWidgets` method. Without that method call, the child widgets are not created from the child parse tree items. For example:

<$macrocall $name=showTrees wikitext="""<$text text="hi">ignored child text</$text>"""/>

Since the `$text` widget does not have a call to `makeChildWidgets`, 'ignored child text' above is present in the parse tree, but not in the widget tree.

!Reference

|!method|!when to call|!what it does|
|`makeChildWidgets`|directly or indirectly from `render` method|converts child parse tree items into widget tree items|
|`renderChildren`|directly or indirectly from `render` method, after the `makeChildWidgets` call|calls the `render` method of the child widget|
|`refreshChildren`|directly or indirectly from `refresh` method, only needed if `refreshSelf` is not called|calls the `refresh` method of of the child widgets so they can check if refresh is needed|
|`this.wiki.parseText`|pass the output parse tree to `makeChildWidgets`|converts the given text to a parse tree...only needed for dynamically constructed parsetree|

|!example call|!purpose|!widgets using this approach|
|`this.makeChildWidgets()`|construct child widgets from the static parse tree|[[$link|$:/core/modules/widgets/link.js]], [[$button|$:/core/modules/widgets/button.js]], etc.|
|`this.makeChildWidgets(parseTreeNodes)`|construct child widgets from a dynamic parse tree|[[$list|$:/core/modules/widgets/list.js]], [[$transclude|$:/core/modules/widgets/transclude.js]], [[$macrocall|$:/core/modules/widgets/macrocall.js]], etc|
|`this.renderChildren(parent, nextSibling)`|when the widget adds nothing to the dom, just pass the `render` arguments through to the children|[[$set|$:/core/modules/widgets/set.js]], [[$importvariables|$:/core/modules/widgets/importvariables.js]], [[$tiddler|$:/core/modules/widgets/tiddler.js]], [[$wikify|$:/core/modules/widgets/wikify.js]], etc.|
|`this.renderChildren(domNode, null)`|passes the dom node generated by this widget into the children|[[$link|$:/core/modules/widgets/link.js]], [[$button|$:/core/modules/widgets/button.js]], etc|


field_name: text
field_value:
<!-- The innerwiki doesn't refresh on its own when tiddlers on the outside change, so use the list widget to force a dependency -->
<$list name=refresh filter=[[donothing.js]get[text]]>
<$innerwiki width="600" height="400" style="width:100%;">
	<$data title="$:/DefaultTiddlers" text="[[do nothing widget]]"/>
	<$data $tiddler=donothing.js/>
	<$data title="do nothing widget" text="""
```
<$donothing/>
```

Renders as:

<$donothing/>
"""/>
</$innerwiki>
</$list>


field_name: text
field_value:
In order to define a widget in a tiddler, the tiddler must satisfy these requirements:

* type field is application/javascript
* module-type field is widget
* the text field contains the javascript code

The [[donothing.js]] tiddler fulfills the requirements and its code looks like this:
{{donothing.js}}
That code does 2 key things:

* Imports the core Widget class ([[$:/core/modules/widgets/widget.js]])
* exports the class in an attribute with the name we want our widget to have (`donothing`)

Here's what it looks like:
{{Do nothing widget demo}}
And it worked. No error message this time.

''Exercise'': Modify [[donothing.js]] and [[Do nothing widget demo]] so the widget is named `noop` instead of `donothing`


field_name: text
field_value:
<!-- The innerwiki doesn't refresh on its own when tiddlers on the outside change, so use the list widget to force a dependency -->
<$list name=refresh filter=[[hello.js]get[text]]>
<$innerwiki width="600" height="400" style="width:100%;">
	<$data title="$:/DefaultTiddlers" text="[[hello world widget]]"/>
	<$data $tiddler=hello.js/>
	<$data title="hello world widget" text="""
```
<$hello/>
```

Renders as:

<$hello/>
"""/>

</$innerwiki>
</$list>


field_name: text
field_value:
Now let's create a widget which actually has output.

When tiddlywiki encounters a widget definition like `<$hello>` it will create an object which is an instance of the class which is exported by the widget code. 

In addition to creating an instance of the class, tiddlywiki will call the render method of the resulting object. The render method is expected to create a dom node which will be display in place of the widget.

In the `donothing` example the core widget was exported. The core widget class doesn't have a render method which creates a dom node and that's why there is no output. Getting output requires writing a widget class which inherits from the core `Widget` class. Code in the render method of this class will display the hello world message.

The [[hello.js]] tiddler has code which accomplishes that:
{{hello.js}}
The code for importing the core widget class remains, but now we also have code to create our own class which inherits from it. In addition an implementation of the `render` method is included. Here is the result:
{{Hello World demo}}


field_name: text
field_value:
! Introduction
This tutorial provides step-by-step, interactive examples of how to write code for tiddlywiki widgets. The demo javascript code can be modified without having to reload the entire wiki.

Intended audience:

# Those who know tiddlywiki well and know programming and javascript and want to write their own widget. I don't make any effort to explain javascript here. For that you will need other resources.
# Those who know tiddlywiki well and don't know javascript, but want to understand more about how tiddlywiki works. You should be able to skim through and interact with the demos and learn something.

!The tutorial
*[[Undefined widget tutorial]]
*[[Do nothing widget tutorial]]
*[[Hello World widget tutorial]]
*[[Widget refresh tutorial part I]]
*[[Widget refresh tutorial part II]]
*[[Widget refresh tutorial part III]]
*[[Widget attributes tutorial part I]]
*[[Widget attributes tutorial part II]]
*[[Child widgets tutorial]]

! Notes

tiddlywiki doesn't support dynamically reloading javascript. If you change a javascript tiddler, then you need to save and reload  the wiki before the changes will take affect.

To avoid the need for such reloads, the excellent [[innerwiki plugin|https://tiddlywiki.com/prerelease/plugins/tiddlywiki/innerwiki/]] is used. This allows an inner wiki to be created from a subset of tiddlers in the outer wiki. Each time the inner wiki is refreshed, its entire wiki is reloaded and the javascript changes in the inner wiki will take affect.

Without the need for reloads, a tiddlywiki instance with the [[innerwiki plugin|https://tiddlywiki.com/prerelease/plugins/tiddlywiki/innerwiki/]] installed works great as a playground for interacting with tiddlywiki javascript.

! Other documentation on writing TW widgets

*WidgetModules
*[[Widgets]]


field_name: text
field_value:
<$innerwiki width="600" height="400" style="width:100%;">
	<$data title="$:/DefaultTiddlers" text="[[Undefined widget]]"/>
	<$data title="Undefined widget" text="""
```
<$donothing/>
```

Renders as:

<$donothing/>
"""/>
</$innerwiki>


field_name: text
field_value:
Let's start be defining a minimal widget which does nothing. It doesn't support any attributes, no child elements, and it doesn't output anything. The name of the widget will be `donothing`. If it does nothing, then how can we verify after writing the code that we accomplished anything? Well, let's see what happens when an undefined widget is referenced.

{{Undefined widget demo}}

Since we haven't written the code, the attempt to render the widget gives an undefined widget error. So we will know the donothing code accomplishes something if we don't get the undefined widget error when rendering.


field_name: text
field_value:
<!-- The innerwiki doesn't refresh on its own when tiddlers on the outside change, so use the list widget to force a dependency -->
<$list name=refresh filter=[[hello-attribute.js]get[text]]>
<$innerwiki width="600" height="400" style="width:100%;">
	<$data title="$:/DefaultTiddlers" text="[[hello world widget]]"/>
	<$data $tiddler=hello-attribute.js/>
	<$data title="hello world widget" text="""
```
<$hello/>
```

Renders as:

<$hello/>

---

```
<$hello message="pale blue dot"/>
```

Renders as:

<$hello message="pale blue dot"/>

---

<$edit-text focus=yes tiddler=test tag=input/>

```
<$hello message={{test!!text}}/>
```

Renders as:

<$hello message={{test!!text}}/>

"""/>

	<$data title="test" text="Alice"/>

</$innerwiki>
</$list>


field_name: text
field_value:
<!-- The innerwiki doesn't refresh on its own when tiddlers on the outside change, so use the list widget to force a dependency -->
<$list name=refresh filter=[[hello-attribute-optimized.js]get[text]]>
<$innerwiki width="600" height="400" style="width:100%;">
	<$data title="$:/DefaultTiddlers" text="[[hello world widget]]"/>
	<$data $tiddler=hello-attribute-optimized.js/>
	<$data title="hello world widget" text="""
```
<$hello/>
```

Renders as:

<$hello/>

---

```
<$hello message="pale blue dot"/>
```

Renders as:

<$hello message="pale blue dot"/>

---

<$edit-text focus=yes tiddler=test tag=input/>

```
<$hello message={{test!!text}}/>
```

Renders as:

<$hello message={{test!!text}}/>

"""/>

	<$data title="test" text="Alice"/>

</$innerwiki>
</$list>


field_name: text
field_value:
So far none of the widgets we've implemented have had any code for handling widget attributes A vast majority of useful widgets will need to support attributes in order to make them useful.

As an example, let's change the Hello World widget so it can greet not just the world, but whoever/whatever the user wants. To do that we can add support for an attribute named `what` and call it like `<$hello what="pale blue dot"/>`.

The tiddlywiki widget class provides methods `computeAttributes` and `getAttribute` which can together be used by the widget code to discover what values are passed into the widget.

The `computeAttributes` and `getAttribute` methods can be called like this (the second parameter to `getAttribute` will be used as the default value if the user doesn't provide that attribute in the widget call):

```javascript
this.computeAttributes();
var message = this.getAttribute("message", "World");
```

Then the `message` variable can be used to construct the Hello XXX string:

```javascript
var textNode = this.document.createTextNode("Hello, " + message + "!");
```

The original [[hello.js]] code only implements a `render` method. The `refresh` method is not needed because the output from the widget can never be different...it will always be "Hello, World!".

Even with a `message` attribute, you might think the `render` by itself is enough. After all, the value of the input parameter `message` can only be changed by modifying the wiki text which means the tiddler will be redisplayed from scratch.

However, tiddlywiki has a syntax which allows parameter values to vary without modifying the wiki text. See https://tiddlywiki.com/#Widgets%20in%20WikiText for details. As one example, if the widget were called like `<$hello message={{MyTiddler!!field}}/>`, then every time the `field` field of `MyTiddler` were modified, only the `refresh` method would be called. Therefore, in order to get the widget display to update, the refresh method needs to be implemented.

If the `computeAttributes` and `getAttribute` calls are placed in the `render` method then we can implement a performance unoptimized version of refresh as was done in [[Widget refresh tutorial part II]]:

```javascript
/*
A widget with optimized performance will selectively refresh, but here we refresh always
*/
MyWidget.prototype.refresh = function(changedTiddlers) {
	// Regenerate and rerender the widget and
	// replace the existing DOM node
	this.refreshSelf();
	return true;
};
```

The full code can be seen at [[hello-attribute.js]] and here is the result ([[Widget attributes demo I]]):

{{Widget attributes demo I}}

The third example above is the only one which requires the refresh method in order to behave properly.


field_name: text
field_value:
This example will build on the previous one. The only modification will be to add a check to the `refresh` method. The `refreshSelf` will only be called if a change to the attributes is detected.

The `computeAttributes` method returns a Javascript object containing properties for each attribute which has changed. So a check like `if (changedAttributes.attr1 || changedAttributes.attr2 || changedAttributes.attr3)` etc. can be used to detect the change.  See the refresh method in [[$:/core/modules/widgets/view.js]] for an example showing the check for multiple attributes.

For this example, `message` is the only attribute implemented.

```javascript
/*
Refresh if the attribute value changed since render
*/
MyWidget.prototype.refresh = function(changedTiddlers) {
	// Find which attributes have changed
	var changedAttributes = this.computeAttributes();
	if (changedAttributes.message) {
		this.refreshSelf();
		return true;
	} else {
		return false;
	}
};
```

The full code can be seen at [[hello-attribute-optimized.js]] and here is the result ([[Widget attributes demo II]]):

{{Widget attributes demo II}}

The visible behavior here should be identical to the unoptimized behavior of the previous tutorial.


field_name: text
field_value:
<!-- The innerwiki doesn't refresh on its own when tiddlers on the outside change, so use the list widget to force a dependency -->
<$list name=refresh filter=[[tiddlerfield-norefresh.js]get[text]]>
<$innerwiki width="600" height="400" style="width:100%;">
	<$data title="$:/DefaultTiddlers" text="[[tiddler field widget]]"/>
	<$data title="test" text="type new text here"/>
	<$data $tiddler=tiddlerfield-norefresh.js/>
	<$data title="tiddler field widget" text="""
<$edit-text focus=yes tiddler=test tag=input/>
<$button set="!!refresh" setTo={{test}}>Force refresh</$button>
<$list filter="[{!!refresh}]">

<div>
<div style="display:inline-block;width: 49%;vertical-align: text-top;word-wrap: break-word;}">

```
<$tiddlerfield/>
```

Renders as:

<$tiddlerfield/>
</div>
<div style="display:inline-block;width: 49%;vertical-align: text-top;word-wrap: break-word;}">

```
<$view tiddler="test"/>
```

Renders as:

<$view tiddler="test"/>
</div>
</div>
</$list>
"""/>

</$innerwiki>
</$list>


field_name: text
field_value:
<!-- The innerwiki doesn't refresh on its own when tiddlers on the outside change, so use the list widget to force a dependency -->
<$list name=refresh filter=[[tiddlerfield.js]get[text]]>
<$innerwiki width="600" height="400" style="width:100%;">
	<$data title="$:/DefaultTiddlers" text="[[tiddler field widget]]"/>
	<$data title="test" text="type new text here"/>
	<$data $tiddler=tiddlerfield.js/>
	<$data title="tiddler field widget" text="""
<$edit-text focus=yes tiddler=test tag=input/>
    
<div>
<div style="display:inline-block;width: 49%;vertical-align: text-top;word-wrap: break-word;}">

```
<$tiddlerfield/>
```

Renders as:

<$tiddlerfield/>
</div>
<div style="display:inline-block;width: 49%;vertical-align: text-top;word-wrap: break-word;}">

```
<$view tiddler="test"/>
```

Renders as:

<$view tiddler="test"/>
</div>
"""/>

</$innerwiki>
</$list>


field_name: text
field_value:
<!-- The innerwiki doesn't refresh on its own when tiddlers on the outside change, so use the list widget to force a dependency -->
<$list name=refresh filter=[[refreshcount.js]get[text]]>
<$innerwiki width="600" height="400" style="width:100%;">
	<$data title="$:/DefaultTiddlers" text="[[refresh count widget]]"/>
	<$data title="test" text="Text field of tiddler='test'"/>
	<$data $tiddler=refreshcount.js/>
	<$data title="refresh count widget" text="""

*<$button set="test!!test" setTo="hello">Modify a different tiddler</$button>
*<$button set="!!test" setTo="hello">Modify this tiddler</$button>
*<$edit-text focus=yes tiddler=test tag=input/>

<div>
<div style="display:inline-block;width: 49%;vertical-align: text-top;word-wrap: break-word;}">

```
<$refreshcount/>
```

Renders as:

<$refreshcount/>
</div>

<div style="display:inline-block;width: 49%;vertical-align: text-top;word-wrap: break-word;}">

```
<$list filter="[[test]get[text]]">
<<currentTiddler>><br>
<$refreshcount/>
</$list>
```

Renders as:

<$list filter="[[test]get[text]]">
<<currentTiddler>><br>
<$refreshcount/>
</$list>
"""/>
</div>
</div>
</$innerwiki>
</$list>


field_name: text
field_value:
But what if we want to display dynamic content? How can we display information and keep it up to date as it changes? Let's display the content of a tiddler field.

The [[tiddlerfield-norefresh.js]] which defines the `tiddlerfield` widget is almost the same as [[hello.js]] except for this part:

```javascript
MyWidget.prototype.render = function(parent,nextSibling) {
	this.parentDomNode = parent;
	var text = this.wiki.getTiddlerText("test", "<empty>")
	var textNode = this.document.createTextNode(text);
	parent.insertBefore(textNode,nextSibling);
	this.domNodes.push(textNode);
};
```

Instead of creating the text dom node from a static string, the text field of the `test` tiddler is used. This is similar to using the view widget like this:  `<$view tiddler="test"/>`

Here's how it looks (see [[Widget refresh demo I]] to look at the code):

{{Widget refresh demo I}}

Notice if you change the text in the input box, the output from the `tiddlerfield` widget doesn't change, but the output of the `view` widget does. Only after the ''Force refresh'' button is clicked does the output of `tiddlerfield` update to match the input box contents.

What's going on here? The render method of the widget code is only called by tiddlywiki core when the widget is first created. After that, it isn't called again unless the widget is completely destroyed and then created again. 

The tiddlywiki ~ViewWidget has a properly written `refresh` method so typing in the input box will cause its content to update. However, the `tiddlerfield` widget does not have a `refresh` method at all. It has no way of being notified that the `test` tiddler content has changed. Its output will not change until the ''Force refresh'' button is clicked.

See the next example for an implementation of the `refresh` method for the `tiddlerfield` widget.

The code for the refresh button looks like this:

```
<$button set="!!refresh" setTo={{test}}>Force refresh</$button>
```

and the widgets are enclosed in a list widget like this:

```
<$list filter="[{!!refresh}]">...</$list>
```

When the button is clicked the field `refresh` in the containing tiddler is modified and it causes the children of the list widget to be created from scratch. The render method is called and the output of the `tiddlerfield` widget updates.


field_name: text
field_value:
This example is like [[Widget refresh tutorial part I]] except the widget output will be automatically refreshed when the tiddler field changes.

[[tiddlerfield.js]] is the same as [[tiddlerfield-norefresh.js]], except this `refresh` method is added:

```javascript
/*
A widget with optimized performance will selectively refresh, but here we refresh always
*/
MyWidget.prototype.refresh = function(changedTiddlers) {
	// Regenerate and rerender the widget and
	// replace the existing DOM node
	this.refreshSelf();
	return true;
};
```

The `refreshSelf` method called above is implemented by the core widget class and it takes care of cleaning the old dom node and calling the render function.

Here is the result ([[Widget refresh demo II]]):

{{Widget refresh demo II}}

And now any typing into the input box will cause both the `tiddlerfield` and the `view` widget output to refresh immediately.

Note this is a naive version of `refresh`. It unconditionally refreshes itself. This is far from optimal since the `refresh` method for all visible widgets is called every time the tiddler store changes. But the way we've defined our widget, the output ONLY depends on the tiddler titled `text`.

In tiddlywiki the tiddler store is used for everything and almost any interaction will result in an update to the store. This means almost any interaction will cause the refresh method to be called. If you type into the search box, for example, the `tiddlerfield` widget will be refreshed with every keystroke.

Adding and removing dom elements is a relatively expensive operation, so if someone has used the list widget to create a few hundred instances of this widget, then such tiddlywiki interactions might gain a noticable lag. Therefore, it usually makes sense to avoid modifying the dom when possible by writing a smarter `refresh` method. 

''Exercise'' - change the refresh method above to only call `refreshSelf` when the `changedTiddlers` input array contains `test` as one of its entries (Hint: see the refresh method in $:/core/modules/widgets/view.js for an example).


field_name: text
field_value:
This tutorial is intended to demonstrate a few examples of when calls to the `refresh` method happen vs. when a widget is recreated from scratch.

This is accomplished with a [[refreshcount.js]] widget which sets a counter to zero when the widget is created and increments the counter every time the `refresh` method is called. Here is the full code:

{{refreshcount.js}}

These are the key parts of the code from above:

```javascript
this.refreshCount = 0;
this.document.createTextNode(this.refreshCount + " refreshes");
this.refreshCount++;
```

In the following example (see [[Widget refresh demo III]] for the code), two instances of the `refreshcount` widget are created. One at the top level and the other inside a list widget whose filter results depend on the value in the `text` field of the `test` widget. The tiddler store can be modified in a few ways via two buttons and an input box:
{{Widget refresh demo III}}

* ''Modify a different tiddler'' - every time this button is clicked, both counters increment, indicating the `refresh` method is being called
* ''Modify this tiddler'' - clicking this button modifies the tiddler itself. In earlier ~TiddlyWiki versions that caused both widgets to be recreated from scratch and the counters are thereby reset to zero. Since [[version 5.2.0|https://tiddlywiki.com/#Release%205.2.0]] modifying another field in this tiddler does not cause the widgets to be recreated and the counters are not reset.
*  ''Text field of tiddler='test''' - typing text into the input box causes the counter in the standalone `refreshcount` widget to be incremented. But the other instance of the widget is embedded inside a list widget whose filter output depends on the value of the tiddler field which is being modified. This causes it to recreate its children from scratch and the counter is reset every time. So with every keystroke, the counter on the left is incremented, but the counter on the right goes to/stays at zero.


field_name: text
field_value:
/*\

Library function for creating widget using a dom creating function

\*/
(function() {

/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";

var Widget = require("$:/core/modules/widgets/widget.js").widget;

function createDomWidget(domCreatorFunction) {

	var MyWidget = function(parseTreeNode, options) {
		this.initialise(parseTreeNode, options);
	};

	/*
	Inherit from the base widget class
	*/
	MyWidget.prototype = new Widget();

	/*
	Render this widget into the DOM
	*/
	MyWidget.prototype.render = function(parent, nextSibling) {
		this.parentDomNode = parent;
		var domNode = domCreatorFunction(this.document);
		parent.insertBefore(domNode, nextSibling);
		this.domNodes.push(domNode);
	};

	/*
	A widget with optimized performance will selectively refresh, but here we refresh always
	*/
	MyWidget.prototype.refresh = function(changedTiddlers) {
		// Regenerate and rerender the widget and replace the existing DOM node
		this.refreshSelf();
		return true;
	};

	return MyWidget;
}
module.exports = createDomWidget;
})();


field_name: text
field_value:
/*\

Do nothing widget

\*/
(function(){

/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";

var Widget = require("$:/core/modules/widgets/widget.js").widget;

exports.donothing = Widget;

})();


field_name: text
field_value:
/*\

Hello, World widget

\*/
(function() {

/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";

var Widget = require("$:/core/modules/widgets/widget.js").widget;

var MyWidget = function(parseTreeNode, options) {
	this.initialise(parseTreeNode, options);
};

/*
Inherit from the base widget class
*/
MyWidget.prototype = new Widget();

/*
Render this widget into the DOM
*/
MyWidget.prototype.render = function(parent, nextSibling) {
	this.parentDomNode = parent;
	this.computeAttributes();
	var message = this.getAttribute("message", "World");
	var textNode = this.document.createTextNode("Hello, " + message + "!");
	parent.insertBefore(textNode, nextSibling);
	this.domNodes.push(textNode);
};

/*
Refresh if the attribute value changed since render
*/
MyWidget.prototype.refresh = function(changedTiddlers) {
	// Find which attributes have changed
	var changedAttributes = this.computeAttributes();
	if (changedAttributes.message) {
		this.refreshSelf();
		return true;
	} else {
		return false;
	}
};

exports.hello = MyWidget;

})();


field_name: text
field_value:
/*\

Hello, World widget

\*/
(function() {

/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";

var Widget = require("$:/core/modules/widgets/widget.js").widget;

var MyWidget = function(parseTreeNode, options) {
	this.initialise(parseTreeNode, options);
};

/*
Inherit from the base widget class
*/
MyWidget.prototype = new Widget();

/*
Render this widget into the DOM
*/
MyWidget.prototype.render = function(parent, nextSibling) {
	this.parentDomNode = parent;
	this.computeAttributes();
	var message = this.getAttribute("message", "World");
	var textNode = this.document.createTextNode("Hello, " + message + "!");
	parent.insertBefore(textNode, nextSibling);
	this.domNodes.push(textNode);
};

/*
A widget with optimized performance will selectively refresh, but here we refresh always
*/
MyWidget.prototype.refresh = function(changedTiddlers) {
	// Regenerate and rerender the widget and
	// replace the existing DOM node
	this.refreshSelf();
	return true;
};

exports.hello = MyWidget;

})();


field_name: text
field_value:
/*\

Hello, World widget

\*/
(function(){

/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";

var Widget = require("$:/core/modules/widgets/widget.js").widget;

var MyWidget = function(parseTreeNode,options) {
	this.initialise(parseTreeNode,options);
};

/*
Inherit from the base widget class
*/
MyWidget.prototype = new Widget();

/*
Render this widget into the DOM
*/
MyWidget.prototype.render = function(parent,nextSibling) {
	this.parentDomNode = parent;
	var textNode = this.document.createTextNode("Hello, World!");
	parent.insertBefore(textNode,nextSibling);
	this.domNodes.push(textNode);
};

exports.hello = MyWidget;

})();


field_name: text
field_value:
/*\

widget to count the number of times this widget refreshes

\*/
(function() {

/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";

var Widget = require("$:/core/modules/widgets/widget.js").widget;

var MyWidget = function(parseTreeNode, options) {
	this.refreshCount = 0;
	this.initialise(parseTreeNode, options);
};

/*
Inherit from the base widget class
*/
MyWidget.prototype = new Widget();

/*
Render this widget into the DOM
*/
MyWidget.prototype.render = function(parent, nextSibling) {
	this.parentDomNode = parent;
	var textNode = this.document.createTextNode(this.refreshCount + " refreshes");
	parent.insertBefore(textNode, nextSibling);
	this.domNodes.push(textNode);
};

MyWidget.prototype.refresh = function(changedTiddlers) {
	// Regenerate and rerender the widget and replace the existing DOM node
	this.refreshCount++;
	this.refreshSelf();
	return true;
};

exports.refreshcount = MyWidget;

})();


field_name: text
field_value:
/*\

Hello, World widget

\*/
(function() {

/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";

var Widget = require("$:/core/modules/widgets/widget.js").widget;

var MyWidget = function(parseTreeNode, options) {
	this.initialise(parseTreeNode, options);
};

/*
Inherit from the base widget class
*/
MyWidget.prototype = new Widget();

/*
Render this widget into the DOM
*/
MyWidget.prototype.render = function(parent, nextSibling) {
	this.parentDomNode = parent;
	var text = this.wiki.getTiddlerText("test", "<empty>")
	var textNode = this.document.createTextNode(text);
	parent.insertBefore(textNode, nextSibling);
	this.domNodes.push(textNode);
};

exports.tiddlerfield = MyWidget;

})();


field_name: text
field_value:
/*\

Hello, World widget

\*/
(function() {

/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";

var Widget = require("$:/core/modules/widgets/widget.js").widget;

var MyWidget = function(parseTreeNode, options) {
	this.initialise(parseTreeNode, options);
};

/*
Inherit from the base widget class
*/
MyWidget.prototype = new Widget();

/*
Render this widget into the DOM
*/
MyWidget.prototype.render = function(parent, nextSibling) {
	this.parentDomNode = parent;
	var text = this.wiki.getTiddlerText("test", "<empty>")
	var textNode = this.document.createTextNode(text);
	parent.insertBefore(textNode, nextSibling);
	this.domNodes.push(textNode);
};

/*
A widget with optimized performance will selectively refresh, but here we refresh always
*/
MyWidget.prototype.refresh = function(changedTiddlers) {
	// Regenerate and rerender the widget and
	// replace the existing DOM node
	this.refreshSelf();
	return true;
};

exports.tiddlerfield = MyWidget;

})();


field_name: text
field_value:
Not all browsers support the latest features of ES2015. The Babel project offers a polyfill that can be included into your TiddlyWiki so those features can be available to your plugins. To do this you will need a copy of the polyfill source.

You can obtain the source either through <<.def "npm">> or downloaded/saved. See the [[Babel Polyfill documentation|https://babeljs.io/docs/usage/polyfill/]] for specific information on installing it.

In your TiddlyWiki editions folder make sure you have a `plugins/babel-polyfill` folder. Then create the `plugins/babel-polyfill/plugin.info` file with the following in it:

```json
{
  "title": "$:/plugins/babel/babel-polyfill",
  "description": "Babel Polyfills for ES2015 support",
  "author": "Your Name Here",
  "core-version": ">=5.0.0"
}
```

Create the folder `plugins/babel-polyfill/files` folder. Then create the `plugins/babel-polyfill/files/tiddlywiki.files` file with the following in it:

```json
{
  "tiddlers": [
    {
      "file": "polyfill.min.js",
      "fields": {
        "title": "$:/plugins/babel/babel-polyfill/polyfill.min.js",
        "type": "application/javascript",
        "module-type": "library",
        "global-module": "true"
      }
    }
  ]
}
```

Now copy the `polyfill.min.js` you downloaded/saved.

<<.tip "If you downloaded this via ''npm'' then it would be available in `./node_modules/babel-polyfill/dist/polyfill.min.js`.">>

Lastly you need a initializer so create the `plugins/babel-polyfill/plugin.js` file with the following in it:

```javascript
/*\
title: $:/plugins/babel/babel-polyfill/plugin.js
type: application/javascript
module-type: startup

Load the babel-polyfill library on startup

\*/

exports.startup = function() {
  $tw.modules.execute('$:/plugins/babel/babel-polyfill/polyfill.min.js');
}
```

<<.warning "Because the polyfill is meant to be used in the browser we need to conditionally load the library which ES2016 doesn't allow. This is why it is written using TiddlyWiki's dependency resolver instead of using ES2015 `import` statements.">>

Now all the //runtime// ES2015 features are available like using `Promise` in your plugin code.

See [[Using ES2016 for Writing Plugins]] on how to use the ES2015 //syntax// for your plugin code.


field_name: text
field_value:
The single file version of ~TiddlyWiki saves the tiddlers within the HTML file. 

Version 5.2.0 of ~TiddlyWiki introduced a new format for how tiddlers are saved within the HTML file.


---

!! Up to and including ~TiddlyWiki v5.1.23

Tiddlers are saved within the HTML file in one of two `<div>` tags depending on whether the TiddlyWiki is configured to encrypt its content or not. 

!!! Without encryption
If the ~TiddlyWiki is not encrypted the data is stored in a `<div>` tag with an `id` attribute of "storeArea".

```html
<div id="storeArea" style="display:none;">
```

Within the store area `<div>`, each tiddler is stored in its own div. 

//Tiddler DIV//

Each tiddler `<div>` has an attribute corresponding to each of the tiddler's fields, except the text field which is saved within a `pre` tag within the `<div>`. Note that all attributes and therefore field names must be lowercase letters, digits or the characters `-` (dash), `_` (underscore) and `.` (period). The only attribute that is required is `title`, all other attributes are optional. All attribute values and the text field within the `pre` tag are HTML encoded.

Example:

```html
<div id="storeArea" style="display:none;">
<div created="20140611153703343" modified="20140611153734589" tags="testTag" testfield="testvalue" title="TestTiddler" type="text/plain">
<pre>testText</pre>
</div>
</div>
```

!!! With encryption

If the ~TiddlyWiki is configured to encrypt its content, the tiddlers are stored as as an encrypted JSON string in a `<pre>` tag with the `id` attribute "encryptedStoreArea". 

```html
<pre id="encryptedStoreArea" type="text/plain" style="display:none;">
```

~TiddlyWiki uses the [[Stanford JavaScript Crypto Library|http://bitwiseshiftleft.github.io/sjcl/]]. 

---

!! From ~TiddlyWiki v5.2.0

From v5.2.0 onwards, ~TiddlyWiki introduces a new JSON based format for the tiddler store area for unencrypted content, while retaining support for the older store area formats described above for backwards compatibility. The store area format remains unchanged for encrypted content.


!!! Without encryption

By default, all tiddlers are now stored as an array of JSON objects inside a `<script>` tag with the `class` attribute "tiddlywiki-tiddler-store" and the `type` "application/json". For better readability, every tiddler object begins on a new line. There are no longer any restrictions on characters that are allowed in tiddler field names. However, `<script>` tag store areas must encode the `<` character to `\u003c`.

```html
<script class="tiddlywiki-tiddler-store" type="application/json">[
{"title":"XLSX Utilities Edition","created":"20161023202301847","modified":"20161023202301847","tags":"Editions","type":"text/vnd.tiddlywiki","text":"The ''XLSX Utilities'' edition of TiddlyWiki contains tools to work with `.XLSX` spreadsheets generated by applications like Microsoft Excel and Google Sheets. It can be used in the browser or under Node.js.\n\nhttps://tiddlywiki.com/editions/xlsx-utils/\r\n"},
{"text":"In accordance with the [[Philosophy of Tiddlers]], documentation tiddlers are typically short and interlinked.\n\nWhen a tiddler seems as if it needs to contain subheadings, this is often a sign that it should in fact be split into several tiddlers. But it is reasonable for a [[reference tiddler|Reference Tiddlers]] to consist of an untitled introductory section followed by a titled section of details.\n\nConsistency of terminology is essential if the reader is not to become confused. Consistent typography and punctuation lend a professional quality to the documentation. Macros can improve the consistency and maintainability of the text.\n\nUse numbered lists for step-by-step instructions, and bullet points for lists whose order is arbitrary. Use a definition list in preference to a bulleted list if each bulleted item would begin with a term and a colon. If at all possible, avoid burdening the reader with a nested list.\n\nUse a table when information naturally falls into three or more columns, and also for lists of parameters, attributes, etc in [[reference tiddlers|Reference Tiddlers]].\n\nAvoid periods at the end of list items, headings and table cell text.\n\nThe documentation describes the current reality of ~TiddlyWiki. Avoid discussing future aspirations.\n","title":"Tiddler Structure","tags":"[[Improving TiddlyWiki Documentation]]","modified":"20210207124737959","created":"20150110183300000"}
]</script>
```

To retain compatibility with external tools that might insert tiddlers by directly manipulating the ~TiddlyWiki HTML file, the older format `<div>` store area is still present in the HTML file immediately after the new `<script>` tag store area:


```html
<script class="tiddlywiki-tiddler-store" type="application/json">[
{"title":"XLSX Utilities Edition","created":"20161023202301847","modified":"20161023202301847","tags":"Editions","type":"text/vnd.tiddlywiki","text":"The ''XLSX Utilities'' edition of TiddlyWiki contains tools to work with `.XLSX` spreadsheets generated by applications like Microsoft Excel and Google Sheets. It can be used in the browser or under Node.js.\n\nhttps://tiddlywiki.com/editions/xlsx-utils/\r\n"},
{"text":"In accordance with the [[Philosophy of Tiddlers]], documentation tiddlers are typically short and interlinked.\n\nWhen a tiddler seems as if it needs to contain subheadings, this is often a sign that it should in fact be split into several tiddlers. But it is reasonable for a [[reference tiddler|Reference Tiddlers]] to consist of an untitled introductory section followed by a titled section of details.\n\nConsistency of terminology is essential if the reader is not to become confused. Consistent typography and punctuation lend a professional quality to the documentation. Macros can improve the consistency and maintainability of the text.\n\nUse numbered lists for step-by-step instructions, and bullet points for lists whose order is arbitrary. Use a definition list in preference to a bulleted list if each bulleted item would begin with a term and a colon. If at all possible, avoid burdening the reader with a nested list.\n\nUse a table when information naturally falls into three or more columns, and also for lists of parameters, attributes, etc in [[reference tiddlers|Reference Tiddlers]].\n\nAvoid periods at the end of list items, headings and table cell text.\n\nThe documentation describes the current reality of ~TiddlyWiki. Avoid discussing future aspirations.\n","title":"Tiddler Structure","tags":"[[Improving TiddlyWiki Documentation]]","modified":"20210207124737959","created":"20150110183300000"}
]</script><div id="storeArea" style="display:none;"></div>
```

Any tiddlers in the older format `<div>` store area are also loaded before tiddlers from the new `<script>` store area. 

!!! Multiple store areas and precedence

Tiddlers from the new `<script>` tag store areas are loaded in the order of their store areas in the HTML file. Therefore if the same tiddler exists in two different `<script>` tag store areas, the tiddler from the later store area takes precedence. Note however that tiddlers from `<script>` tag store areas always take precedence over tiddlers from the older format  `<div>` store area. Therefore a tiddler from the older `<div>` store area can never overwrite a tiddler from  a `<script>` tag store area.

Note that all `<script>` tags with the `class` attribute "tiddlywiki-tiddler-store" that precede the `$:/boot.js` module in the HTML file will have their content parsed as JSON and loaded as tiddlers.

This allows external tools to easily insert tiddlers into an HTML file by prepending an additional `<script>` tag(s) at the very start of the HTML file:

```html
<script class="tiddlywiki-tiddler-store" type="application/json">[
{"created":"20210525212411223","text":"This is some test text","tags":"[[test tag]] [[another tag]]","title":"My new tiddler to insert","modified":"20210525212430577"}
]</script>
<!doctype html>
...
```

Although invalid HTML, all known browsers will silently move the script tag to a valid position within the 

Additional topics:

* [[Extracting tiddlers from a single file TiddlyWiki]]


field_name: text
field_value:
~TiddlyWiki has two approaches to saving the user data (tiddlers) depending on whether you are using the single file version, or are using the node.js server.

~TiddlyWiki on node.js saves each tiddler in a separate text file. For details on the file formats supported for tiddlers on node.js, see [[Tiddler Files|https://tiddlywiki.com/#TiddlerFiles]].

The single file version of ~TiddlyWiki saves the tiddlers within the HTML file. See [[Data Storage in Single File TiddlyWiki]]


field_name: text
field_value:
! Overview

Filter operators are modules (tiddlers of type `application/javascript`) with their `module-type` field set to `filteroperator`, exporting one or more functions implementing a filter.

Each function will be called with three arguments:

* A [[tiddler iterator|Tiddler Iterators]] representing the results of the previous filter step (or all tiddlers, if this filter appears first in an expression), conventionally named `source`.
* An object, conventionally called `operator`, representing the arguments for this filter step, with the following keys:
** //operator//: the name of the filter operator specified in the WikiText;
** //operand//: the operand for the filter step (as a string; if the filter specified it in angle brackets or braces, the text reference or variable name will have already been resolved);
** //prefix//: (optional) a string containing a single exclamation mark if the filter operator is to be negated;
** //suffix//: (optional) a string containing an additional filter argument (typically a tiddler field name) following the filter name (separated by a colon in the filter syntax);
** //regexp//: (optional, deprecated) used instead of //operand// if the filter operand is a regexp.
* An object, conventionally called `options`, with the following keys:
** //wiki//: The `$tw.Wiki` object;
** //widget//: (optional) a widget node.

The function should return either a new [[tiddler iterator|Tiddler Iterators]], or else an array of tiddler titles (as strings). The underlying filter mechanism will convert back and forth between iterators and arrays as needed.

! References

There are several filter operators built into the core which can serve as a jumping off point for your own filter operators:

https://github.com/Jermolene/TiddlyWiki5/tree/master/core/modules/filters

! Example

Suppose we want to make a filter operator that returns every other tiddler from the input list. A typical invocation might look like `[tags[interesting]everyother[]]`.

We make a new tiddler, set its `type` and `module-type` appropriately, and begin writing the code:

```
(function(){
"use strict";
    
exports.everyother = function(source, operator, options) {
    // TODO
}
})();
```

For the example filter syntax, our function will be called with

* source: an iterator over all the tiddlers tagged as `interesting`
* operator: an object `{operator: "everyother", operand: ""}`
* options: an object with the current Wiki object and a widget object, neither of which we need

As is usually the case, we don't care about `operator.operator` here (since that information has already been used to look up our function); we also don't care about `operator.operand`, since there is no meaningful operand for this operation.

We could implement the operator by iterating over the input tiddlers and explicitly building a result array of titles:

```
(function(){
"use strict";
    
exports.everyother = function(source, operator, options) {
    var result = [];
    var include = true;
    source(function(tiddler, title) {
        if (include) { result.push(title); }
        include = !include;
    });
    return result;
}
})();
```

That is, we supply a callback to `source` that negates `include` each time through (in order to grab every other result) and pushes the `title` of every other tiddler onto the result.

Alternatively, we can return our own iterator, by returning a function that accepts a similar callback and only calls it on every other tiddler:

```
(function(){
"use strict";
    
exports.everyother = function(source, operator, options) {
    return function(callback) {
        var include = true;
        source(function(tiddler, title) {
            if (include) { callback(tiddler, title); }
            include = !include;
        });
    };
}
})();
```

Either way, we could interpret the `!` flag on the filter, if present, to mean that we want the //other// half of the tiddlers, by using it to set the initial value of `include`: `var include = operator.prefix !== "!";`

! Filter Behaviour

As with [[JavaScript Macros]], filter operators should not make modifications to tiddlers, but only return a list of tiddlers or a tiddler iterator.


field_name: text
field_value:
The hook mechanism provides a way for plugins to intercept and modify default functionality. 

!! Add a hook

Hooks are added as follows:

```js
/*
name: name of hook function (by convention prefixed with `th-`)
handler: function to be called when hook is invoked
*/
$tw.hooks.addHook(name,handler);
```

!!! Params and return

The handler function will be called with parameters that depend on the specific hook in question, but they always follow the pattern `handler(value,params...)`

* ''value'': an optional value that is to be transformed by the hook function
* ''params'': one or more optional parameters that are passed to the hook function

If required by the hook in question, the handler function must return the modified ''value''.

!!! Multiple handlers

Multiple handlers can be assigned to the same name using repeated calls. When a hook is invoked by name all registered functions will be called sequentially in their order of addition.

Note that the ''value'' passed to the subsequent hook function will be the return value of the previous hook function.

Be careful not to `addHook` in widget's `render` method, which will be call several times. You could `addHook` in methods that only called once, e.g. the constructor of widget class. Otherwise you should `removeHook` then add it again.

!!! Timing of registration

Though not essential care should be taken to ensure that hooks are added before they are invoked.

For example: [[Hook: th-opening-default-tiddlers-list]] should ideally be added before the story startup module is invoked. Otherwise any hook specified additions to the default tiddlers will not be seen on the initial loading of the page, though will be visible if the user clicks the home button.

!! Remove a hook

You should clean up the callback when your widget is going to unmount.

```js
$tw.hooks.removeHook(handler)
```

The `handler` should be the same function instance you used in `addHook` (check by `===`). You can save it to `this.xxxHookHandler` on your widget, and call `removeHook` in [[destroy method|Widget `destroy` method examples]].

!! Example

A working example of a hook that adds "test" to the default tiddlers.

```js
$tw.hooks.addHook("th-opening-default-tiddlers-list",function(list) { 
    list.push("test");
    return list; 
});
```


field_name: text
field_value:
This hook allows plugins to inspect or modify the `importTiddler` object ''before'' any tiddlers are imported. It is invoked after the final "Import" button is clicked, but ''before'' the selected tiddlers are being imported into the store.

''Intended Usecases'':

* Manipulate the import "selection state"
* Eg: create a customized "log-tiddler" that contains a heading, that should only be written once

''Important'': 

* This hook ''should not'' be used to manpulate the `importTiddler.fields.text` element!
* If you want to give the users a possibility to verify the imported data, use ùpgraders like: `$:/core/modules/upgraders/` instead
* If you need to manipulate the imported tiddler content, without default user interaction, consider: [[Hook: th-importing-tiddler]] instead

The hook is part of the `NavigatorWidget.prototype.handlePerformImportEvent` function.

Hook function parameters:

* ''importTiddler'': an object, that contains information about "selected / unselected" tiddlers and more

Return value:

* ''importTiddler'': object

The hook must return the `importTiddler` object. For many usecases the object will be returned unmodified.

''Example code how to implement a hook in your project''

```
/*\
title: $:/plugins/<author>/<plugin>/th-before-importing.js
type: application/javascript
module-type: startup

YOUR DISCRCRIPTION COMES HERE!

\*/
(function(){

/*jslint node: true, browser: true */
/*global $tw: false, exports: true */
"use strict";

// Export name and synchronous status
exports.name = "<yournamecomesherewithoutspaces>";
exports.platforms = ["browser"];
exports.after = ["startup"];
exports.synchronous = true;

// Define your variables here!

exports.startup = function() {
	$tw.hooks.addHook("th-before-importing",function(importTiddler) {

// YOUR CODE !

		return importTiddler;
	});
};

})();

```


field_name: text
field_value:
This hook allows plugins to monitor the closing of a tiddler from the story.

Hook function parameters:

* ''event'': Widget message object with the following properties:
** ''event'': DOM event object that triggered the widget message
** ''tiddlerTitle'': the title of the tiddler being closed
** ''widget'': reference to the widget that sent the message.

Return value:

* ''event'': Widget message object

The original event widget message object can be returned unmodified by the hook. 


field_name: text
field_value:
This hook notifies plugins that a page refresh has just occurred. It is typically used to apply post-rendering effects.

Hook function parameters:

* (none)

Return value:

* (none)


field_name: text
field_value:
This hook notifies plugins that a page refresh is just about to occur. It is typically used to apply pre-rendering effects.

Hook function parameters:

* (none)

Return value:

* (none)


field_name: text
field_value:
This hook allows plugins to inspect tiddlers before they are deleted via the ''delete'' toolbar button. When the delete button is used from the edit toolbar there are actually two invocations of the `th-deleting-tiddler` hook function: one for the original tiddler and one for the draft.

Note that this hook is not invoked for tiddlers deleted by other means such as the ActionDeleteTiddlerWidget.

Hook function parameters:

* ''tiddler'': tiddler object about to be deleted

Return value:

* unmodified tiddler to be deleted


field_name: text
field_value:
This hook allows plugins to inspect tiddlers before they are edited via the ''edit'' toolbar button.

Hook function parameters:

* ''event'': DOM event object that triggered the edit

Return value:

* ''editTiddler'': ''true'' to continue with editing the tiddler as usual, ''false'' to silently suppress editing


field_name: text
field_value:
This hook allows plugins to inspect or modify the details of files imported via drag and drop or the "import" button. It is invoked as each [[File object|https://developer.mozilla.org/en-US/docs/Web/API/File]] provided by the browser in response to an import or drag and drop is being read. The hook function can choose to ignore the file, in which case TiddlyWiki's default processing proceeds to read and import the content of the file. Alternatively, the hook function can process the file to extract the tiddlers itself, and then pass them back to TiddlyWiki to be handled by the rest of the import process.

Use this hook if you want to control how tiddlers are extracted from files during an import. See [[Hook: th-importing-tiddler]] if you want to process each imported tiddler after they have been extracted from the files.

Hook function parameters:

* ''info'': an object with properties containing information relating to the current file:
** ''file'': reference to the browser's [[File object|https://developer.mozilla.org/en-US/docs/Web/API/File]]
** ''type'': the MIME type of the file. If not provided by the browser then TiddlyWiki attempts to infer the type from the file extension
** ''isBinary'': flag for whether the file contains binary data (which requires that the file type be recognised by TiddlyWiki)
** ''callback'': callback function to be called with an array of tiddler field objects extracted from the file object

Return value:

* ''true'' indicates that the hook handled the file, and passed any extracted tiddlers to the callback
* ''false'' indicates that the hook didn't process the file


field_name: text
field_value:
This hook allows plugins to inspect or modify tiddlers as they are imported via the import mechanism. It is invoked when the final "Import" button is clicked, and the selected tiddlers are being imported into the store.

The hook is part of the `NavigatorWidget.prototype.handlePerformImportEvent` function.

Use this hook if you want to process each imported tiddler after they have been extracted from the files.  See [[Hook: th-importing-file]] if you want to control how tiddlers are extracted from files during an import.

Hook function parameters:

* ''tiddler'': tiddler object about to be imported

Return value:

* tiddler object to be imported

The original tiddler object can be returned unmodified by the hook. If the hook needs to modify the tiddler then it should return a new tiddler object, for example:

```
	return new $tw.Tiddler(tiddler,{"my-field": value});
```

Hooks must not change the ''title'' field but can freely modify any other field of the tiddler.


field_name: text
field_value:
This hook allows plugins to monitor and modify navigation events.

Hook function parameters:

* ''event'': object describing the navigation event:
** ''event.navigateTo'': title of target tiddler
** ''event.navigateFromTitle'': title of tiddler containing the
** ''event.navigateSuppressNavigation'': boolean; when true the target tiddler opens without the usual scrolling
** ''event.navigateFromClientRect'': rectange in client coordinates of the DOM node triggering the navigation

Return value:

* possibly modified event object


field_name: text
field_value:
This hook allows plugins to inspect tiddlers before they are relinked ("relinking" is the optional operation of relinking references to a tiddler when it is renamed).

Hook function parameters:

* ''newTiddler'': tiddler object incorporating the relinking
* ''oldTiddler'': optional existing tiddler object that will be overwritten

Return value:

* ''newTiddler'': tiddler object to be used for the relinking operation.

The original tiddler object can be returned unmodified by the hook. If the hook needs to modify the tiddler then it should return a new tiddler object, for example:

```
	return new $tw.Tiddler(tiddler,{"my-field": value});
```

Hooks must not change the ''title'' field but can freely modify any other field of the tiddler.


field_name: text
field_value:
This hook allows plugins to inspect tiddlers before they are modified by the `tm-rename-tiddler` message.

Hook function parameters:

* ''newTiddler'': tiddler object incorporating the rename
* ''oldTiddler'': optional existing tiddler object that will be overwritten

Return value:

* newTiddler: tiddler object to be used for the renaming operation.

The original tiddler object can be returned unmodified by the hook. If the hook needs to modify the tiddler then it should return a new tiddler object, for example:

```
	return new $tw.Tiddler(tiddler,{"my-field": value});
```

Hooks must not change the ''title'' field but can freely modify any other field of the tiddler.


field_name: text
field_value:
This hook provides a notification that a DOM element is about to be rendered by the "element" widget. The hook can optionally provide an alternate parse tree that will be rendered in place of the intended element.

Note the element widget only renders those HTML elements that were parsed as plain HTML elements within wikitext (i.e. using the `<tagname>` syntax). This means that this hook is not invoked for elements created by other widgets.

Hook function parameters:

* ''newParseTreeNodes'': optional parse tree nodes provided by a previously called hook
* ''widget'': instance of the element widget invoking the hook

Return value:

* ''newParseTreeNodes'': optionally new parse tree nodes to replace the intended element, or a falsey value to leave the element untouched

Here is an example of a handler for this hook:

```js
$tw.hooks.addHook("th-rendering-element",function(parseTreeNodes,widget) {
	// Return the previous mapping if there is one
	if(parseTreeNodes) {
		return parseTreeNodes;
	}
	// Detect the elements we're interested in
	if(someCondition()) {
		// Replace them with a parse tree
		return generateParseTreeNodes();
	}
	// Otherwise do nothing
	return null;
});
```


field_name: text
field_value:
This hook allows plugins to extend the TiddlyWiki server command after it initializes. The two 
most obvious use cases are adding routes (such as an attachments folder for external files) 
to the SimpleServer instance and adding a websockets handler to the HTTP server. 

Hook function parameters: 

* SimpleServer instance
** Defined in core/modules/commands/server.js
* NodeJS HTTP Server instance
** See the NodeJS docs at [ext[https://nodejs.org/docs/latest-v8.x/api/http.html#http_class_http_server]]
* Name of server invoking this hook (for special handling of the NodeJS HTTP server instance argument). 
** Current known values: `tiddlywiki`, `tiddlyserver`. 

Return value is ignored.


field_name: text
field_value:
This hook lets a plugin inspect or modify the tiddler file path during the saving process.

Hook function parameters:

* ``currentPath``: The path the tiddler file will be saved to.
* ``originalPath``: The original tiddler file path unmodified by any hooks.

Return value:

The path to use for saving the tiddler file.


field_name: text
field_value:
Browsers still have significant variations in their handling of drag and drop and clipboard operations.

You can switch on special logging to help debug issues:

# Open your browser JavaScript console
# Type:
#> ``$tw.log.IMPORT = true``
# Drag or paste a file to import it
# Look for debug information in the console. For example:
#> ``Importing file 'my-image.png', type: 'image/png', isBinary: true``


field_name: text
field_value:
!! Introduction

The wikitext parser subclassing mechanism makes it possible for custom parsers to use the wiki text parsing engine, but to customise the rules that are used.

!! Example

Here is an example of a subclass of the checkbox widget that adds logging to the event handler:

```js
(function(){

/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";

var WikiParser = require("$:/core/modules/parsers/wikiparser/wikiparser.js")["text/vnd.tiddlywiki"],
	HtmlParser = $tw.modules.createClassFromModule(require("$:/core/modules/parsers/wikiparser/rules/html.js"),$tw.WikiRuleBase),
	EntityParser = $tw.modules.createClassFromModule(require("$:/core/modules/parsers/wikiparser/rules/entity.js"),$tw.WikiRuleBase);

var MyCustomWikiParser = function(type,text,options) {
	var parser = new WikiParser(type,text,$tw.utils.extend({},options,{
		// Force the parser to parse in inline mode
		parseAsInline: true,
		// Specify which rules will be used
		rules: {
			pragma: [],
			block: [],
			inline: [HtmlParser,EntityParser]
		}
	}));
	this.tree = parser.tree;
	this.prototype = parser.prototype;
};

exports["text/vnd.my-custom-type"] = MyCustomWikiParser;

})();
```


field_name: text
field_value:
It is straightforward to allow any HTML file to interoperate with TiddlyWiki's drag and drop implementation.

This example shows how to attach draggable data to a DOM element. The data is provided in two different forms:

* the string data is used if the element is dragged onto a text editing area
* the tiddler data is used if the element is dragged into TiddlyWiki's import area

<$button>
<$action-sendmessage $message="tm-download-file" $param="$:/dev/save/dragndropinterop" filename="index.html"/>
Download this sample code
</$button>

<$codeblock code={{DragAndDropInterop}} language="text/html"/>


field_name: text
field_value:
With the advent of ES2015 (also known as ES6) and the availability of [[Babel.js|http://babeljs.io/]] plugin developers can leverage ES2015 when writing TiddlyWiki plugins. Understanding the nuances between TiddlyWiki's module sandbox and how Babel compiles it's output ready for a module system like ~CommonJS/AMD.

Please understand how the PluginMechanism works since this is all about writing a plugin using Babel to compile the output that will be included in the final TiddlyWiki (for example [[TiddlyWiki on Node.js]]).

!! Installing and Configuring Babel

You can install Babel using

```
$ npm install --global babel-cli babel-presets-es2015
```

If your developing the plugin for inclusion to the npm registry (or for convenience) you can avoid the global install and save it to the local `package.json` file with

```
$ npm install --save-dev babel-cli babel-presets-es2015
```

Inside your plugin project edit the file `.babelrc` and enter the following:

```json
{
  "presets": [
    "es2015"
  ]
}
```

<<.tip "I found it easier to manage my plugins as if they were ''npm'' modules complete with a `package.json` that compiles the output via `npm run build`. See [[npm-scripts documentation|https://docs.npmjs.com/misc/scripts]] for details.">>

!! Compiling the Output

Pick a folder to store the ES2015 JavaScript and a folder to output the TiddlyWiki ready JavaScript. In this example I will use `src` and `lib` respectively. With Babel installed and working I can compile all the JavaScript in the `src` folder to the `lib` folder by running this command:

```
$ babel src -d lib
```

<<.warning "Babel will //not// copy over non-JavaScript files. It is up to the developer to include all the supporting files themselves. Babel only converts the ~JavaScript files (ending in `.js`) from the `src` folder to the `lib` folder.">>

!! Imports and Exports

In a plugin written pre-ES2015 one would `require` a module through TiddlyWiki like so:

```javascript
var Widget = require('$:/core/modules/widgets/widget.js').widget;
```

But in ES2015 the following would look like:

```javascript
import { widget as Widget } from '$:/core/modules/widgets/widget.js';
```

Conveniently when Babel compiles this it will essentially output the same JavaScript as the first pre-ES2016 code.

Also, in ES2016 you are required to declare your imports at the beginning and can not dynamically `require` things. This means you can not have an `import` statement in an if block or in a function. If that functionality is desired then you will have to go back to using the `require()` statement directly. But conciser that by doing so that you may be missing an oppertunity to make your code cleaner and better.

Exporting is the same thing. Instead of assigning to a property of the `exports` variable you use the `export` keyword:

```javascript
export { MyWidget as mywidget };
```

<<.tip "It is illegal JavaScript to export with a name that is not an identifier even though it is ok to use a non-identifier (string) as a property key. What this means is if you want a widget to have a dash in it then you have to revert to using the `exports['my-widget'] = MyWidget;` syntax.">>

It is important to understand that in ES2016 the ''default'' export is not supported in TiddlyWiki. This is mostly because the core code expects specific properties to be attached to the `exports` variable. Bable's `export` conversion plays well with this //except// with the default export.

!! Classes

In the example of a widget ES2016 plays well with class inheritance. To contrast the typical Widget definition would look something like this:

```javascript
function MyWidget() {
  Widget.call(this);
}
MyWidget.prototype = new Widget();
MyWidget.prototype.render = function(parent, nextSibling) {…};
// And so on…
```

With classes this ceremony can be tightened up:

```javascript
class MyWidget extends Widget {
  render(parent, nextSibling) {…}
  // And so on…
}
```

With classes one //could// eliminate much of the `Widget.execute()` cruft using <<.def "getters">>. I found this to be more readable then the typical mass assignment to `this`. It gave me the added benefit of allowing calculations in properties that normally would have conflated the `execute()` method. For example developing a compound property like so:

```javascript
class NameWidget extends Widget {
  get title() { return this.getAttribute('title'); }
  get firstName() { return this.getAttribute('first'); }
  get lastName() { return this.getAttribute('last'); }
  get fullName() { return `${this.title}. ${this.firstName} ${this.lastName}`; }
}
```

!!! Non Class Modules

For non class modules you can use the `export` keyword. Here is a simple [[Startup Module|ModuleType]]:

```javascript
export function startup() {
  // Do stuff here
}
```

Or in the case of a [[Macro|https://tiddlywiki.com/dev/#JavaScript%20Macros]]:

```javascript
export const name = 'my-macro';
export const params = {};
export function run() {…}
```

!! Polyfills

ES2015 comes with some features that are part of the JavaScript core objects. These are not supported by all browsers. To use these features in [[most browsers|BrowserCompatibility]] you will need a <<.def "polyfill">>. Babel has a polyfill package that you can include. See [[Adding Babel Polyfill to TiddlyWiki]] for how to accomplish this.

!! Example

Here is an example ES2015 plugin/widget that will show the time and update it:

```javascript

/*\
title: $:/plugins/sukima/clock-widget.js
type: application/javascript
module-type: widget

A updating time stamp

\*/
import { widget as Widget } from '$:/core/modules/widgets/widget.js';

class ClockWidget extends Widget {
  constructor(parseTreeNode, options) {
    super(parseTreeNode, options);
    this.logger = new $tw.utils.Logger('clock-widget');
  }

  render(parent, nextSibling) {
    if (!$tw.browser) { return; }
    this.logger.log('Rendering clock DOM nodes');
    this.computeAttributes()
    this.parentDomNode = parent;
    this.domNode = $tw.utils.domMaker('div', {
      document: this.document,
      class: 'tc-clock-widget'
    });
    parent.insertBefore(this.domNode, nextSibling);
    this.tick();
  }

  tick() {
    this.logger.log('Tick!');
    if (!document.contains(this.domNode)) {
      // Apparently the widget was removed from the DOM. Do some clean up.
      return this.stop();
    }
    this.start();
    this.domNode.innerHTML = this.dateString;
  }

  start() {
    if (!this.clockTicker) {
      this.logger.log('Starting clock');
      this.clockTicker = setInterval(this.tick.bind(this), 1000);
    }
  }

  stop() {
    this.logger.log('Stopping clock');
    clearInterval(this.clockTicker);
    this.clockTicker = null;
  }

  get dateString() {
    const format = 'DDth MMM YYYY at hh12:0mm:0ss am';
    return $tw.utils.formatDateString(new Date(), format);
  }
}

export { ClockWidget as clock };
```

<<.tip "Adding an extra space at the top causes Babel's output the preamble tiddler comment without any obscene indenting. Although it doesn't affect TiddlyWiki any, when reading the output it can be confusing when the tiddler information is rendered off the screen to the right.">>


field_name: text
field_value:
!! Overview

The notifier module is part of TiddlyWiki's suite of built-in utilities. It displays the text of a tiddler as a notification that briefly appears at the top right top of the screen. They are automatically dismissed after a few seconds.


Notifications are an easy and visual way to notify the user of key information that is transient -- in other words, it shouldn't matter whether the user misses the notification (modals or alerts that require manual dismissal should be used in these cases). 

An example is the `Saved wiki` notification seen each time the "save" button is clicked in the single file configuration of TiddlyWiki.

The notification module makes it easy to display such notifcations, including all the heavy lifting of the notification creation, appending it to the DOM, animating it and finally removing it from the DOM.

!! Parameters

The notifier module only has one method (`display(title,options)`) that accepts two parameters:

* title: The title of an existing tiddler
** If the tiddler does not exist, then no notification will take place
** The content of this tiddler will be transcluded into the notification body
* Options: An object containing a `variables` property that will be applied in the tiddler transclusion

!! Usage

A notifier instance is availably directly on the global `$tw` object:

```js
$tw.notifier.display("$:/language/Notifications/Save/Starting");
```


field_name: text
field_value:
!! Introduction

The widget subclassing mechanism allows widgets to be subclassed with additional methods and properties. The subclassed widgets can either overwrite the existing definition of the baseclass widget, or it can be made available as a new widget

Widget subclasses are defined in modules of module-type `widget-subclass`. They should export the following properties:

* ''baseClass'': the name of the widget class being subclassed
* ''name'': (optional) the name to be used for the subclassed widget (defaults to overwriting the baseclass widget)
* ''constructor'': constructor function for creating the widget object
* ''prototype'': object whose properties are added to the subclass

!! Example

Here is an example of a subclass of the checkbox widget that adds logging to the event handler:

```
/*\
title: $:/my-customised-checkbox-widget.js
type: application/javascript
module-type: widget-subclass

Widget base class

\*/
(function(){

/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";

exports.baseClass = "checkbox"; // Extend the <$checkbox> widget

// Specify a different name to make the subclass available as a new widget instead of overwriting the baseclass:
// exports.name = "my-enhanced-checkbox";

exports.constructor = function(parseTreeNode,options) {
	this.initialise(parseTreeNode,options);
};

exports.prototype = {};

exports.prototype.handleChangeEvent = function(event) {
	// Call the base class handleChangeEvent function
	Object.getPrototypeOf(Object.getPrototypeOf(this)).handleChangeEvent.call(this,event);
	// Print our message
	console.log("Checkbox status:",this.inputDomNode.checked);
};

})();
```


field_name: text
field_value:
<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>Drag and Drop Interoperability with TiddlyWiki Demo</title>
    <style>
        #draggable {
            padding: 1em;
            margin: 1em;
            background: #ecc;
        }
    </style>
</head>
<body>
    <div id="draggable" draggable="true">
        Drag me to a TiddlyWiki window
    </div>
    <button id="copy">
        Click to copy two tiddlers to the clipboard
    </button>

</body>
<script>

    var titleString = "This is the string that appears when the block is dragged to a text input";
    var tiddlerData = [
        {title: "Tiddler One", text: "This is one of the payload tiddlers"},
        {title: "Tiddler Two", text: "This is another of the payload tiddlers", "custom-field": "A custom field value"}
    ];

    document.getElementById("draggable").addEventListener("dragstart",function(event) {
        event.dataTransfer.setData("URL","data:text/vnd.tiddler," + encodeURIComponent(JSON.stringify(tiddlerData)));
        event.dataTransfer.setData("Text",titleString);
        event.stopPropagation();
        return false;
    });

    document.getElementById("copy").addEventListener("click",function(event) {

    function listener(event) {
        event.clipboardData.setData("URL","data:text/vnd.tiddler," + encodeURIComponent(JSON.stringify(tiddlerData)));
        event.preventDefault();
    }

    document.addEventListener("copy",listener);
    document.execCommand("copy");
    document.removeEventListener("copy",listener);

    });
</script>
</html>


field_name: text
field_value:
This hook allows plugins to add to or remove from the list of tiddlers that are opened when the wiki is first loaded or the home button is clicked.

Hook function parameters:

* ''list'': array of tiddler titles to be opened

Return value:

* modified array of tiddler titles to be opened

Note that this hook is invoked with the tiddler titles that are generated from the filter in [[$:/DefaultTiddlers]]. Any added entries must be tiddler titles, not filter expressions.


field_name: text
field_value:
This hook allows plugins to inspect or modify tiddlers before they are saved via the ''confirm'' toolbar button; the hook is not invoked for tiddlers that are saved through other means, such as state tiddlers created by the ActionSetFieldWidget.

Hook function parameters:

* ''newTiddler'': tiddler object about to be saved
* ''oldTiddler'': tiddler object of draft tiddler that is being saved (from v5.1.23)

Return value:

* tiddler object to be saved

The original tiddler object can be returned unmodified by the hook. If the hook needs to modify the tiddler then it should return a new tiddler object, for example:

```
	return new $tw.Tiddler(tiddler,{"my-field": value});
```

Hooks must not change the ''title'' field but can freely modify any other field of the tiddler.


field_name: text
field_value:
\define base-github()
https://github.com/Jermolene/TiddlyWiki5/edit/master/editions/dev/tiddlers/
\end

<$set name="draft-of" value={{{ [<currentTiddler>get[draft.of]] }}}>
<$list filter="[[$:/config/OriginalTiddlerPaths]getindex<draft-of>]" variable="target" >
<div class="tc-improvement-banner">
{{$:/core/images/star-filled}} Can you help us improve this documentation? [ext[Find out how|https://tiddlywiki.com/#Improving%20TiddlyWiki%20Documentation]] to
<a href={{{ [<target>addprefix<base-github>] }}} class="tc-tiddlylink-external" target="_blank" rel="noopener noreferrer">edit this tiddler on ~GitHub</a>
</div>
</$list>
</$set>


field_name: text
field_value:
<script>

window.$tw = window.$tw || Object.create(null);
$tw.boot = $tw.boot || Object.create(null);

$tw.boot.encryptionPrompts = {
	decrypt: "Decrypt this TiddlyWiki by entering the password"
};

</script>
<style>

body .tc-password-wrapper {
	background-color: rgb(183, 197, 235);
	border: 8px solid rgb(152, 164, 197);
}

body .tc-password-wrapper form {
	text-align: center;
}

body .tc-password-wrapper h1 {
	padding-bottom: 8px;
}

body .tc-password-wrapper input {
	width: auto;
}

</style>


field_name: text
field_value:
\define github-link-base()
https://github.com/Jermolene/TiddlyWiki5/blob/master/editions/dev/tiddlers/$(title)$
\end

\define make-github-link()
<$set name="title" value={{$:/config/OriginalTiddlerPaths##$(currentTiddler)$}}>
<$set name="title" filter="[<title>encodeuricomponent[]]" select="0">
<a href=<<github-link-base>> class="tc-tiddlylink-external" target="_blank" rel="noopener noreferrer"><$text text=<<github-link-base>>/></a>
</$set>
</$set>
\end

<$list filter="[all[current]!is[system]!is[shadow]]">

Help us to improve the documentation by sending a ~GitHub pull request for this tiddler:

* <<make-github-link>>

</$list>


field_name: text
field_value:
<div class="tc-static-alert"><div class="tc-static-alert-inner">This page is part of a static HTML representation of the ~TiddlyWiki at https://tiddlywiki.com/dev/</div></div>


field_name: text
field_value:
\define .concat(1,2,3,4,5) $1$$2$$3$$4$$5$

\define .def(_) <dfn class="doc-def">$_$</dfn>
\define .em(_) <em class="doc-em">$_$</em>
\define .strong(_) <strong class="doc-strong">$_$</strong>
\define .place(_) <code class="doc-place">$_$</code>
\define .word(_) "$_$"

\define .preamble(_) :.doc-preamble $_$
\define .note(_)
@@.doc-note
;Note
: $_$
@@
\end

\define .tid(_) <code class="doc-tiddler">$_$</code>
\define .tag(_) <code class="doc-tag">$_$</code>
\define .field(_) <code class="doc-field">$_$</code>
\define .value(_) <code class="doc-value">$_$</code>
\define .op(_) <code class="doc-operator">$_$</code>
\define .var(_) <code class="doc-var">$_$</code>
\define .wid(_) <code class="doc-widget">$$_$</code>
\define .attr(_) <code class="doc-attr">$_$</code>
\define .param(_) <code class="doc-param">$_$</code>

\define .mtitle(_) $_$ Macro
\define .otitle(_) $_$ Operator
\define .vtitle(_) $_$ Variable

\define .link(_,to) <$link to="$to$">$_$</$link>
\define .clink(_,to) <span class="doc-clink"><<.link """$_$""" "$to$">></span>
\define .dlink(_,to) <$macrocall $name=".link" _=<<.def "$_$">> to="$to$">/>
\define .dlink-ex(_,to) <a href="$to$" class="tc-tiddlylink-external" target="_blank" rel="noopener noreferrer"><<.def "$_$">></a>
\define .flink(to) <$macrocall $name=".link" _=<<.field {{$to$!!caption}}>> to="$to$"/>
\define .mlink(_,to) <$macrocall $name=".link" _=<<.var "$_$">> to=<<.mtitle "$_$">>/>
\define .mlink2(_,to) <$macrocall $name=".link" _=<<.var "$_$">> to="$to$"/>
\define .olink(_) <$macrocall $name=".link" _=<<.op "$_$">> to=<<.otitle "$_$">>/>
\define .olink2(_,to) <$macrocall $name=".link" _=<<.op "$_$">> to=<<.otitle "$to$">>/>
\define .vlink(_,to) <$macrocall $name=".link" _=<<.var "$_$">> to=<<.vtitle "$_$">>/>
\define .vlink2(_,to) <$macrocall $name=".link" _=<<.var "$_$">> to="$to$"/>
\define .wlink(to) <$macrocall $name=".link" _=<<.wid {{$to$!!caption}}>> to="$to$"/>
\define .wlink2(_,to) <$macrocall $name=".link" _="$_$" to="$to$"/>

\define .key(_) <span class="doc-key">$_$</span>
\define .combokey(_) <$macrocall $name=".if" cond="$_$" then=<<.key '$_$'>>/>
\define .keycombo(1,2,3,4) <<.combokey "$1$">><<.if "$2$" +>><<.combokey "$2$">><<.if "$3$" +>><<.combokey "$3$">><<.if "$4$" +>><<.combokey "$4$">>

\define .tab(_) <span class="doc-tab">{{$_$!!caption}}</span>
\define .sidebar-tab(_) <<.tab "$:/core/ui/SideBar/$_$">>
\define .more-tab(_) <<.tab "$:/core/ui/MoreSideBar/$_$">>
\define .info-tab(_) <<.tab "$:/core/ui/TiddlerInfo/$_$">>
\define .controlpanel-tab(_) <<.tab "$:/core/ui/ControlPanel/$_$">>
\define .advancedsearch-tab(_) <<.tab "$:/core/ui/AdvancedSearch/$_$">>
\define .toc-tab() <<.tab "TableOfContents">>
\define .example-tab(_) <span class="doc-tab">$_$</span>

\define .button(_) <span class="doc-button">{{$:/core/ui/Buttons/$_$!!caption}}</span>

\define .tip(_) <div class="doc-icon-block"><div class="doc-block-icon">{{$:/core/images/tip}}</div> $_$</div>
\define .warning(_) <div class="doc-icon-block"><div class="doc-block-icon">{{$:/core/images/warning}}</div> $_$</div>

\define .state-prefix() $:/state/editions/tw5.com/

\define .lorem()
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
\end

\define .toc-lorem()
This is an example tiddler. See [[Table-of-Contents Macros (Examples)]].

<<.lorem>>
\end

\define .example(n,eg,egvar:NO-SUCH-VAR)
<div class="doc-example">
<$reveal default="$egvar$" type="match" text="NO-SUCH-VAR">
	<$macrocall $name="copy-to-clipboard-above-right" src="""$eg$"""/>
	<$codeblock code="""$eg$"""/>
</$reveal>
<$reveal default="$egvar$" type="nomatch" text="NO-SUCH-VAR">
	<!-- allow an example to contain """ -->
	<$macrocall $name="copy-to-clipboard-above-right" src=<<$egvar$>>/>
	<$codeblock code=<<$egvar$>>/>
</$reveal>
<$list filter="[title<.state-prefix>addsuffix{!!title}addsuffix[/]addsuffix[$n$]]" variable=".state">
<$reveal state=<<.state>> type="nomatch" text="show">
	<dl>
	<dd><$button set=<<.state>> setTo="show">Try it</$button></dd>
	</dl>
</$reveal>
<$reveal state=<<.state>> type="match" text="show">
	<dl>
	<dd><$button set=<<.state>> setTo="">Hide</$button></dd>
	</dl>
	<blockquote class="doc-example-result">
	<$reveal default="$egvar$" type="match" text="NO-SUCH-VAR">
		$eg$
	</$reveal>
	<$reveal default="$egvar$" type="nomatch" text="NO-SUCH-VAR">
		<<$egvar$>>
	</$reveal>
	</blockquote>
</$reveal>
</$list>
\end

<pre><$view field="text"/></pre>


field_name: text
field_value:
a.doc-from-version.tc-tiddlylink {
    display: inline-block;
    border-radius: 1em;
	background: <<colour muted-foreground>>;
	color: <<colour background>>;
	fill: <<colour background>>;
    padding: 0 0.4em;
    font-size: 0.7em;
    text-transform: uppercase;
    font-weight: bold;
    line-height: 1.5;
    vertical-align: text-bottom;
}

a.doc-deprecated-version.tc-tiddlylink {
    display: inline-block;
    border-radius: 1em;
	background: red;
	color: <<colour background>>;
	fill: <<colour background>>;
    padding: 0 0.4em;
    font-size: 0.7em;
    text-transform: uppercase;
    font-weight: bold;
    line-height: 1.5;
    vertical-align: text-bottom;
}

.doc-deprecated-version svg,
.doc-from-version svg {
	width: 1em;
	height: 1em;
    vertical-align: text-bottom;
}


field_name: text
field_value:
<div class="github-fork-ribbon-wrapper right" style><div class="github-fork-ribbon" style="background-color:#DF4848;"><a href="https://github.com/Jermolene/TiddlyWiki5" target="_blank" rel="noopener noreferrer">Find me on ~GitHub</a></div></div>


field_name: text
field_value:
alert-background: #ffe476
alert-border: #b99e2f
alert-highlight: #881122
alert-muted-foreground: #b99e2f
background: #e5f8fd
blockquote-bar: <<colour muted-foreground>>
code-background: #f7f7f9
code-border: #e1e1e8
code-foreground: #dd1144
dirty-indicator: #ff0000
download-background: #34c734
download-foreground: <<colour background>>
dragger-background: <<colour foreground>>
dragger-foreground: <<colour background>>
dropdown-background: <<colour background>>
dropdown-border: <<colour muted-foreground>>
dropdown-tab-background-selected: #fff
dropdown-tab-background: #ececec
dropzone-background: rgba(0,200,0,0.7)
external-link-background-hover: inherit
external-link-background-visited: inherit
external-link-background: inherit
external-link-foreground-hover: inherit
external-link-foreground-visited: #0000aa
external-link-foreground: #0000ee
foreground: #4e432f
message-background: #ecf2ff
message-border: #cfd6e6
message-foreground: #547599
modal-backdrop: <<colour foreground>>
modal-background: <<colour background>>
modal-border: #999999
modal-footer-background: #f5f5f5
modal-footer-border: #dddddd
modal-header-border: #eeeeee
muted-foreground: #bbb
notification-background: #ffffdd
notification-border: #999999
page-background: #f4d7a3
pre-background: #f5f5f5
pre-border: #cccccc
primary: #5778d8
sidebar-button-foreground: #877452
sidebar-controls-foreground-hover: #000000
sidebar-controls-foreground: #658deb
sidebar-foreground-shadow: rgba(255,255,255, 0.4)
sidebar-foreground: #9f8860
sidebar-muted-foreground-hover: #444444
sidebar-muted-foreground: #c9ac7a
sidebar-tab-background-selected: #f4d7a3
sidebar-tab-background: #e6c58b
sidebar-tab-border-selected: #d9ba83
sidebar-tab-border: #dbb678
sidebar-tab-divider: #dfbe87
sidebar-tab-foreground-selected: #8d764e
sidebar-tab-foreground: #66573e
sidebar-tiddler-link-foreground-hover: #8e7a56
sidebar-tiddler-link-foreground: #937e59
static-alert-foreground: #aaaaaa
tab-background-selected: #dff6fc
tab-background: #d8d8d8
tab-border-selected: #d8d8d8
tab-border: #cccccc
tab-divider: #d8d8d8
tab-foreground-selected: <<colour tab-foreground>>
tab-foreground: #666666
table-border: #dddddd
table-footer-background: #a8a8a8
table-header-background: #f0f0f0
tag-background: #d5ad34
tag-foreground: #ffffff
tiddler-background: <<colour background>>
tiddler-border: <<colour background>>
tiddler-controls-foreground-hover: #888888
tiddler-controls-foreground-selected: #444444
tiddler-controls-foreground: #9eaeb4
tiddler-editor-background: #f8f8f8
tiddler-editor-border-image: #ffffff
tiddler-editor-border: #cccccc
tiddler-editor-fields-even: #e0e8e0
tiddler-editor-fields-odd: #f0f4f0
tiddler-info-background: #f8f8f8
tiddler-info-border: #dddddd
tiddler-info-tab-background: #f8f8f8
tiddler-link-background: <<colour background>>
tiddler-link-foreground: <<colour primary>>
tiddler-subtitle-foreground: #c0c0c0
tiddler-title-foreground: #715e3e
toolbar-new-button: 
toolbar-options-button: 
toolbar-save-button: 
toolbar-info-button: 
toolbar-edit-button: 
toolbar-close-button: 
toolbar-delete-button: 
toolbar-cancel-button: 
toolbar-done-button: 
untagged-background: #999999
very-muted-foreground: #888888


field_name: text
field_value:
\define tv-wikilink-template() https://tiddlywiki.com/dev/static/$uri_doubleencoded$.html

<!-- For Google, and people without JavaScript-->

<$reveal default="yes" text=<<savingEmpty>> type="nomatch">

It looks like this browser doesn't run JavaScript. You can use one of these static HTML versions to browse the same content:

* https://tiddlywiki.com/dev/static.html - browse individual tiddlers as separate pages
* https://tiddlywiki.com/dev/alltiddlers.html#HelloThere - single file containing all tiddlers

---

{{HelloThere}}

</$reveal>


field_name: text
field_value:
\define .from-version(version)
<$link to={{{ [<__version__>addprefix[Release ]] }}} class="doc-from-version">{{$:/core/images/warning}} New in: <$text text=<<__version__>>/></$link>
\end

\define .deprecated-since(version, superseded:"TODO-Link")
<$link to="Deprecated - What does it mean" class="doc-deprecated-version tc-btn-invisible">{{$:/core/images/warning}} Deprecated since: <$text text=<<__version__>>/></$link> (see <$link to=<<__superseded__>>><$text text=<<__superseded__>>/></$link>)
\end


