Wrap wikitext conditionally within a html tag / text substitution inside html tag

  1. How can I wrap a block of wikitext conditionally within a <div> tag?

If condition is true, the div tag should exist. Else the div tag should not be rendered.
One approach is to use a <$reveal> widget. But this requires me to use the widget two times - one for the opening <div> tag and another for the closing </div> tag. Is there a better more elegant approach?


  1. How can I substitute text inside/part of any html tag?

<section inert>

In the above example, how can I conditionally render/not render the inert text?
I tried something like this

\define htmlparam()
ok
\end

<section <<htmlparam "">> >
2 this section tag does not work.
</section>

But it renders the entire html line as text and doesnt parse it as html.
Shouldn’t a macro call substitute text before wikification occurs?

1 Like

The reveal-widget itself creates a DOM element. So IMO that’s not what you want.

What is the condition? … Is it the content of a state tiddler or is it a variable. That info is needed. So you should be a bit more specific about your real usecase. Otherwise we will need to guess.

The condition can be based on a variable set to a specific value.

<$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:

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 :wink: 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>&lt;section ok &gt;
<section <<htmlparam="true">&gt; &gt;
</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 >