Disable self-closing tags in macros?

Hello. This is my macro:

\define detailState()
<details class='bookitem journalitem'>
\end

I expect it to give me the opening tag only, as written. I’m finding, though, that it gives me both the opening and the closing details tag.

I’m wondering how I could turn this off, or if I should approach this a different way. I’m wanting to add the “open” attribute depending on the value of one of the fields of the current tiddler.

Unfortunately you can’t spit html content across more than one macro or wikitext.

One way to achieve what you want may be the $details widget Plugins — Utilities for TiddlyWiki

In some ways you have not fully specified your problem, class definition etc… but other methods exist. Please come back and let us know if the details widget was enough!

This might get you somewhere without disabling core functionality…

\define class() bookitem journalitem
\define content() 
            🤡 oh hey
\end
\define detailState()
<$list filter="[<currentTiddler>myField[sesame]]" emptyMessage="""<details class=<<class>>>
<<content>>
</details>
""">
<details open class=<<class>>>

<<content>>
</details>
</$list>
\end

You can set a button to be a details tag, and toggle the content with a reveal widget. Same effect, but you get the benefit to use animations too while using standard html elements :slight_smile:

\define details(content:"Content",field:"details",summary:"More",tooltip:"Show more")
<$let stateTitle={{{ $:/state[{!!title}][<qualify>]+[join[/]] }}}>
<$button  class={{{ [<stateTitle>get[$field$]]  }}} actions='<$action-listops $tiddler=<<stateTitle>> $field="$field$" $subfilter="+[toggle[open]]">' tag="details">
<summary title="$tooltip$">$summary$</summary>
<$reveal stateTitle=<<stateTitle>> stateField="$field$" text="open" default="closed" type="match"  retain="yes" animate="yes" tag="div">
$content$
</$reveal>
</$button>
</$let>
<style>
/* Disable the details tag to prevent content to be hidden accidentally */
details { display:contents }
details > summary {list-style:none}
details>summary::before{content:"▸"}
details.open>summary::before{content:"▾"}
</style>
\end

<<details "Hello World" 1>>
<<details "Another one" 2>>
<<details "Bye World" 3>>

Demo (with additional styling to emulate the details widget of TW Classic) : Demos — Q&A about tiddlywiki

Embed
4 Likes

WOW!
Wonderful! Having live preview, live edit! More than Amazing
:star2: :star2: :star2: :star2: :star2:

A minor comment: why not have two way animation ? Now, only opening details uses animation!

It seems like chrome handle display:contents for the detail element differently than firefox, on firefox this can be used to disable the toggle behavior of the details element and this allows to use animation… not sure how to fix that/ if it’s possible to fix :confused:

Might be best to just use a button element and style it like a details element ?

1 Like

Wouldn’t it be nice if the contents of the $macrocall widget could be passed as a named parameter, e.g. widget-content, to the macro? This way one could wrap any amount of text within the $macrocall and let the macro wrap it with opening and closing tags or hide it or do whatever with it.

Depending on the unknown details of the OP’s problem, that might be useful in this case, or not. Would be nice to have anyway, though…

Have a nice day
Yaisog

Thanks to all who have responded! Here is my code in full. I want to be able to open and close all the details elements with a click of a button. This works, but not when I open one individually.

\define sortdirection()
[all[current]tagging[]tag[journal-entry]$(SortType)$[created]]
\end

\define detailState(state)
<details class='bookitem journalitem' $state$>
	<summary>
		<div class='serif upone'><$link /></div>
		<div class='excerpt'>
			<$wikify name="snapshot" mode="inline" text="<<firstLine>>" output="html"><<snapshot>></$wikify>
		</div>
	</summary>
	<$wikify name="remnanttext" mode="block" text="<<remnant>>" output="html"><<remnanttext>></$wikify>
</details>
\end 

<$set name=SortType filter='[<currentTiddler>get[sortorder]]'>
	<$list filter="[is[current]tag[journal]]">
		<$button>
			<$action-listops $field="sortorder" $subfilter="+[toggle[sort],[!sort]]" />
			Sort {{$:/images/google-material-design/av/outlined/24px/loop}}
		</$button>
		<$button>
			<$action-setfield $tiddler="$:/jenn/states/journalDetails" text="open"/>
			Open All
		</$button>
		<$button>
			<$action-setfield $tiddler="$:/jenn/states/journalDetails" text=""/>
			Close All
		</$button>
		<div class='spacer1'></div>
		<div class='grid_auto_1'>
			<$list filter=<<sortdirection>>>
				<div>
				<$view format="date" template="MM/DD/YY" field="created"/>
				</div>
				<div>
					<$list filter="[{!!text}splitbefore[. ]]" variable="firstLine">
					<$list filter="[{!!text}trim<firstLine>]" variable="remnant">
					<$list filter="[<remnant>length[]compare:number:ne[0]]" variable="remnantsize">
					<$macrocall $name="detailState" state={{$:/jenn/states/journalDetails}} />
					</$list>
					<$list filter="[<remnant>length[]compare:number:eq[0]]" variable="remnantsize">
						<div class='serif upone'><$link /></div>
						<div class='excerpt'>
							<$wikify name="snapshot" mode="inline" text="<<firstLine>>" output="html"><<snapshot>></$wikify>
						</div>
					</$list>
					</$list>
					</$list>
				</div>
			</$list>
		</div>
	</$list>
</$set>

Funnily enough, I’ve been working on just that in https://github.com/Jermolene/TiddlyWiki5/pull/6666

Here’s an example. First there’s a procedure definition (they are a replacement for macros that don’t do textual substitution of their parameters). It includes a <$slot> widget that defines the position in which the content will be grafted:

\procedure hello
<div class="frame">
    <$slot $name="greeting"/>
</div>
\end

Secondly, we invoke the procedure, but not with the <$macrocall> widget. Instead, in the PR the <$transclude> widget has been extended to be able to transclude variables, which is all that <$macrocall> ever did.

<$transclude $variable="hello">
    <$fill $name="greeting">
        <h1>A heading</h1>
        <p>A paragraph</p>
    </$fill>
</$transclude >

The result would be:

<div class="frame">
    <h1>A heading</h1>
    <p>A paragraph</p>
</div>
5 Likes

:dizzy_face:
I am looking forward to reading the docs page describing all this new syntax to us old-timers…
Gonna grab a pot of coffee and spend the evening reading through that PR. Or maybe the next morning.

Have a nice day
Yaisog

1 Like

Thank you Jeremy!
One question, does the PR also take care of generation extra

tag? From above example I see the div tag and this is great!

What I’m running into now is that when the detailState macro is rendered, it is expanding the Boolean attribute “open” into “open=true”. Thus when I have collapsed all of my details elements via a TW button but open one of them with the native disclosure widget, I can get a state like this:

<details class="bookitem journalitem" closed="true" open>
</details>

Wondering if there is a way to use the wikify widget inside the macro to prevent this substitution.

Here’s my code in full again.

\define sortdirection()
[all[current]tagging[]tag[journal-entry]$(SortType)$[created]]
\end

\define detailContent()
<summary>
<div class='serif upone'><$link /></div>
<div class='excerpt'>
<$wikify name="snapshot" mode="inline" text="<<firstLine>>" output="html"><<snapshot>></$wikify>
</div>
</summary>
<$wikify name="remnanttext" mode="block" text="<<remnant>>" output="html"><<remnanttext>></$wikify>
\end

\define detailState(openclosed:"closed")
<details class='bookitem journalitem' $openclosed$>
<<detailContent>>
</details>
\end 

<$set name=SortType filter='[<currentTiddler>get[sortorder]]'>
	<$list filter="[is[current]tag[journal]]">
		<$button>
			<$action-listops $field="sortorder" $subfilter="+[toggle[sort],[!sort]]" />
			Sort {{$:/images/google-material-design/av/outlined/24px/loop}}
		</$button>
		<$button>
			<$action-setfield $tiddler="$:/jenn/states/journalDetails" text="open"/>
			Open All
		</$button>
		<$button>
			<$action-setfield $tiddler="$:/jenn/states/journalDetails" text=""/>
			Close All
		</$button>
		<div class='spacer1'></div>
		<div class='grid_auto_1'>
			<$list filter=<<sortdirection>>>
				<div>
				<$view format="date" template="MM/DD/YY" field="created"/>
				</div>
				<div>
					<$list filter="[{!!text}splitbefore[. ]]" variable="firstLine">
					<$list filter="[{!!text}trim<firstLine>]" variable="remnant">
					<$list filter="[<remnant>length[]compare:number:ne[0]]" variable="remnantsize">

					<$macrocall $name=detailState openclosed={{$:/jenn/states/journalDetails}} />

					</$list>
					<$list filter="[<remnant>length[]compare:number:eq[0]]" variable="remnantsize">
						<div class='serif upone'><$link /></div>
						<div class='excerpt'>
							<$wikify name="snapshot" mode="inline" text="<<firstLine>>" output="html"><<snapshot>></$wikify>
						</div>
					</$list>
					</$list>
					</$list>
				</div>
			</$list>
		</div>
	</$list>
</$set>

I am hoping to make use of the native HTML display routine. Although this details element is a very peculiar HTML element, and is almost a widget of its own.

There are no automatic extra tags being created here; the <div> tag in my example comes from the procedure definition.

1 Like