Batch edit tiddler title

217 views
Skip to first unread message

Kalmir

unread,
Jan 4, 2019, 9:36:44 AM1/4/19
to tiddl...@googlegroups.com
Hi,

I am looking for a way to edit the title of a group of tiddlers. I would first filter the tiddlers by tag and then execute the batch edit on this group. What I want to do is to put something at the beggining of each tiddler's tiddler (like adding prefix) without changing the rest of the tittle. So in the end each tiddler will have the same prefix but different rest of the title.

The BatchEdit, BatchManipulator and TiddlerTool plugins I found don't seem to have this funcionality.

In the old discussions here, I found a reply to someone who wanted to be able to add something to the end of the text of a group of tiddlers. It looks like this:

store.suspendNotifications();
store.forEachTiddler(function(
title, tiddler) {
     if(tiddler.tags.contains("foo")) {
         // TODO: check for existing Review section first
         var body = tiddler.text + "\n!!!Review\n";
         store.saveTiddler(title, title, body, tiddler.modifier,
             tiddler.modified, tiddler.tags, tiddler.fields, false,
             tiddler.created, tiddler.creator);
     }
});
store.resumeNotifications();


So the main difference is that I want to edit the title and not the body (text field).

I should also say I am no coder and I don't even know how to run the script above or its adjusted version. But I guess I could figure that out.

Any ideas if the script above could be adjusted? If so, any tips how to run the script? Or is there a different solution?


I would be very glad for help.

Thanks,

Mira

Mark S.

unread,
Jan 4, 2019, 10:40:06 AM1/4/19
to TiddlyWiki
This discussion, from two weeks ago, is essentially the same thing:


If you were changing any other field, it wouldn't be such a big deal. But in TW everything hinges on the title. This is why, it may be better in one's projects to give a unique name to the title, and then use caption and description fields to use as titles. PMario's uni-link plugin can help with this.

I'm pretty sure the code you display is from TWC, which unfortunately had a different code base.

For anyone reading this, what would be the best way to document this particular situation?

Have fun
-- Mark
Message has been deleted

Eric Shulman

unread,
Jan 4, 2019, 12:19:12 PM1/4/19
to TiddlyWiki
First, a bit of history: the code you quoted in your post is for TiddlyWiki Classic ("TWC").  The current version of TiddlyWiki ("TW" or "TW5") was completely re-written from the ground up several years ago to take advantage of modern browser tech such as HTML5.  Additionally, in TWC, writing programmatic manipulations of tiddlers required either javascript programming or use of extra "plugins" to provide the needed syntax while in TW5, much of the programmatic syntax is provided natively within the TWCore.

Now... on to your specific question.  You wrote:
I would first filter the tiddlers by tag and then execute the batch edit on this group. What I want to do is to put something at the begining of each tiddler's tiddler (like adding prefix) without changing the rest of the tittle. So in the end each tiddler will have the same prefix but different rest of the title.

To "filter tiddlers by tag", use the <$list> widget, like this:
<$list filter="[tag[sometag]]">
   
</$list> 

The <$list> widget uses the filter to find all the matching tiddlers and then loops through all the matches and sets the value of the <<currentTiddler>> variable to each title, in turn.  By default, the <$list> widget will simply output the value of the <<currentTiddler>> resulting in the display of titles of all the matching tiddlers.  To make the widget do something else, you need to add more syntax *within* the enclosing <$list>...</$list> that references the <<currentTiddler>> variable to act on each tiddler (e.g., setting a specified field value in the <<currentTiddler>>)

For example, if you wanted to add/update a field named "matched" to "true", you would use the <$action-setfield> widget, like this:
<$list filter="[tag[sometag]]">
   <$action-setfield $tiddler=<
<currentTiddler>> matched="true"/>
</$list>

However, the above code is NOT enough to get the job done.  Because the <$action-setfield> widget changes stored tiddler values, it requires a user-initiated "trigger" event to start the process.  To achieve this, you can enclose the above <$list>...</$list> loop within a <$button> widget, like this:
<$button>
   BUTTON TEXT
   <$list filter="[tag[sometag]]">
      <$action-setfield $tiddler=<
<currentTiddler>> matched="true"/>
   </$list>
</$button>

So... for your use-case, you might think that the code would be something like:
<$button>
   BUTTON TEXT
   <$list filter="[tag[sometag]]">
      <$action-setfield $tiddler=<
<currentTiddler>> title="...NEW TITLE HERE..." />
   </$list>
</$button>

However... there are a few tricky details to consider:

First, tiddler *titles* are not just display text, but are used to uniquely identify each tiddler.  Thus, changing a title actually *copies* the existing tiddler content (all fields) to another tiddler with the specified new title and "renaming" a tiddler actually takes TWO actions: first change the title (creating a new tiddler), and then delete the tiddler with the old title, like this:
<$button>
   BUTTON TEXT
   <$list filter="[tag[sometag]]">
      <$action-setfield      $tiddler=<<currentTiddler>> title="..." /> <!-- CREATES NEW TIDDLER -->
      <$action-deletetiddler $tiddler=<<currentTiddler>> /> <!-- REMOVES OLD TIDDLER -->  
   </$list>
</$button>

The next problem is that TW5 syntax does not do direct text manipulation "in line", so assembling the desired new title (i.e., prepending some text to the beginning of the existing title) requires use of a little "helper" macro, like this:
\define newTitle(prefix) $prefix$$(currentTiddler)$
This macro takes one parameter, "prefix".  The value of the parameter is rendered into the output using the $...$ syntax (i.e., "$prefix$").  The value of the current tiddler title is already available as a variable defined in the calling scope, and is referenced using the $(...)$.

Putting it together, we get:
\define newTitle(prefix) $prefix$$(currentTiddler)$
<$button>
   BUTTON TEXT
   <$list filter="[tag[SOMETAG]]">
      <$action-setfield      $tiddler=<<currentTiddler>> title=<<newTitle "SOMEPREFIX">> />
      <$action-deletetiddler $tiddler=<<currentTiddler>> />
   </$list>
</$button>

While this works, it would be nicer if we didn't "hard code" the button label, tag to match and the prefix to be added.  To do this we can move the <$button> definition into a macro, and then invoke the macro, passing in the desired values, like this:
\define newTitle(prefix) $prefix$$(currentTiddler)$

\define addPrefix(label,tag,prefix)
<$button>
   $label$
   <$list filter="[tag[$tag$]]">
      <$action-setfield      $tiddler=<<currentTiddler>> title=<<newTitle "$prefix$">> />
      <$action-deletetiddler $tiddler=<<currentTiddler>> />
   </$list>
</$button>
\end

<<addPrefix "ClickMe!" "sometag" "SomePrefix">>

That should do it.  Let me know how it goes.

enjoy,
-e
Eric Shulman
TiddlyTools.com: "Small Tools for Big Ideas!" (tm)
InsideTiddlyWiki: The Missing Manuals







Mohammad

unread,
Jan 4, 2019, 12:42:02 PM1/4/19
to TiddlyWiki
Hi Eric,

This does the job! I tested it on tiddlywiki.com and it works like a charm.

Thank you Eric, Thanks a million.


Cheers
Mohammad

Kalmir

unread,
Jan 4, 2019, 3:37:53 PM1/4/19
to tiddl...@googlegroups.com
Mark, I am aware of TW approach to title as the unique ID. In case of my old titles as well as the new ones, the title remains unique. So I didn't think this relevant. But I get the "everything hinges on it so it is much more difficult to manipulate".

Eric, thank you a lot! Not just for the solution but also for taking time to explain each step of your code. I think I get how does it work (and am learning a bit more about TW in the process). That being said, I wasn't able to make the final version work, I am clearly missing something, but since i don't mind hard-coding label+tag+prefix, I am able to get the job done.   / Btw I know that if I change the title links to the old one won't redirect etc. but in my case this not a problem.

Mark S.

unread,
Jan 4, 2019, 3:52:33 PM1/4/19
to TiddlyWiki
Hi Kalmir,

Obviously I was wrong -- it was a lot easier than I thought. I didn't realize that changing the title with set-action would create a brand new tiddler, complete with all the fields and tags -- that was the part I imagined taking hours to work out.

Thanks,
-- Mark

TonyM

unread,
Jan 4, 2019, 5:01:12 PM1/4/19
to TiddlyWiki
Mark,

This supprises me and I would like to understand it better, and ensure its documented.

Tony

Diego Mesa

unread,
Jan 4, 2019, 8:38:14 PM1/4/19
to TiddlyWiki
Eric your answers are always fantastic. Thank you! 

Respectfully, I think I speak for many here in saying we all hope you can complete "InsideTiddlyWiki: The Missing Manuals" one day! 

Mohammad

unread,
Jan 4, 2019, 9:17:32 PM1/4/19
to TiddlyWiki
Diego
Eric not only gives fantastic solutions, but also, gives insights into what is going on behind the scene. He is of course a great teacher.

Hope he can finalize his book.

Cheers
Mohammad

Watt

unread,
Jan 5, 2019, 6:10:19 AM1/5/19
to TiddlyWiki
Eric's textbook final example works, but I had to edit the "ClickMe!", 2nd line from the bottom, to "Clickme!". The camelcase (capitalisation within a word) was stopping it working for me.
Thanks Eric!
Reply all
Reply to author
Forward
0 new messages