Qualify widget, unique strings

I must have an incomplete understanding of TW, I wrote a macro to make a drop-down section using reveal and qualify, but qualify returns the same value when used multiple times in the same tiddler, making all the sections expand and close together rather than individually. Am I using it wrong?

My macro, for reference (a modification of one of the ToC macros):

\define collapse(spoiler, content)
\whitespace trim
<$let collapse-state=<<qualify "$:/tavi-vi/state/collapse">>>
  <$reveal type="nomatch" stateTitle=<<collapse-state>> text="open">
    <$button setTitle=<<collapse-state>> setTo="open" class="tc-btn-invisible">
      {{$:/core/images/right-arrow}}
      <span>$spoiler$</span>
    </$button>
  </$reveal>
  <$reveal type="match" stateTitle=<<collapse-state>> text="open">
    <$button setTitle=<<collapse-state>> setTo="close" class="tc-btn-invisible">
      {{$:/core/images/down-arrow}}
      <span>$spoiler$</span>
    </$button>
  </$reveal>
  <$reveal type="match" stateTitle=<<collapse-state>> text="open">
    <div>$content$</div>
  </$reveal>
</$let>
\end

The documentation for the qualify macro (see https://tiddlywiki.com/#qualify%20Macro) says this:

It returns a unique string that encodes its position within the widget tree, as identified by the stack of transcluded tiddlers that lead to that position.

Take note of that last part “… as identified by the stack of transcluded tiddlers …”.

Thus, as you have observed, the value returned by the qualify macro will be the same for every instance within the same tiddler. One way to work around this limitation is to append an additional identifier that you can pass as a parameter to your collapse macro, like this:

\define collapse(spoiler,content,id)
\whitespace trim
<$let collapse-state=<<qualify "$:/tavi-vi/state/collapse/$id$">>>
...

Then, when you use your macro, you could write something like:

<<collapse "spoiler" "content" "1">>
<<collapse "spoiler" "content" "2">>
<<collapse "spoiler" "content" "3">>
etc.

-e

1 Like

I was meaning for it be be used in arbitrary contexts, having to manually make the qualification more unique is error prone and doesn’t really compose well…

Welcome @Tavi , as Eric says, the qualify macro may “qualify something”, but any qualification tends to have its scope. In this case the scope it the tiddler and its place in the tree; eg a tiddler may be transcluded in another.

  • The parameter to the qualify macro is often a prefix but this is the way to further qualify the result.
  • You could use other methods to “qualify something” such as CSS ID’s or classes etc…

Thanks for the suggestions. None of this is sufficient. I’ll just buy a filing cabinet.

You can try this…

\define collapse(spoiler, content)
\whitespace trim
<$let
     collapse-state=<<qualify "$:/tavi-vi/state/collapse-$spoiler$">>>
  <$reveal type="nomatch" stateTitle=<<collapse-state>> text="open">
    <$button setTitle=<<collapse-state>> setTo="open" class="tc-btn-invisible">
      {{$:/core/images/right-arrow}}
      <span>$spoiler$</span>
    </$button>
  </$reveal>
  <$reveal type="match" stateTitle=<<collapse-state>> text="open">
    <$button setTitle=<<collapse-state>> setTo="close" class="tc-btn-invisible">
      {{$:/core/images/down-arrow}}
      <span>$spoiler$</span>
    </$button>
  </$reveal>
  <$reveal type="match" stateTitle=<<collapse-state>> text="open">
    <div>$content$</div>
  </$reveal>
</$let>
\end


<<collapse SW1 "Darth Vader is Luke's father">>

<<collapse SW2 "Leia is Luke's sister">>

<<collapse SW3 "Darth Sideous is kiiiinda Darth Vader's father">>

These are two cases where I have used qualify macro before, obviously with Eric’s help. Sharing it here, in case it helps you.

1 Like

I m sure we can solve your problem, you just need to define it a little more.

  • For example you do not show how your macro is invoked. Obviously more than once.
  • If you just call it multiple times from within a tiddler you just need to provide an index to label the instance of its use.
  • An index need only be a unique name or number. However there may be cases where you want a set of content to open at the same time, for which you can use the same “index”.
  • The index could just be the value in spoiler which would practically be unique.
    • And if not this may be your intention.
  • Just include the index in the qualify prefix as suggested by Eric.

If you are using a list widget you can source the index number using the counter parameter eg counter=item

  • <<qualify "$:/tavi-vi/state/collapse/$(item)$">>
  • Although this will vary if you add, remove or reorder items.

I am prepared to say we can do anything :nerd_face: !

It’s probably for the best. Using completely unique identifiers would result in strange behavior, like if used in dynamic contexts, the open spoilers would change when the number of spoilers changes.

So the best solution is probably the spoiler text plus an optional unique string