Trying to understand syntax

My issue is this… in another tiddler, I want to create a list of lists.

One of the lists would be Powers that have a final-cost between 0-10, 11-20, 21-30, etc. And I thought that would be much simplier if I could just reference the final-cost field of each tiddler.

I tried this:
{{{[!has[draft.of]tag[Spell]filter[field[final-cost]compare:integer:lteq[10]]sort[title]]}}}

But again, I don’t have the syntax correct (it is reporting “Missing [ in filter expression”).

@TW_Tones, I was thinking along those lines… somehow trap the “close” event and save the calculated value then… but of course, I have NO IDEA how to go about doing that. So I implemented the “Save” button… and I will manually click it when the field needs to be updated.

BTW, in case other new users follow this thread (and hopefully learn something from it), here is the Wiki that I am working on: Spells Tiddlywiki — "Magic as Powers"

Yes this filter is the wrong syntax

eg what is filter[field[ or change lteq[10]] to lteq[10]

I think you may need to try and restate what you are wanting to do, not how, or with what you already have.

I have a hunch you need to make use of the map: filter prefix to calculate the value for each tiddlers where needed rather than trying to make use of other existing lists.

The high level design is that I want to create a bunch of Spells (Powers), whose final cost is calculated from a starting cost, and a set of modifiers. Different variations on the Spell will exist, using the same starting cost, but have a different set of modifiers.

From the wonderful help given today, I have have been able to create an example spell that I can clone and edit to create the different Spells.

For example:
Fireball v1: 3d6 burn damage, initial cost: 15, final-cost: 15
Fireball v2: 3d6 burn damage, initial cost: 15, modifiers: Cost Fatigue 1 (-10%), final-cost: 13
Fireball v3: 3d6 burn damage, initial cost: 15, modifiers: Cost Fatigue 1 (-10%) & Limited Use: 1/day (-140%), final-cost: 7

So I have 3 variations on a Spell, each with slightly different limitations (as defined by their modifiers), and each with a different final-cost.

I would then like to be able to list spells in various ways. Some examples:

All spells, sorted alphbetically
All spells, sorted by final-cost, then sorted alphabetically
Any spell whose final-cost is between 0-10, then sorted alphabetically
Any spell whose final-cost is between 11-20, then sorted alphabetically
Any spell whose final-cost is between 21-30, then sorted alphabetically

When you use the filter operator you can’t insert the filter expression directly inside, you need use it from macro or use the filter prefix, as @TW_Tones said. See https://tiddlywiki.com/#filter%20Operator where there is a example similar to your case, and a better explanation how the filter operator works.

Thank you, yes, I saw the examples, and didn’t know the filter MUST use a macro. Once I duplicated that, I have been able to create two lists following that format:

Spells (0-10):

<$vars lt10="[{!!final-cost}compare:integer:lteq[10]]">
<$list filter="[!has[draft.of]tag[Spell]filter<lt10>sort[title]]">
<$link to=<<currentTiddler>>><<currentTiddler>> </$link> [{{!!final-cost}}] <br>
</$list>
</$vars>

Which displays:
Fireball V3 [8]

Spells (11-20)

<$vars lt20="[{!!final-cost}compare:integer:lteq[20]]" gt10="[{!!final-cost}compare:integer:gt[10]]">
<$list filter="[!has[draft.of]tag[Spell]filter<lt20>filter<gt10>sort[title]]">
<$link to=<<currentTiddler>>><<currentTiddler>> </$link> [{{!!final-cost}}]<br>
</$list>
</$vars>

Which displays:
Fireball V1 [15]
Fireball V2 [14]

So again, thank you all for your help. I am STILL a bit shaky on the syntax, but I have enough examples that I can start building the data.

Just a detail, but good to know:
These things…

…can be simplified into…

(yes, that last one is correct because it by default refers to current tid)

Great, thanks again! I will do whatever I can to reduce the amount of code :slightly_smiling_face:

One last question, I am listing the spells with their cost and summary (a one line description), using:

<$list filter="[!has[draft.of]tag[Spell]sort[title]]">
<$link/> [{{!!final-cost}}] "{{!!summary}}"<br>
</$list>

Which displays:
Example Spell [25] “Clone this to create your new Spell”
Fireball V1 [15] “”
Fireball V2 [14] “”
Fireball V3 [8] “”

is there a way to only display the quotes (“”) if {{!!summary}} is not empty? Just wondering (I can certainly live with what I have… but if I can learn more…)

It is a bit convoluted and I’m curious to see of anyone has better ideas, because there are many ways, but here is one way:

{{{ [{!!summary}!is[blank]addprefix["]addsuffix["]] }}}

Unfortunately this, as usual, results in a linkified output. But you can present the output with a custom template:

{{{ [{!!summary}!is[blank]addprefix["]addsuffix["]] || mytemplate }}}

…and the template is a tiddler titled mytempalte containing <$view field=title/>

(IMO, TW should feature some much better way to textify the output from a filter)

EDIT: reading my own linked to post, I found this

<$text text={{{ [{!!summary}!is[blank]addprefix["]addsuffix["]] }}} />

Here’s a couple of minor syntax improvements to consider:

1 to 10:
<blockquote>
<$list filter="[tag[Spell]!has[draft.of]] :filter[{!!final-cost}compare:integer:lteq[10]]  +[sort[title]]">
   <$link/> [{{!!final-cost}}]<br>
</$list>
</blockquote>
11 to 20:
<blockquote>
<$list filter="[tag[Spell]!has[draft.of]] :filter[{!!final-cost}compare:integer:lteq[20]compare:integer:gt[10]]  +[sort[title]]">
   <$link/> [{{!!final-cost}}]<br>
</$list>
</blockquote>
21 to 30:
<blockquote>
<$list filter="[tag[Spell]!has[draft.of]] :filter[{!!final-cost}compare:integer:lteq[30]compare:integer:gt[20]]  +[sort[title]]">
   <$link/> [{{!!final-cost}}]<br>
</$list>
</blockquote>
  1. Start your filter with tag[Spell]. The tag[] operator is highly optimized, and will reduce the number of tiddlers that have to be processed by !has[draft.of]

  2. While the filter[...] operator needs to use a macro because the inner filter syntax contains square brackets, the :filter[...] filter run prefix can handle the inner square brackets, so no macro is needed.

  3. You can combine multiple compare[...] operators in succession.

  4. Put the +[sort[]] operator last, as a separate filter run, using the +prefix so it applies to the results of the previous filter runs. This allows the sorting to work on the smallest final list, rather than sorting a larger list and then filtering it further.

  5. I enclosed each $list output inside <blockquote>...</blockquote> to make it look nice.

-e

1 Like

Imagine that you placed the mods for each spell inside a field in that tiddler called mods, as a list, e.g: [[Costs Fatigue 1]] [[Limited Use: 1/day]]

You could then create a list for the spells that cost less than ten as follows:

<$list filter="[tag[Spell]!is[draft]] :filter[enlist{!!mods}get[cost]sum[]add[100]divide[100]multiply{!!initial-cost}trunc[]compare:integer:lteq[10]]"/>

The benefit is that if you update the cost of any of the mods, you don’t need to update the cost of each individual spell as it is calculated on the fly. Arguably this approach might be theoretically slower to list all the spells, but realistically it probably wont be a problem unless you have an enormous number of spells. All the usual caveats about premature optimization apply.

Alternatively if you really want the cost of each spell written into a field in its tiddler, consider a separate form UI for creating new spells and editing spells, that does the necessary calculations for you and creates/edits the spell tiddlers.

I thought of that while designing the “Spell” tiddler. But the “creation” process has a lot of “what if” scenarios… and I like the fact that if I embed the modifier list in the tiddler itself, I could present them vertically, and, using an “auto complete” plugin, I can quickly type in a few characters, and get a list of known modifiers.

My current Spell tiddler format is:

"{{!!summary}}"<hr>
The caster creates a ball of fire in their hand, and throws it at the target (using the Innate Attack (Projectile) skill). <hr>
<$set name="mods" value="

[[Costs Fatigue 1]]
[[Limited Use: 1/day]]

">
{{||SpellTemplate}}
</$set>

Where I do require a “summary” field, and an “initial-cost” field. This seems to allow me the most freedom for creating new spells… but YMMV.

I hope to, over time, build up a large library of Spells. So I also created searches by alphabet. I wasn’t sure how to “parameterize” a transclusion, but this is what I came up with:

Spells (F)

<$vars search="F">
{{||SpellsByLetter}}
</$vars>

SpellsByLetter

<blockquote>
<$list filter="[tag[Spell]!has[draft.of]prefix<search>]  +[sort[title]]">
<$link/> [{{!!final-cost}}] "{{!!summary}}"<br>
</$list>
</blockquote>

Is there a better way to pass a parameter to a template?

A post was split to a new topic: Curating or flagging threads

I truly hope that new users can/will read this thread, since I feel they might be going through the same issues that I am… and again, thank you to everyone for your suggestions and advice.

I have encountered an odd situation, not show-stopping, but odd.

[EDIT] I understand the difference now… if there is a newline after the text, the list is created vertically. Good thing to know for a new user.

Given this tiddler:

Click the various filters to view lists of Spells:

{{{[tag[Spells]sort[title]]}}}

Click the various filters to view lists of Modifiers:

{{{[tag[Modifiers]sort[title]]}}}

Templates:
{{{[tag[Template]sort[title]]}}}

That displays 3 lists of tiddlers, based on a tag. The top two list displays vertically (spells and modifiers), but the last list displays everything on a single line…
This is what is displayed:

Click the various filters to view lists of Spells:

All Spells

Spells (0-10)

Spells (11-20)

Spells (21-30)

Spells (Fire)

Spells (Ranged)

Click the various filters to view lists of Modifiers:

All Modifiers

Enhancement Modifiers

Limitation Modifiers

Zero Modifiers

Templates: ModifierTemplateSpellsByLetterSpellsByTagSpellTemplate

As I mentioned above, the difference is the added newline after the label. A useful trick, but one that caused me to lose an hour or so of effort, as I tried various tricks to get it to display “correctly”.

Suggest reading up on block and inline mode for wikitext: https://tiddlywiki.com/#WikiText%20Parser%20Modes

The empty line switches the wikitext to be parsed in block mode.

Thanks! That is a great reference. Sometimes I feel that the answers are out there… if I only knew where to look. And trust me, I spend 30+ minutes googling or searching tiddlywiki.com before I post anything here. I really do try to figure this stuff out before reaching out.

Personally I think tiddlywiki.com is excellent as reference documentation but can be less helpful for initial orientation when one does not know what to look for.

An excellent resource for newcomers is Soren’s Grok TiddlyWiki book:
Grok TiddlyWiki — Build a deep, lasting understanding of TiddlyWiki

Oh, I got so close… I’ve been able to figure out a lot of things (and yes, the Grok TiddlyWiki is a good read) but here I am, stuck (yet again).

I want to use a template to list spells by a complex filter.

I already have working templates like:
SpellsByTag:

<blockquote>
<$list filter="[tag[Spell]!has[draft.of]tag<search>]  +[sort[title]]">
<$link/> ({{!!spellcomponents}}) [{{!!final-cost}}] {{{ [{!!notes}!is[blank]addprefix["]addsuffix["]] || Textifier }}}<br>
</$list>
</blockquote>

Which I call like this
SpellsWithFire:

<$vars search="Fire">
{{||SpellsByTag}}
</$vars>

and SpellsByLetter:

<blockquote>
<$list filter="[tag[Spell]!has[draft.of]prefix<search>]  +[sort[title]]">
<$link/> ({{!!spellcomponents}}) [{{!!final-cost}}] {{{ [{!!notes}!is[blank]addprefix["]addsuffix["]] || Textifier }}}<br>
</$list>
</blockquote>

but when I try to make a template that uses a complex filter, such as
SpellsByFilter:

<blockquote>
<$list filter="[tag[Spell]!has[draft.of]] :filter<search> +[sort[title]]">
<$link/> ({{!!spellcomponents}}) [{{!!final-cost}}] {{{ [{!!notes}!is[blank]addprefix["]addsuffix["]] || Textifier }}}<br>
</$list>
</blockquote>

Calling it with:

<$vars search="[{!!final-cost}compare:integer:lteq[20]compare:integer:gt[10]]">
{{||SpellsByFilter}}
</$vars>

It doesn’t filter anything (it shows all of the spells).

I am basing this work on a tiddler that DOES work
Spells (10-20):

<blockquote>
<$list filter="[tag[Spell]!has[draft.of]] :filter[{!!final-cost}compare:integer:lteq[20]compare:integer:gt[10]]  +[sort[title]]">
<$link/> [{{!!final-cost}}] {{{ [{!!notes}!is[blank]addprefix["]addsuffix["]] || Textifier }}}<br>
</$list>
</blockquote>

But, of course, to make more of these, I would have to copy the complete tiddler, and update the “:filter”. Which has become a pain, as the display format for the spells is changing over time… and I have to go to each and every one of these to update them. Hence, I thought that moving the display code into a separate template tiddler would be the answer (and it is for tags and starting letters), but I can’t get it to work for arbitrary filters.

Is it possible? I’ve tried using a macro for the filter text, instead of a var, but I haven’t been able to make that work either.

You can see the work in progress here: Spells Tiddlywiki — "Magic as Powers"

I see a syntax error. :filter is a filter run prefix, which determines the behaviour of an entire filter run. This is distinct from a filter operator, filter operators together constitute a filter run.

Filter operators can accept variables as their operands, filter run prefixes expect a literal string.

Two ways to accomplish the same thing instead:
[tag[Spell]!has[draft.of]filter<search>] :and[sort[title]]
or
[tag[Spell]!has[draft.of]] :filter[subfilter<search>] :and[sort[title]]

Hmm… I couldn’t get the first one to work, but the second one (:filter[subfilter]) works! Again thank you.

Which, of course, has opened up a new question for me. Can you sort on multiple fields, ex: sort by cost, and then for spells that have the same cost, sort by name?

Have a look at the sortsub operator and the :sort filter run prefix.