[TW5] creating new tiddlers silently?

408 views
Skip to first unread message

Alberto Molina

unread,
Jan 30, 2015, 9:55:57 AM1/30/15
to tiddl...@googlegroups.com
Hi all,

When setting a field (action-setfield) of a non-existing tiddler, that tiddler is created silently : it doesn't open in edit mode nor shows itself in the story river.

Is there a way to get the same behaviour when creating a new tiddler with tm-new-tiddler messages?

Regards,

Alberto

Stephan Hradek

unread,
Jan 30, 2015, 10:21:58 AM1/30/15
to tiddl...@googlegroups.com
Is it required?

You could use the setfield to do that. Simply set the title field.

Jed Carty

unread,
Jan 30, 2015, 11:58:47 AM1/30/15
to tiddl...@googlegroups.com
I haven't found a way to do it, but I haven't found a time when I couldn't do the same thing using action-setfield.

If you want to silently make a tiddler using a templat, use action setfield to set the name of the template, it will create a copy of the template with the new name.

do you have a situation where this wouldn't work?

Patrick Detzner

unread,
Jan 30, 2015, 7:45:19 PM1/30/15
to
Hi Alberto,

Yes, I have done this for my TW5 (pespot.tiddlyspot.com). What I did was to modify the navigator widget and add a new message called "new."

var NavigatorWidget = function(parseTreeNode,options) {
this.initialise(parseTreeNode,options);
this.addEventListeners([
{type: "tm-navigate", handler: "handleNavigateEvent"},
{type: "tm-edit-tiddler", handler: "handleEditTiddlerEvent"},
{type: "tm-delete-tiddler", handler: "handleDeleteTiddlerEvent"},
{type: "tm-save-tiddler", handler: "handleSaveTiddlerEvent"},
{type: "tm-cancel-tiddler", handler: "handleCancelTiddlerEvent"},
{type: "tm-close-tiddler", handler: "handleCloseTiddlerEvent"},
{type: "tm-close-all-tiddlers", handler: "handleCloseAllTiddlersEvent"},
{type: "tm-close-other-tiddlers", handler: "handleCloseOtherTiddlersEvent"},
{type: "tm-new-tiddler", handler: "handleNewTiddlerEvent"},
---> {type: "new", handler: "handleNewEvent"},
{type: "tm-import-tiddlers", handler: "handleImportTiddlersEvent"},
{type: "tm-perform-import", handler: "handlePerformImportEvent"}
]);
};

Then I copied the code for "handleNewTiddlerEvent" and changed it so that it doesn't create add the draft of the new tiddler to the top of the story. Add this in the navigator widget somewhere:

NavigatorWidget.prototype.handleNewEvent = function(event) {
// Get the story details
var storyList = this.getStoryList(),
templateTiddler, additionalFields, title, draftTitle, existingTiddler;
// Get the template tiddler (if any)
if(typeof event.param === "string") {
// Get the template tiddler
templateTiddler = this.wiki.getTiddler(event.param);
// Generate a new title
title = this.wiki.generateNewTitle(event.param || $tw.language.getString("DefaultNewTiddlerTitle"));
}
// Get the specified additional fields
if(typeof event.paramObject === "object") {
additionalFields = event.paramObject;
}
if(additionalFields && additionalFields.title) {
title = additionalFields.title;
}
// Generate a title if we don't have one
title = title || this.wiki.generateNewTitle($tw.language.getString("DefaultNewTiddlerTitle"));
// Find any existing draft for this tiddler
draftTitle = this.wiki.findDraft(title);
// Pull in any existing tiddler
if(draftTitle) {
existingTiddler = this.wiki.getTiddler(draftTitle);
} else {
existingTiddler = this.wiki.getTiddler(title);
}
// Merge the tags
var mergedTags = [];
if(existingTiddler && existingTiddler.fields.tags) {
$tw.utils.pushTop(mergedTags,existingTiddler.fields.tags)
}
if(additionalFields && additionalFields.tags) {
// Merge tags
mergedTags = $tw.utils.pushTop(mergedTags,$tw.utils.parseStringArray(additionalFields.tags));
}
if(templateTiddler && templateTiddler.fields.tags) {
// Merge tags
mergedTags = $tw.utils.pushTop(mergedTags,templateTiddler.fields.tags);
}
var draftTiddler = new $tw.Tiddler({
text: "",
},
templateTiddler,
existingTiddler,
additionalFields,
this.wiki.getCreationFields(),
{
title: title,
tags: mergedTags
},this.wiki.getModificationFields());
this.wiki.addTiddler(draftTiddler);
// Add a new record to the top of the history stack
this.addToHistory(title);
return false;
};

Then you can trigger this to happen the same way you would use a "tm-new-tiddler" message, for example, with a button:

<$action-sendmessage  $message="new" $param=$template$/>

Edit: I should have read the other 2 responses more carefully - they are a lot simpler! The only benefit to this approach that I can think of is that you can take advantage of TW's automatic title generation. I'm not sure what would happen if you used action-setfield to name a tiddler using a title that has already been used. Maybe TW would take care of it anyway.

Jed Carty

unread,
Jan 30, 2015, 8:16:00 PM1/30/15
to tiddl...@googlegroups.com
The automatic title generation could be a big benefit. I just tested it and the action-setfield widget will overwrite a tiddler if you use it to give another tiddler the same name.

Alberto Molina

unread,
Jan 31, 2015, 5:39:58 AM1/31/15
to tiddl...@googlegroups.com
Thanks everybody,

I'm a fool for not using the setfield solution earlier. It works better than expected.

Alberto

James Mars

unread,
Mar 28, 2015, 3:28:21 AM3/28/15
to tiddl...@googlegroups.com
Hi Jed,

How exactly do you use a template with the action-setfield widget?

Danielo Rodríguez

unread,
Mar 28, 2015, 1:14:44 PM3/28/15
to tiddl...@googlegroups.com
It is not possible to use a template at all. What Alberto does is setting each field individually.

Jed Carty

unread,
Mar 28, 2015, 1:26:35 PM3/28/15
to tiddl...@googlegroups.com
If you use:

<$button>Make Tiddler
<$action-setfield $tiddler='TemplateTiddler' $field='title' $value='NewTiddlerName'/>
</$button>

where you replace TemplateTiddler with the templates name, and NewTiddlerName with the desired name the button will make a copy of TemplateTiddler called NewTiddlerName without affecting TemplateTiddler.

I put some stuff on inmysocks.tiddlyspot.com about this.

James Mars

unread,
Mar 28, 2015, 8:20:38 PM3/28/15
to tiddl...@googlegroups.com
Thanks very much Jed.. I've been waiting for a good number of months for this solution :). I experimented a little with your code and this is what I found out. In my case, I needed not only to create a new tiddler based on a template, but also populate its fields. I had:

<$action-setfield $tiddler="MyTemplate" $field="title" $value=<<MyNewTitle>> firstname=<<FirstName>> lastname=<<LastName>>/>

The result was a bit weird: it both modified the actual template itself to include the firstname and lastname inputs, as well as created a separate tiddler (MyNewTitle) based on the template but with the firstname and lastname fields left unmodified.

However the following code gave the desired behaviour; It left the template tiddler untouched and created a new tiddler based on the template and populated its fields.

<$action-setfield $tiddler="MyTemplate" $field="title" $value=<<MyNewTitle>>/>
<$action-setfield $tiddler=<<MyNewTitle>> firstname=<<FirstName>> lastname=<<LastName>>/>

Thanks again.

Richard Smith

unread,
Mar 28, 2015, 11:25:19 PM3/28/15
to tiddl...@googlegroups.com
I think you can combine those two lines, like this

<$action-setfield $tiddler="MyTemplate" title=<<MyNewTitle> firstname=<<FirstName>> lastname=<<LastName>>/>

Regards,
Richard

James Mars

unread,
Mar 29, 2015, 12:35:31 AM3/29/15
to tiddl...@googlegroups.com
Hi Richard,

I did try that one too, and I've just tried it again: the behaviour is identical to the problem I mentioned above, it modifies both the template tiddler and creates a new tiddler. Might be a bug :)

Jed Carty

unread,
Mar 29, 2015, 12:41:00 AM3/29/15
to tiddl...@googlegroups.com
I couldn't make it work using one line. If I understand correctly this is consistent with how action-setfield works.
The action-setfield widget uses the wiki.setText function to overwrite the old tiddler by creating a new tiddler with the same name as the old tiddler, just with the new field appended to the tiddler data. When you set the value of an existing field the new value takes the place of the the old one in the created tiddler, so when you change the title field the new tiddler is created, but since the title of the new tiddler is different, the old tiddler isn't affected.
When you set multiple fields using a single set widget this process is repeated once for each field in sequence, but each time it is starting out with the tiddler given by the $tiddler input. So you can do this in one line IF you have the order of the inputs such that the title field is given last, AND you want the changes to affect the original template tiddler as well, because the fields are added to the template tiddler one by one, and then a new tiddler is created. If you have 'title=newtitle' first than none of the changes after that are applied to the new tiddler, but they are applied to the template. Unless you want to change the template this probably isn't a good way to do it.

James Mars

unread,
Mar 29, 2015, 12:54:02 AM3/29/15
to tiddl...@googlegroups.com
Hi Jed,

Thanks for the explanation.. it makes sense.

James.

Richard Smith

unread,
Mar 29, 2015, 5:21:04 AM3/29/15
to tiddl...@googlegroups.com
Hi Jed,

Thanks from me also for the explanation. I wasn't paying attention when I tried it - sorry James.

Regards,
Richard
Reply all
Reply to author
Forward
0 new messages