<$list filter='MYCONDITION' >
<div>foo</div>
</$list>
\define section(inert:"") <section $inert$>
<$list filter='If my condition is true' emptyMessage=<<section>> >
<$macrocall $name=section inert=inert />
</$list>
Hi @twMat
Wouldn’t this not render the content foo
, if the filter condition is false ?
What I am trying to find a way to do is to have the content foo
displayed always. The content foo
being surrounded by a <div></div>
html tag should depend on the condition.
\define foomacro() foo
<$list filter='condition' emptyMessage=<<foomacro>> >
<div><<foomacro>></div>
</$list>
I tried the following based on code above:
\define section(inert:"") <section $inert$>
<$list filter='[[2]compare:number:eq[2]]' emptyMessage=<<section>> >
<$macrocall $name=section inert=inert />
</$list>
This is a section content
</section>
But it gets displayed as below
This is a section content </section>
I was expecting an output of
This is a section content
Why would TiddlyWiki not match the <section>
generated by the macro with the wikitext </section>
tag?
@rguy I am curious as to why you want this, in part because I think there are other ways to use HTML in tiddlywiki you may not be aware of, that your question is too specific that we can’t address the bigger picture?
Hi @rguy, you may be interested in a pre-release feature of the <$genesis> widget: the ability to not create a widget if the value of $type is blank.
@xcazin I will take a look at it. Thanks.
@TW_Tones True; there might be other ways to use HTML in tiddlywiki I may not be aware of and I hope I can get a solution in this group. I am trying to wrap a block of wikitext in html tag conditionally. But I guess am running into problems with how transclusion and substitution work in TW.
I have a long single tiddler, having multiple paragraphs, constructed using macros (within tiddler and javascript macros) and wikitext.
Now, I would conditionally like to wrap a particular paragraph foo
(that is constructed using macros and wikitext) with html code (in my case wap foo
within a <section>
html tag)
I tried various mechanisms as above, but all of them result in the problem of either
- the tag is not “evaluated”/wikified in sync with the end/closing html tag
- the tag is not wikified at all and displays as text in the tiddler.
I would guess that this happens because the listwidget outputs a list so the <section inert>
is probably wrapped in <li><section insert></li>
which breaks the structure for the <section>..</section>
construct.
Instead, you should do:
\define section(inert:"")
<section $inert$>
This is a section content
</section>
\end
<$list filter='[[2]compare:number:eq[2]]' emptyMessage=<<section>> >
<$macrocall $name=section inert=inert />
</$list>
(BTW, the that inner macrocallwidget can be shortened to just <<section inert>>
)
HTML constructs cannot span transclusion boundaries.
Coming from an HTML background, you might think of transclusion as being a textual substitution process similar to conventional HTML templating systems.
Instead, it’s best to think of a transclusion as a special type of HTML element that performs the transclusion. As such, you can see by analogy that it wouldn’t be possible for the opening tag of an HTML construction to be within one <div>
while the closing tag is in an adjacent <div>
.
Forgive me , But I still don’t understand the purpose of this construction; Here are a few tips that may lead to a solution,
- Some widgets actually accept a html tag as a parameter, such as the button widget. So setting this you can determine which tag is used to wrap the content.
- Html sections and all html tags including arbitrary tags can be used in wikitext quite freely, as long as you honour the correct closing tags.
- All class and style tags are operational, the only thing that does not work with html is interactions that need javascript. We have smarter ways.
- Commonly when you do this we use CSS to determine if it is displayed or not. eg
display: none;
- list and reveal can conditionally display text, wikitext or HTML, in the following example if the current tiddler has one or more tags. The content can just be html, as can be a tiddler using the list widgets template parameter.
<$list filter="[all[current]tags[]limit[1]]" variable=nul>
<section>
Content of section
</section>
</$list>
Installing the core plugin TiddlyWiki Internals as on tiddlywiki.com adds an additional editor preview that shows how the tiddler gets rendered into html. this will help you see the results once tiddlywiki has its way with the content.
If you do use a list widget you need to leave a blank line before using wikitext so that tiddlywiki puts it into block mode.
Eg
<$list filter="[all[current]tags[]limit[1]]" variable=nul>
* List item
</$list>
the above works, but the following fails to render the wikitext “*” as a list item <li></li>
<$list filter="[all[current]tags[]limit[1]]" variable=nul>
* List item
</$list>
- If you use the raw HTML preview you can see what tiddlywiki’s render process does. Unless it know better it often wraps things in a the
<p></p>
tags
The reverse also works
<section style="display:none;">
Section containing list widget
<$list filter="[all[current]tags[]limit[1]]" variable=nul>
* List item
</$list>
</section>
But not until you remove the display: none;
Wiki text will not work correctly unless it knows which mode its in inline or block
<section style="display:none;">
Section containing list widget
<$list filter="[all[current]tags[]limit[1]]" variable=nul>
* List item
</$list>
</section>
The following fails to render the wikitext
<div>
;Heading
:detail
</div>
This following does not;
<div>
;Heading
:detail
</div>
This is a personal opinion, but tiddlywiki ultimately passes through most html (not javascript/onclick etc) so you gain the power of tiddlywiki and most of html at the same time. With ample Widget support for the rest. Html in tiddlywiki is more powerful in tiddlywiki than outside it.
- You just need to learn some exceptions because tiddlywiki needs to also interpret its own markup, macros and widgets.
As is common from me, I would rather know what you are trying to achieve than what you are trying to fix, if I had a better idea of what you want to achieve, rather than you asking how to do something a particular way, a way I think may be based on a misunderstanding, I suspect I can answer.
- What is the root cause or desired outcome?
[Edited] see also https://tiddlywiki.com/#HTML%20in%20WikiText
especialy
Attributes
In an extension of conventional HTML syntax, attributes of elements/widgets can be specified in several different ways:
- a literal string
- a transclusion of a TextReference
- a transclusion of a macro/variable
- as the result of a Filter Expression
The above allows you to use wikitext to provide attribute values to html.
Also even this works
\define html-code(tag)
<$tag$>
content
</$tag$>
\end
<<html-code li>>
<<html-code div>>
- use the internals’ Raw HTML preview to see what it does.
Hi @rguy again, the issue here is that in TiddlyWiki transclusions are not implemented via textual substitution. Instead, the HTML syntax is extended to allow attribute values to be set as dynamic values. This is done by using special quotes around the attribute value:
-
attr={{title!!field}}
sets an attribute to a value transcluded from a tiddler field -
attr=<<variable>>
sets an attribute to a value transcluded from a variable or macro -
attr={{{ filter ]}}
sets an attribute to the first result of evaluating a filter expression
So, to set an attribute of an element dynamically you can do something like:
<section lang={{{ [<language>match[french]then[fr-FR]else[en-GB]] }}}>
But, in your case, you want to control an attribute that doesn’t have a value, or rather, the value of the attribute is ignored, and it is its presence or absence that determines whether it is applied.
For those attributes, it is necessary to use the <$genesis>
widget, which permits full control over a generated HTML element and its attributes.
For example:
<$let mycondition="yes">
<$genesis $type="section" $names={{{ [<mycondition>match[yes]then[inert]] }}} $values={{{ [<mycondition>match[yes]then[inert]] }}}>
This is the text within the section
</$genesis>
</$let>
The $names
and $values
attributes are both filters, the first yielding the name of attributes to be assigned and the second yielding their corresponding values.
Thanks. That is useful. [1] [2] [3] [$:/plugins/tiddlywiki/internals]
In a long interactive tiddler with many paragraphs, I would like to be able to selectively/conditionally
- wrap a given paragraph within html code/tag
- have the ability to dynamically choose the attribute and its values for that html tag (conditionally based on prior user interaction).
Is there a way in Tiddlywiki to achieve simple text substitution? I thought inline macros did just that like pragma statements of programming languages? Should I be exploring $wikify [1] [2] for such use cases?
This approach seems to provide the available best fit for my requirement. I want to provide a dynamically constructed css style
attribute along with the inert
attribute. But then again I am running into similar earlier problems.
https://groups.google.com/g/tiddlywiki/c/46pEC0E8nLA/m/8B3k2GWfAwAJ
Tried using @TW_Tones macro to pass variable number of attribute names/values for the $genesis
widget.
\define multiparam2(string delim:" " )
<$list filter="[[$string$]split[$delim$]]"><<currentTiddler>> </$list>
\end
<$genesis $type="section" $names=<<multiparam2 "style inert">> $values="val1 val2" />
It generates raw HTML like so:
<section "><<currentTiddler>>="" <$list="val1" </$list>="" filter="="val2" inert="" style=""></section>
Not what is expected.
- OK, I can see what you are asking
- But why do you need to use the HTML method when TiddlyWikis native list and reveal widgets are designed for this very purpose?
- To what purpose do you wish to use the inert?
- My HTML/CSS resource is w3schools and they do not even list it as a valid attribute
Hi @rguy, TW macros are no functions: your call to multiparam2
just copies the whole text of the macro into the $names attribute If you want to compute the $names
, you should use filters, as shown by Jeremy above. A very simple filter is probably what you want in this case: <$genesis $type="section" $names="style inert" $values="val1 val2" />
Why not use HTML?
In this particular case, a direct html code is the shortest and apt use to achieve desired functionality. An equivalent wikitext would be much more verbose and indirect.
Am not sure how a list/reveal is related to a section/div html tag. I am not working with a list. I am not hiding/revealing content either. I am highlighting/decorating a part of content conditionally.
Now, how do I dynamically generate the values for $names and $values.
If I knew the values before hand, I wouldn’t need the $genesis widget; I could directly write the equivalent html tag.
How would you explain this wikitext snippet…
\define htmlparam() ok
<section <<htmlparam "">> >
<section <<htmlparam>> >
…generating a html as below?
<p><section ok >
<section <<htmlparam="true">> >
</section></p>
Notice the big difference in output when passing in a parameter vs not passing in a parameter in the macro call.
If macros were a direct substitution, we should be expecting an output like so:
<section ok >
<section ok >
Hi @rguy I may finally have understood your idea. What about this:
\define is_wrapped() yes
\define is_styled() yes
<$genesis $type={{{ [<is_wrapped>match[yes]then[section]] }}}
$names=" [<is_styled>match[yes]then[style]] [<is_wrapped>match[yes]then[inert]]"
$values="[<is_styled>match[yes]then[val1]] [<is_wrapped>match[yes]then[val2]] ">
This text only gets wrapped with a `<section>` element when the `is_wrapped` macro/variable is set to ''yes''.
</$genesis>
Note that this only works fully with the 5.2.6 prerelease: before this release, the $type
attribute cannot be set to a blank value. The transcluded filter for $type
returns nothing when <is_styled>
is not set to yes, while $names
and $values
filters also change their returned values depending of the value of <is_wrapped>
.
I don’t know if this will help you. I figured it out recently answering my own question.
I wrapped the open tag in two lists, one including the tag, one not including it.
<$list filter="[<something>mycondition[param]]">
<section inert>
</$list>
<$list filter="[<something>!mycondition[param]]">
<section>
</$list>
Notice the !
in the second filter.
It’s not clear if it would help, but it worked for me.
@rguy based on decades of experience with TiddlyWiki I am confident you are making some assumptions that make this whole thread and your support much more complicated.
I could certainly help you a lot more if I/we did not have to second guess this which you have not yet answered;
- This is a design assumption which I think is incorrect, maybe correct in a pure HTML document but not in TiddlyWiki. This is why returning to what the desired outcome is, not how would help.
- Well that illustrates to me in part where I can help you, because I do see the relationships.
It is up to you @rguy if you want a substantial answer to the technical questions you are posing please step back and describe the broader picture so I/we can provide better solutions and break you out of particular path you are currently following.