$:/plugins/sq/streams/Settings
contains a clickable link named Tiddler to use as new node template, which points to $:/config/sq/streams/new-node-tiddler-template
. A tiddler is usually identified by its title. A template can be interpreted as a code snippet. After I click on that link, what should I put in the text field of $:/config/sq/streams/new-node-tiddler-template
? A wikitext snippet that will be automatically inserted when I create new nodes, or the name of a tiddler that contains that wikitext snippet in its text field? I’m asking because I’m confused - I’ve tried either way and after clicking the (+) button, I’m still getting empty new nodes.
Per a Shadows search, $:/config/sq/streams/new-node-tiddler-template
is referenced in $:/plugins/sq/streams/action-macros
, so let’s see how it’s used…
<$action-createtiddler $basetitle=<<new-node>>
text=<<__startText__>>
$template={{$:/config/sq/streams/new-node-tiddler-template}}
parent=<<parent>>
stream-type="default"
stream-list=<<__streamList__>> />
It looks like the transcluded text of the config tiddler is used as the value of the $template
attribute. Further checking the docs on action-createtiddler (and looking at the “Template and custom base title” testcase in particular), you can see that the $template
attribute names a tiddler whose fields will get copied when the new tiddler is created. And you were right: normally, this would include the text field. But in this case, the widget also specifies alternate values for several fields, including text
— so the text field will not get copied over into each streams tiddler, but other named fields present in the template tiddler will be.
Unfortunately, if your goal is to start each new streams-node with the textbox already pre-filled, I don’t think it’s currently possible. I looked for the startText
variable as well, and it seems to be used specifically by macros that handle streams-node saving and splitting. For instance, when you use a keyboard shortcut to split an existing node in two, the second part of the original node becomes the starting text of the newly created tiddler.
I’m not sure if there’s any easy workaround that would achieve your goal, but perhaps @saqimtiaz can weigh in.
if your goal is to start each new streams-node with the textbox already pre-filled
This is exactly how I interpreted that config setting. I expected I can tap on the link, the config tiddler with an empty text field opens, I put my chunk of wikitext there, and everytime I tap (+) at the bottom of the tiddler, or press Enter while typing the content of a node tiddler, so a new node tiddler gets created - I magically get my thing there.
This seems to me like it might be pretty limiting, for example you might want several different types of wikitext. In your situation, I would probably create a new action macro that could be triggered from the context menu and/or keyboard shortcut that would enter a given wikitext as a prefix.
Or perhaps you can use a viewtemplate, as @etardiff has been helping me on You could configure the stream-row-body to pass all streams through a template. I do that with several different tags and have action-macros add appropriate tags and field values for different types of tiddlers I commonly use.
From my modified copy of $:/plugins/sq/streams/templates/stream-row-body, for example:
<$list filter="[all[current]tag[Record]]">
<sup>
<$link to={{!!title}}>
<$list filter="[all[current]has[caption]]" emptyMessage="{{!!title}}">
{{!!caption}}
</$list>
<i class="far fa-calendar-alt" style="font-size: 80%; position: relative; top: 0.2em; transform: translateY(-50%); margin-left: 0.1em;"></i>
</$link>
</sup>
{{||$:/Notestreams/Templates/Topical/JournalList}}
</$list>
Unfortunately diving into the plugin source code as shown above is way above my level of knowledge. So the evolution of this thread shows I’ve misunderstood the purpose of the $:/config/sq/streams/new-node-tiddler-template
setting. I’ll try to approach the problem from another direction, at the risk of moving the goalposts: is there an example with a minimal non-empty, non default value of this setting, bringing observable benefit over the vanilla, default empty setting, which I could try to study, maybe I succeed to understand it that way?
I wanted all my streams tiddlers to receive the tag “streams”, so I configured it like this:
title: $:/config/sq/streams/new-node-tiddler-template
text: StreamsTemplate
title: StreamsTemplate
tags: streams
Whenever I add a new node to a stream, the tags
field gets copied from my template tiddler to the new node tiddler → the tag is automatically applied. This makes it easy to write filters that will look only at streams tiddlers. For instance:
[tag[streams]]
→ all the streams nodes in my wiki
[tag[streams]links[]]
→ all the tiddlers linked in a streams node
[tag[streams]search[keyword]]
→ all the streams nodes that contain the word “keyword”
It also makes it much easier to exclude all the streams tiddlers when I don’t want them in my filter results:
[all[tiddlers]] -[tag[streams]] :filter[get[created]format:date[YYYY0MM0DD]match<now YYYY0MM0DD>]
→ all tiddlers created today except streams tiddlers
After all, this is exactly what I wanted, just for the value of the text field rather than adding a certain tag. But alas, as you’ve explained above, the text field is treated differently. Bad luck
@vuk, you shouldn’t allow yourself to be intimidated with this particular modification if you make a mistake you can always delete and get back to the original!
I’d be happy to post more of my version of the code later if it would be helpful for your context, @etardiff will probably note how convoluted it is and recommend refinements
In my case I set the fieldname object-type=stream-item
and avoid poluting the tag space.
I also set the streams config item “Template wikified for node title” to $:/s/<<now "[UTC]YY-0MM-0DD 0hh:0mm:0ss 0XXX">>
this places all streams items behind the system prefix.
I am currently building a view template tiddler, that on detecting the parent field, locates the root parent and provides a link to that. In the case of streams this will be the streams root.
- I am now looking at displaying an icon when the parent is a system tiddler (The titles are all but unreadable) and idealy with a mouse over preview each stream item in the tree.
So far I only managed to create an edit toolbar button that inserts the wikitext template into the stream node. It looks like this:
<$action-sendmessage
$message="tm-edit-text-operation"
$param="replace-all"
text={{Stream node template!!text}}
/>
Here Stream node template
is the tiddler that contains the actual template. Unfortunately I can only use it if I enable the editor toolbar for stream node editor in the plugin. This eats a lot of screen space, which is especially painful on smartphone, but at least it works.
I would probably create a new action macro that could be triggered from the context menu
I had a look at the first FAQ entry and the example tiddler $:/streams/contextmenu/flatten
, I can make a new context menu appear by cloning this tiddler, but I’ve yet to figure how to implement its event handler. I don’t know how to reference the stream node tiddler from there. Simply copying the edit toolbar button code from above did not work.
@vuk, I’m happy to help you with this some, as possible Could I perhaps see your Stream node template, so I can understand what you are trying to achieve?
I can tell you that you will not be able to trigger an action-sendmessage in this way. $:/plugins/sq/streams/templates/stream-row-body
is the tiddler you would want to modify in order to apply conditions to the streams view.
For example, in my $:/plugins/sq/streams/templates/stream-row-body
I have the following statement:
<$list filter="[all[current]tag[concept]] [all[current]tag[element]] [all[current]tag[reaction]] [all[current]tag[setting]] [all[current]tag[description]] [all[current]tag[character]] [all[current]tag[Notes]]">
{{||$:/config.template}}
</$list>
Roughly translated, for all tiddlers that have the tags concept, element, reaction, setting, description, character, or Notes, transclude these contents through the $:/config.template
tiddler.
The contents of that template are:
\define structure.title()
[[$(structure)$|$(parent)$]]
\end
\define title.title()
[[$(title)$|$(cover)$]]
\end
\define editable()
$(turtle)$.editable
\end
<$set name= structure value={{!!structure}}>
<$set name= title value={{!!caption1}}>
<$set name= turtle value={{!!title}}>
<$set name= cover value={{!!cover}}>
<$set name= parent value={{!!parent}}>
<$list filter="[all[current]![search[$:/config.template]]">
<!-- This line transcludes the tiddler content: -->
<$transclude tiddler=<<currentTiddler>> mode="block"/>
<$reveal type="nomatch" state=<<editable>> text="edit">
<$button set=<<editable>> setTo="edit" class="tc-btn-invisible">
{{!!pagenum}}
</$button>
</$reveal>
<$reveal type="match" state=<<editable>> text="edit">
<$edit-text tiddler=<<currentTiddler>> field="pagenum" tag="input" default="" placeholder="Enter page number" class="input-small"/>
<$button set=<<editable>> setTo="" class="tc-btn-invisible">
{{$:/core/images/done-button}}
</$button>
</$reveal>, //<<structure.title>>,// <<title.title>>. <$set name="tempStateTiddler" value=<<qualify "$:/temp/showtags/"+<<currentTiddler>>>
<$button>
{{$:/core/images/tag-button}}
<$action-setfield $tiddler=<<tempStateTiddler>> text="yes"/>
</$button>
<$reveal type="match" state=<<tempStateTiddler>> text="yes">
<$edit-text tiddler=<<currentTiddler>> field="tags" tag="input"/>
<$button>
Done
<$action-setfield $tiddler=<<tempStateTiddler>> text="no"/>
</$button>
</$reveal>
</$set>
<br><br>
</$list>
And the result is:
which renders some of the field values of those stream-list tiddlers as a reference at the bottom of the text, which you can see here:
If you are trying to make a viewtemplate that applies to all streams, I would recommend using a field that all streams (created conventionally, you’ll note that my tiddler does not have that field because it was processed by AI) have such as [all[current]field:stream-type[default]]
I have never played with $:/streams/contextmenu/flatten
I have rather made extensive modifications to $:/plugins/sq/streams/contextmenu/contextmenu-template
This will be embarrassing for me, because I’m sure there is some more-artful way to add items to the context-menu that @saqimtiaz might enlighten us both on However, this has been my approach to adding new macro triggers to the context menu and it has worked well:
Within $:/plugins/sq/streams/contextmenu/contextmenu-template
, there is a definition for common-menu-items. These are items that you want to appear on every streams context menu, and you see that I have added several of my own, including the yadda-yadda macro for the WikiSage plugin:
\define common-menu-items()
<$macrocall $name="menu-item" title="Open" actions="""<$action-navigate/>"""/>
<$macrocall $name="menu-item" title="Rename" subtitle="((streams-rename))" actions=<<rename-node-actions>>/>
<$macrocall $name="menu-item" title="Add Description" subtitle="((add-description-actions))" actions=<<add-description-actions>>/>
<$macrocall $name="menu-item" title="Mark as Stub" subtitle="((mark-stub))" actions=<<addStubTag>>/>
<$macrocall $name="menu-item" title="Copy Title" subtitle="((copy-link))" actions="""<<copy-link>>/>"""/>
<$macrocall $name="menu-item" title="Create Reference" subtitle="((create-link))" actions="""<<add-new-link>>/>"""/>
<$macrocall $name="menu-item" title="Transclude as Note" subtitle="((transclude-config))" actions="""<<transcludeAsNote>>/>"""/>
<$macrocall $name="menu-item" title="Delete" subtitle="((streams-delete))" actions=<<delete-node-actions>>/>
<$macrocall $name="menu-item" title="Add to Daily Notes" subtitle="((transclude-tiddler))" actions=<<create-transclusion-and-append-to-daily-journal>>/>
<$macrocall $name="menu-item" title="Edit Content" subtitle="" actions="""<<clarify-content-streams>>"""/>
<$macrocall $name="menu-item" title="Yadda-yadda" subtitle="((yadda-yadda))" actions="""<<yadda-yadda-streams>>"""/>
<$macrocall $name="menu-item" title="send to calendar" subtitle="" actions="""<<.addToCalendarActions>>"""/>
\end
Now I’m absolutely sure that there is a more artful way of doing this, however, in my break-shit-fast methodology I have directly modified the $:/plugins/sq/streams/action-macros
tiddler to add all action macros that I may need:
\define mark-idea-actions()
<$action-listops $tiddler=<<currentTiddler>> $field="tags" $subfilter="Idea"/>
<$action-setfield $tiddler=<<currentTiddler>> description="{{!!text}}"/>
\end
A fun note about modifying the $:/plugins/sq/streams/contextmenu/contextmenu-template
is that you can create different context menus depeneding on different conditions. For example, I have:
<$list filter="[<currentTiddler>tag[Idea]]" variable="ideaCheck">
<$macrocall $name="menu-item" title="Create Topic" subtitle="((create-topic))" actions=<<create-topic-actions>>/>
<$macrocall $name="menu-item" title="Remove Idea Tag" subtitle="((remove-idea-tag))" actions=<<removeIdeaTag>>/>
<$macrocall $name="menu-item" title="Adopt Index" subtitle="((adopt-index))" actions=<<adopt-index-actions>>/>
<$macrocall $name="menu-item" title="Add Description" subtitle="((add-description))" actions=<<add-description-actions>>/>
<$macrocall $name="menu-item" title="Recaption" subtitle="((recaption))" actions=<<recaption-actions>>/>
<$macrocall $name="menu-item" title="Add Alias" subtitle="((add-alias))" actions=<<add-alias-actions>>/>
<$macrocall $name="menu-item" title="Upgrade to Index" subtitle="((mark-index))" actions=<<mark-index-actions>>/>
<<common-menu-items>>
</$list>
What this says is that for all tiddlers with the Tag Idea, the context menu will include Idea-tiddler-specific items in addition to the common-menu-items seen above.
I can, from the context menu, tag a thing Idea, and then open the context menu again and see Idea-specific actions
Could I perhaps see your Stream node template, so I can understand what you are trying to achieve?
So far it only contains “foo”, it’s a placeholder. I don’t want a custom viewtemplate, if I understand you correctly. As I wrote initially, all I want is to have a custom tiddler - Stream node template
in this example - that contains a snippet of wikitext. Static wikitext, not parametrized. And every time I create a new stream node - I want that text prefilled into the stream node text field edit, automatically (now I do it manually, via the edit toolbar button, as explained above).
Why I need this? Typing “foo” in every new node isn’t hard, but I want to use a more complex template of course. Something collapsible like DetailsWidget Plugins — Utilities for TiddlyWiki . I want every new stream node to be prefilled with something like
<$details summary="Node head">
Node body
</$details>
This way I could not only collapse nodes in the tree (functionality provided by streams), but also collapse node content(text) and display only the first line of it (the headline, or title, as one prefers to name it), thus saving more screen space and achieving a visual look closer to a classic outline, which holds node heads in a visual tree structure and displays node bodies in another pane.
I don’t know the DetailsWidget, but yes, you could achieve that with the viewtemplate method. If your viewtemplate were
<$details summary={{!!description}} open="yes">
Content will be immediately visible if open is set to "yes".
</$details>
<$transclude tiddler=<<currentTiddler>> mode="block"/>
For example, then any time you create a node that meets the conditions, its text would appear, in view mode, with the details widget above it with a unique summary based on that tiddler’s description field (it could be any field though).
In this case I would add an action macro to the context menu that would allow me to input a description from the stream.
I actually do that with my recaption macro
\define recaption-actions()
<$action-withinput message="Enter new caption for this tiddler:" default={{!!caption}} actions="""
<$action-setfield $tiddler=<<currentTiddler>> caption=<<userInput>>/>
"""/>
\end
I realize on reflection that prior to the current method I am using (which I still highly recommend, speaking from experience ) I actually did my templates in the way I understand you are trying to achieve, and, if I am understanding you correct, I do not understand why you are having trouble.
In my wiki, whatever tiddler is in this edit text box becomes the text of any new stream node that is generated by clicking Enter to create a new stream (but not if you click the new node).
It’s very possible that this is something I’ve modified along the way, as I notice in my instance that Tiddler to use as new node template
appears twice in the plugin menu.
Let me look into that.
EDIT – Nope, looks to me like $:/config/sq/streams/new-node-tiddler-template
is controlled the same as in the original plugin. Add the tiddler title (try as a string with no spaces) to that tiddler and whatever text or wikitext is in that tiddler will be the basis of new tiddlers when you create them using enter rather than pushing the button
Add the tiddler title (try as a string with no spaces) to that tiddler and whatever text or wikitext is in that tiddler will be the basis of new tiddlers when you create them using enter rather than pushing the button
I can reproduce this. A tiddler title with spaces works as well.
I wanted the edit field prefilled in either scenario. With an empty tiddler, there’s only that (+)
at the bottom, which creates the edit for the new stream node. Until now I kept trying that and getting an text area that is empty. While typing inside it and hitting Enter to create the next edit, that edit indeed isn’t empty, it contains the text of my custom template tiddler. I don’t know if this is better or worse - a broken toy is a broken toy - at least the things are clear. A half-broken toy is even more confusing - while if I hit Enter things work as expected, I’m still confused about how to get the same result when I use the (+)
button (without having the edit toolbar enabled and pushing the custom button). What you tried to explain above about templates is too complex for me - I’ve never wrote a template yet, this is more complex than the basic things I’m currently learning. It may take a while until I will attempt to dive into the source code of streams to understand how it works.
I know you said you didn’t want a ViewTemplate, but IMO the absolute easiest and most efficient way to do this is by editing $:/plugins/sq/streams/templates/stream-row-body
, which is the template used to render nodes when they’re not being edited. Here’s a demo — note the details marker.
Unfolded:
The summary is automatically generated from the first line of text; everything after the first linebreak becomes the body of the details element. Single-line nodes (like the first node under Filters) will be normally displayed.
And here you can see there’s no special code needed in the node text.
Here’s the code I used: $__plugins_sq_streams_templates_stream-row-body.json (537 Bytes)
<$let
summary={{{ [{!!text}splitregexp[\n]!is[blank]] }}}
text={{{ [{!!text}removeprefix<summary>trim[]] }}}
>
<$list filter="[<text>!match[]]"
variable="NULL"
emptyMessage="<$transclude mode=block />"
>
<details>
<summary><<summary>></summary>
<$list filter="[<text>]"><$transclude field=title mode=block /></$list>
</details>
</$list>
</$let>
I highly recommend using a template like this over hard-coding a details widget into every streams node you create: it will avoid a lot of redundant code and make it much easier to update if you should decide you want a different format in the future. Happy to help you modify the template if you have other display needs.
I know you said you didn’t want a ViewTemplate
Don’t get me wrong, I did’t try to avoid the template approach out of just being stubborn, I was trying to avoid using a technique I’m not yet familiar with. But apparently my practical needs are pushing me towards that direction.
However, I spent a couple more hours reading through the streams code and ended in the $:/plugins/sq/streams/action-macros
hacking on the add-node-actions
macro. I’ve got to the
<$action-createtiddler $basetitle=<<new-node>> text=<<__startText__>> $template={{$:/config/sq/streams/new-node-tiddler-template}} parent=<<parent>> stream-type="default" stream-list=<<__streamList__>>/>
part and changed the startText
reference to my custom template code. This gave me that template code in the node edit textarea, no matter how I would create new streams nodes. However, then I realized that the add-node-actions
is called many times in that tiddler by other macros, is called with differed arguments, which means that I broke its functionality. So all those wasted hours at least brought me the confidence that I was solving an X-Y problem.
Now with me morally ready to go the template way, I wouldn’t want to turn this into “just copy/paste and forget it”.
It took me a while to understand the
summary={{{ [{!!text}splitregexp[\n]!is[blank]] }}}
part, as in why a filter produces only one item instead of a whole list, without explicitly using something like
limit[]
. I think I found the answer here Those Pesky Brackets — ...and other wikitext punctuation in example 2 and ultimayely here https://tiddlywiki.com/#Filtered%20Attribute%20Values
But I’ve yet to understand the point of NULL variable, which is never used explicitly.