How to snatch tags from another tiddler?

When editing an existing tiddler, I often need to add a subset of tags from another tiddler. As soon as there’s more than one tag to add, the manual process becomes tedious (especially on a smartphone). I looked at Commander plugin, but it seems to solve a different problem - it adds tags to multiple tiddlers, and it requires manually writing filters (which is still scary for a newcomer :smiley: ). Ideally, when I’m editing a tiddler, I’d like to be able to press a button in the tag area, see an input field a la search where I can fuzzy find by name the tiddler I want to snatch tags from, then see a tag list/table with checkboxes, a la Import dialog for whole tiddlers. Is this currently possible? Perhaps there’s some small plugin that can do it?

That’s a well-written spec :clap:

I think the closest thing available right now is the clone button available on each tiddler in view mode (might be hidden in the “more” dropdown).

image

That will create a copy of the tiddler with the same tags already present. Not ideal, maybe, but pretty close.

How about a “combo” box ($edit-text + $select widgets) that lets you enter a partial tiddler title, and progressively filters the $select list contents to show only matching tiddlers. You would then select one tiddler from that list.

When one unique tiddler title has been entered/selected, rather than offering a list of tags (or table with checkboxes), it would just enable a “copy tags” button next to the $select widget.

Pressing this button would copy ALL the tags from the chosen tiddler. If you don’t want all of those tags, you can then use the standard tiddler editor tag controls to remove individual tags (by clicking the “x” that is shown in each tag).

I could write the above as an installable custom $:/tags/EditTemplate component (e.g., “TiddlyTools/EditTemplates/CopyTags”) that could appear adjacent to the standard tiddler editor tag controls.

Thoughts?

-e

You haven’t done it yet? tssk. :laughing:

But, seriously… I’ve seen the combo edit control. Works a treat. So yes, I’m sure OP would be happy with that as a solution.

Cloning a tiddler is what I’m using when I create a tiddler that must inherit tags (and multiple fields). Editing an already existing tiddler, eventually created in another context, is a different story - exactly what caused the original question. Either I have to add tags manually, or clone the other tiddler, then paste the title, text (gets even worse when edited tiddler also has many fields which needs to be created in the clone), then delete the edited tiddler so the new clone replaces it. Add multiple context switches and it gets even clumsier than just adding the missing tags.

Give this a try:

\define temp() $:/temp/copytags

<$let inputid={{{ [<temp>] [<qualify>] +[join[]] }}} popid={{{ [<temp>] [[/list]] [<qualify>] +[join[]] }}}>
<$edit-text tiddler=<<inputid>> tag=input class=tc-popup-handle focusPopup=<<popid>>/>
<$let tid={{{ [<inputid>get[text]] }}}>
<$button class="tc-button" disabled={{{ [<tid>is[tiddler]then[no]else[yes]] }}}>copy tags
   <$action-listops $tags="[<tid>get[tags]enlist-input[]]"/>
</$button>
<$set name=all filter="[all[tiddlers]!is[system]!has[draft.of]]">
<$set name=items filter="[enlist<all>search:title:literal<tid>]">
<$set name=items filter="[enlist<items>match<tid>]" value=<<all>> emptyValue=<<items>>>
<$reveal state=<<popid>> type="popup">
   <$select tiddler=<<inputid>> size={{{ [enlist<items>count[]min[10]max[2]] }}}>
      <$list filter="[enlist<items>]"><option><<currentTiddler>></option></$list>
   </$select>
</$reveal>

Put the above in a tiddler (e.g., “MyEditTemplates/CopyTags”), tag it with $:/tags/EditTemplate and add a list-after field containing “$:/core/ui/EditTemplate/tags”.

enjoy,
-e

3 Likes

Marvelous @EricShulman :clap:

Personally, I’d wrap the $edit-text in keeping with the tag field itself:

<div class="tc-edit-add-tag"><div class="tc-edit-add-tag-ui">
<$edit-text tiddler=<<inputid>> tag=input class="tc-edit-texteditor tc-popup-handle" focusPopup=<<popid>>/>
</div></div>

Using the same classes as the tag field controls does look better.

I’d even go slightly further and use:

<div class="tc-edit-tags" style="float:right;">
<div class="tc-edit-add-tag"><div class="tc-edit-add-tag-ui">
<$edit-text tiddler=<<inputid>> tag=input class="tc-edit-texteditor tc-popup-handle" focusPopup=<<popid>>/>
</div></div>
...

and then move the template to occur before $:/core/ui/EditTemplate/tags. The “float:right;” style places the added UI on the same line as the tags field controls and the “tc-edit-tags” class wraps it in an enclosing box with the same padding, so everything aligns nicely.

-e

1 Like

… your <$action-delay ...> widget to remove the current selection from the $edit-text after clicking the copy tags button (set to say, ~3000ms).

I do that for a number gizmos in my wiki (thanks again for that).

@vuk Let us know how this works for you – otherwise Eric and I could be here all day tinkering with this :wink:

1 Like

41 minutes? I think Eric must be slipping. It used to be these would be done in under 20 minutes.

:wink:

True statement. I watched him last night.

I hope it’s clear that there’s no disrespect involved.

Only awe!

There’s no need for a dependency on the $action-delay widget: when the copy tags button is clicked, we can just delete the <<inputid>> tiddler to clear the input field and the current list selection.

I’ve added a bit of CSS to handle long tiddler titles in the $select list (using “text-overflow:ellipsis”)

Here’s my newly-published TiddlyTools edit template: TiddlyTools/Templates/CopyTags

which contains this wikitext code:

\define temp() $:/temp/TiddlyTools/CopyTags

<style>
.tt-copytags {
	& select { width:100%; }
	& option { overflow:hidden; text-overflow:ellipsis; }
}
</style>
@@float:right;.tt-copytags.tc-edit-tags
<$let inputid={{{ [<temp>addsuffix<qualify>] }}} popid={{{ [<temp>] [[/list]] [<qualify>] +[join[]] }}}>
<div class=tc-edit-add-tag><$edit-text tiddler=<<inputid>> tag=input class="tc-edit-texteditor tc-popup-handle" focusPopup=<<popid>>/></div>
<$let tid={{{ [<inputid>get[text]] }}}>
<$button>copy tags<$action-listops $tags="[<tid>get[tags]enlist-input[]]"/><$action-deletetiddler $tiddler=<<inputid>>/></$button>
<$set name=all filter="[all[tiddlers]!is[system]!has[draft.of]]">
<$set name=items filter="[enlist<all>search:title:literal<tid>]">
<$set name=items filter="[enlist<items>count[]regexp[0|1]]" value=<<all>> emptyValue=<<items>>>
<$reveal state=<<popid>> type=popup>
	<$select tiddler=<<inputid>> size={{{ [enlist<items>count[]min[15]max[2]] }}}>
		<$list filter="[enlist<items>]" variable=item><option title=<<item>>><<item>></option></$list>
	</$select>
</$reveal>

enjoy,
-e

I did this (as in I blindly copypasted and followed the algorithm steps, since I’m very far from understanding the code past its final achievement). I can report two bugs (albeit first one can be rather labeled as missing feature):

  1. The edit field does not behave like the “main” search of the TiddlyWiki - the appearing menu stays empty as I type. Only after I type the full name of the tag donor tiddler - its name appears in the dropdown and I can select it.
  2. Tags are getting copied, but there’s a caveat. I created a donor tiddler with the following tags: tag1, tag2, +tag3, +tag4. After I fully type the name of the donor tag so I can select it (see 1. above) and tap the copy tags button - all four tags get imported (I really prefer import over copy here, but this is a cosmetic itch and perhaps a personal thought process caprice). If I tap copy tags again, another tag tag4 appears! What kind of poltergeist is this?! Tapping the button again changes nothing. But if I delete tag4 and tap one more time - it appears again! So it’s reproductible.

PS: this is feedback to the very first version of the code.

Good God man. I’m running out of rockets to send you.

Me too.

<style>
.copy-tags-select {
  option {
    max-width:25em;
    text-overflow:ellipsis;
  }
}
</style>

I added an “exclude” list, too. Getting close to adding a config tiddler but I prefer it self-contained…

Not seen here. Which browser? Which OS?

Tiddloid 2.5.0 on Android.

Same problem in Vivaldi 6.9.3451.114 on Android.

I’m not able to develop/test/debug on mobile, sorry.

This seems to be a side-effect of using a tag that begins with “+”. The $action-listops widget sees the “+” as a filter run prefix. As a result, it adds the remainder of the tag value (i.e., “tag4”) as a new tag.

I strongly recommend never using “+” as the initial character in a tag value, as the leading “+” is has special meaning within filter syntax. The same can be said for the other filter prefix characters, such as “-”, “~”, and “=”.

-e