Skip to content

Commit

Permalink
Introduce letlist widget for assigning lists to variables
Browse files Browse the repository at this point in the history
Terrible name. Annoyingly, we can't overload the existing let or set widgets.
  • Loading branch information
Jermolene committed Mar 9, 2025
1 parent 2a1542c commit 78a7aed
Show file tree
Hide file tree
Showing 4 changed files with 127 additions and 1 deletion.
91 changes: 91 additions & 0 deletions core/modules/widgets/letlist.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/*\
title: $:/core/modules/widgets/letlist.js
type: application/javascript
module-type: widget
This widget allows defining multiple variables as lists, allowing
the later variables to depend upon the earlier ones
\*/
(function(){

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

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

var LetListWidget = function(parseTreeNode,options) {
// Initialise
this.initialise(parseTreeNode,options);
};

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

/*
Render this widget into the DOM
*/
LetListWidget.prototype.render = function(parent,nextSibling) {
this.parentDomNode = parent;
this.computeAttributes();
this.execute();
this.renderChildren(parent,nextSibling);
};

LetListWidget.prototype.computeAttributes = function() {
// Before computing attributes, we must make clear that none of the
// existing attributes are staged for lookup, even on a refresh
var changedAttributes = {},
self = this;
this.currentValueFor = Object.create(null);
$tw.utils.each($tw.utils.getOrderedAttributesFromParseTreeNode(this.parseTreeNode),function(attribute) {
var value = self.computeAttribute(attribute),
name = attribute.name;
// Now that it's prepped, we're allowed to look this variable up
// when defining later variables
if(value !== undefined) {
self.currentValueFor[name] = self.wiki.filterTiddlers(value,self);
}
});
// Run through again, setting variables and looking for differences
$tw.utils.each(this.currentValueFor,function(value,name) {
if (!$tw.utils.isArrayEqual(self.attributes[name],value)) {
self.attributes[name] = value;
self.setVariable(name,value);
changedAttributes[name] = true;
}
});
return changedAttributes;
};

LetListWidget.prototype.getVariableInfo = function(name,options) {
// Special handling: If this variable exists in this very $let, we can
// use it, but only if it's been staged.
if ($tw.utils.hop(this.currentValueFor,name)) {
var value = this.currentValueFor[name];
return {
text: value[0] || "",
resultList: value
};
}
return Widget.prototype.getVariableInfo.call(this,name,options);
};

/*
Refresh the widget by ensuring our attributes are up to date
*/
LetListWidget.prototype.refresh = function(changedTiddlers) {
var changedAttributes = this.computeAttributes();
if($tw.utils.count(changedAttributes) > 0) {
this.refreshSelf();
return true;
}
return this.refreshChildren(changedTiddlers);
};

exports["letlist"] = LetListWidget;

})();
19 changes: 19 additions & 0 deletions editions/test/tiddlers/tests/data/letlist-widget/SelfReference.tid
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
title: LetListWidget/SelfReference
description: Using self references with the "letlist" widget
type: text/vnd.tiddlywiki-multiple
tags: [[$:/tags/wiki-test-spec]]

title: Output

<$letlist
original="[all[tiddlers]sort[]]"
varname="[varlist[original]]"
>
<$text text={{{ [varlist[varname]] +[join[-]] }}}/>
</$letlist>
+
title: ExpectedResult

<p>
$:/core-ExpectedResult-Output
</p>
16 changes: 16 additions & 0 deletions editions/test/tiddlers/tests/data/letlist-widget/Simple.tid
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
title: LetListWidget/Simple
description: Simple usage of the "letlist" widget
type: text/vnd.tiddlywiki-multiple
tags: [[$:/tags/wiki-test-spec]]

title: Output

<$letlist varname="[all[tiddlers]sort[]]">
<$text text={{{ [varlist[varname]] +[join[-]] }}}/>
</$letlist>
+
title: ExpectedResult

<p>
$:/core-ExpectedResult-Output
</p>
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@ tags: [[Filter Operators]] [[Selection Constructors]]
title: varlist Operator
type: text/vnd.tiddlywiki

The parameter specifies the name of a variable that has been assigned a list of items by a [[let filter run prefix|Let Filter Run Prefix]]. The operator retrieves all the list items.
The parameter specifies the name of a variable that has been assigned a list of items by a [[let filter run prefix|Let Filter Run Prefix]]. The operator retrieves all the list items stored in the variable.

<<.operator-examples "varlist">>

0 comments on commit 78a7aed

Please sign in to comment.