Add support for relinking when renaming tiddlers

When renaming an existing tiddler, the edit template now shows a
checkbox that determines whether or not to relink references to the
tiddler in the list or tags fields of other tiddlers.
This commit is contained in:
Jermolene 2016-12-15 17:12:57 +00:00
parent 1bba9dc315
commit e8bb897e26
6 changed files with 93 additions and 26 deletions

View File

@ -18,6 +18,8 @@ Tags/Add/Placeholder: tag name
Tags/Dropdown/Caption: tag list
Tags/Dropdown/Hint: Show tag list
Title/BadCharacterWarning: Warning: avoid using any of the characters <<bad-chars>> in tiddler titles
Title/Exists/Prompt: Target tiddler already exists
Title/Relink/Prompt: Update ''<$text text=<<fromTitle>>/>'' to ''<$text text=<<toTitle>>/>'' in the //tags// and //list// fields of other tiddlers
Type/Dropdown/Caption: content type list
Type/Dropdown/Hint: Show content type list
Type/Delete/Caption: delete content type

View File

@ -349,6 +349,12 @@ NavigatorWidget.prototype.handleSaveTiddlerEvent = function(event) {
},this.wiki.getModificationFields());
newTiddler = $tw.hooks.invokeHook("th-saving-tiddler",newTiddler);
this.wiki.addTiddler(newTiddler);
// If enabled, relink references to renamed tiddler
var shouldRelink = this.getAttribute("relinkOnRename","no").toLowerCase().trim() === "yes";
if(isRename && shouldRelink && this.wiki.tiddlerExists(draftOf)) {
console.log("Relinking '" + draftOf + "' to '" + draftTitle + "'");
this.wiki.relinkTiddler(draftOf,draftTitle);
}
// Remove the draft tiddler
this.wiki.deleteTiddler(title);
// Remove the original tiddler if we're renaming it

View File

@ -15,39 +15,66 @@ Bulk tiddler operations such as rename.
/*
Rename a tiddler, and relink any tags or lists that reference it.
*/
exports.renameTiddler = function(fromTitle,toTitle) {
function renameTiddler(fromTitle,toTitle,options) {
var self = this;
fromTitle = (fromTitle || "").trim();
toTitle = (toTitle || "").trim();
options = options || {};
if(fromTitle && toTitle && fromTitle !== toTitle) {
// Rename the tiddler itself
var tiddler = this.getTiddler(fromTitle);
this.addTiddler(new $tw.Tiddler(tiddler,{title: toTitle},this.getModificationFields()));
this.deleteTiddler(fromTitle);
// Rename any tags or lists that reference it
this.each(function(tiddler,title) {
var tags = (tiddler.fields.tags || []).slice(0),
list = (tiddler.fields.list || []).slice(0),
isModified = false;
// Rename tags
$tw.utils.each(tags,function (title,index) {
if(title === fromTitle) {
tags[index] = toTitle;
isModified = true;
}
});
// Rename lists
$tw.utils.each(list,function (title,index) {
if(title === fromTitle) {
list[index] = toTitle;
isModified = true;
}
});
if(isModified) {
self.addTiddler(new $tw.Tiddler(tiddler,{tags: tags, list: list},self.getModificationFields()));
}
});
relinkTiddler(fromTitle,toTitle,options)
}
}
/*
Relink any tags or lists that reference a given tiddler
*/
function relinkTiddler(fromTitle,toTitle,options) {
var self = this;
fromTitle = (fromTitle || "").trim();
toTitle = (toTitle || "").trim();
options = options || {};
if(fromTitle && toTitle && fromTitle !== toTitle) {
this.each(function(tiddler,title) {
var type = tiddler.fields.type || "";
// Don't touch plugins or JavaScript modules
if(!tiddler.fields["plugin-type"] && type !== "application/javascript") {
var tags = (tiddler.fields.tags || []).slice(0),
list = (tiddler.fields.list || []).slice(0),
isModified = false;
if(!options.dontRenameInTags) {
// Rename tags
$tw.utils.each(tags,function (title,index) {
if(title === fromTitle) {
console.log("Renaming tag '" + tags[index] + "' to '" + toTitle + "' of tiddler '" + tiddler.fields.title + "'");
tags[index] = toTitle;
isModified = true;
}
});
}
if(!options.dontRenameInLists) {
// Rename lists
$tw.utils.each(list,function (title,index) {
if(title === fromTitle) {
console.log("Renaming list item '" + list[index] + "' to '" + toTitle + "' of tiddler '" + tiddler.fields.title + "'");
list[index] = toTitle;
isModified = true;
}
});
}
if(isModified) {
self.addTiddler(new $tw.Tiddler(tiddler,{tags: tags, list: list},self.getModificationFields()));
}
}
});
}
};
exports.renameTiddler = renameTiddler;
exports.relinkTiddler = relinkTiddler;
})();

View File

@ -1,13 +1,15 @@
title: $:/core/ui/EditTemplate/title
tags: $:/tags/EditTemplate
<$edit-text field="draft.title" class="tc-titlebar tc-edit-texteditor" focus="true"/>
<$vars pattern="""[\|\[\]{}]""" bad-chars="""`| [ ] { }`""">
<$list filter="[is[current]regexp:draft.title<pattern>]" variable="listItem">
<div class="tc-message-box">
{{$:/language/EditTemplate/Title/BadCharacterWarning}}
{{$:/core/images/warning}} {{$:/language/EditTemplate/Title/BadCharacterWarning}}
</div>
@ -15,4 +17,28 @@ tags: $:/tags/EditTemplate
</$vars>
<$edit-text field="draft.title" class="tc-titlebar tc-edit-texteditor" focus="true"/>
<$reveal state="!!draft.title" type="nomatch" text={{!!draft.of}} tag="div">
<$list filter="[{!!draft.title}!is[missing]]" variable="listItem">
<div class="tc-message-box">
{{$:/core/images/warning}} {{$:/language/EditTemplate/Title/Exists/Prompt}}
</div>
</$list>
<$list filter="[{!!draft.of}!is[missing]]" variable="listItem">
<$vars fromTitle={{!!draft.of}} toTitle={{!!draft.title}}>
<$checkbox tiddler="$:/config/RelinkOnRename" field="text" checked="yes" unchecked="no" default="no"> {{$:/language/EditTemplate/Title/Relink/Prompt}}</$checkbox>
</$vars>
</$list>
</$reveal>

View File

@ -22,7 +22,7 @@ tc-page-container tc-page-view-$(themeTitle)$ tc-language-$(languageTitle)$
<div class=<<containerClasses>>>
<$navigator story="$:/StoryList" history="$:/HistoryList" openLinkFromInsideRiver={{$:/config/Navigation/openLinkFromInsideRiver}} openLinkFromOutsideRiver={{$:/config/Navigation/openLinkFromOutsideRiver}}>
<$navigator story="$:/StoryList" history="$:/HistoryList" openLinkFromInsideRiver={{$:/config/Navigation/openLinkFromInsideRiver}} openLinkFromOutsideRiver={{$:/config/Navigation/openLinkFromOutsideRiver}} relinkOnRename={{$:/config/RelinkOnRename}}>
<$dropzone>

View File

@ -1996,6 +1996,12 @@ a.tc-tiddlylink.tc-plugin-info:hover .tc-plugin-info > .tc-plugin-info-chunk > s
color: <<colour message-foreground>>;
}
.tc-message-box svg {
width: 1em;
height: 1em;
vertical-align: text-bottom;
}
/*
** Pictures
*/