Updated TrashPlugin - Now honours a "dontDelete" tag

49 views
Skip to first unread message

David Szego

unread,
Feb 12, 2012, 9:42:43 PM2/12/12
to TiddlyWiki, i...@idomagal.com
Oddly, exactly 6 years after the last version, I've added a feature to
Ido Magal's "TrashPlugin". Now the Delete button won't do anything on
Tiddlers tagged with "dontDelete".

This is a great way to prevent critical Tiddlers (system, themes, css,
etc.) from getting accidentally wiped!

Enjoy,
David Szego


/***
|''Name:''|TrashPlugin|
|''Version:''|1.1.1 (Feb 12, 2012) |
|''Source:''|http://ido-xp.tiddlyspot.com/#TrashPlugin|
|''Author:''|Ido Magal (idoXatXidomagalXdotXcom)|
|''Licence:''|[[BSD open source license]]|
|''CoreVersion:''|2.1.0|
|''Browser:''|??|

!Description
This plugin provides trash bin functionality. Instead of being
permanently removed, deleted tiddlers are tagged with "Trash." Empty
the trash by clicking on the <<emptyTrash>> button in the [[Trash]]
tiddler. Holding down CTRL while clicking on "delete" will bypass the
trash.

!Installation instructions
Create a new tiddler in your wiki and copy the contents of this
tiddler into it. Name it the same and tag it with "[[systemConfig]]".
Save and reload your wiki.

!Uninstallation instructions
1. Empty the [[Trash]] ( <<emptyTrash>> )
2. Delete this tiddler.

!Revision history
* V1.1.1 (Feb. 12, 2012)
** Added "dontDelete" as an exception tag to prevent things from being
trashed
* V1.1.0 (Dec 12, 2006)
** added movedMsg (feedback when tiddler is tagged as Trash)
** make sure tiddler actually exists before tagging it with "Trash"
** fetch correct tiddler before checking for "systemConfig" tag
* V1.0.3TT.1 (TiddlyTools variant) (Dec 11, 2006)
** don't create Trash tiddler until needed
** remove Trash tiddler when no trash remains
** don't tag Trash tiddler with "TrashPlugin"
** moved all user-visible strings to variables so they can be
translated by 'lingo' plugins
** use displayMessage() instead of alert()
* v1.0.3 (Dec 11, 2006)
** Fixed broken reference to core deleteTiddler.
** Now storing reference to core deleteTiddler in emptyTrash macro.
** Reduced deleteTiddler hijacking to only the handler.
* v1.0.2 (Dec 11, 2006)
** EmptyTrash now uses removeTiddler instead of deleteTiddler.
** Supports trashing systemConfig tiddlers (adds systemConfigDisable
tag).
* v1.0.1 (Dec 10, 2006)
** Replaced TW version with proper Core reference.
** Now properly hijacking deleteTiddler command.
* v1.0.0 (Dec 10, 2006)
** First draft.

!To Do
* Make trash keep only n days worth of garbage.
* Add undo.
* rename deleted tiddlers?

!Code
***/
//{{{

config.macros.emptyTrash =
{
tag: "Trash",
preventionTag: "dontDelete",
movedMsg: "'%0' has been tagged as '%1'",
label: "empty trash",
tooltip: "Delete items tagged as %0 that are older than %1 days old",
emptyMsg: "The trash is empty.",
noneToDeleteMsg: "There are no items in the trash older than %0
days.",
confirmMsg: "The following tiddlers will be deleted:\n\n'%0'\n\nIs it
OK to proceed?",
deletedMsg: "Deleted '%0'",

handler: function
( place,macroName,params,wikifier,paramString,tiddler )
{
var namedParams = (paramString.parseParams(daysOld))[0];
var daysOld = namedParams['daysOld'] ? namedParams['daysOld'][0] :
0; // default
var buttonTitle = namedParams['title'] ? namedParams['title'][0] :
this.label;
createTiddlyButton ( place, buttonTitle,
this.tooltip.format([ config.macros.emptyTrash.tag,daysOld ]),
this.emptyTrash( daysOld ));
},

emptyTrash: function( daysOld )
{
return function()
{
var collected = [];
var compareDate = new Date();
compareDate.setDate( compareDate.getDate() - daysOld );
store.forEachTiddler(function ( title,tiddler )
{
if ( tiddler.tags.contains( config.macros.emptyTrash.tag ) &&
tiddler.modified < compareDate )
collected.push( title );
});

if ( collected.length == 0 )
{
if ( daysOld == 0 )
displayMessage( config.macros.emptyTrash.emptyMsg );
else

displayMessage( config.macros.emptyTrash.emptyMsg.format( [daysOld] ) );
}
else {
if (
confirm( config.macros.emptyTrash.confirmMsg.format( [collected.join( "',
'" )] ) ) )
{
for ( var i=0;i<collected.length;i++ )
{
store.removeTiddler( collected[i] );

displayMessage( config.macros.emptyTrash.deletedMsg.format( [collected[i]] ) );
}
}
}
// remove Trash tiddler if no trash remains
if ( store.getTaggedTiddlers( config.macros.emptyTrash.tag ).length
== 0 ) {
story.closeTiddler( config.macros.emptyTrash.tag,true,false);
store.removeTiddler( config.macros.emptyTrash.tag );
}
else
story.refreshTiddler( config.macros.emptyTrash.tag,false,true );
store.setDirty( true );
}
}
}

////////////////// hijack delete command

config.macros.emptyTrash.orig_deleteTiddler_handler =
config.commands.deleteTiddler.handler;
config.commands.deleteTiddler.handler = function( event,src,title )
{
// if tiddler exists (i.e., not a NEW, unsaved tiddler in edit mode)
and not bypassing Trash (holding CTRL key) and not tagged with the
prevention tag ("dontDelete" by default)
if ( store.tiddlerExists( title ) && !event.ctrlKey )
{
var tiddler=store.fetchTiddler(title);
if (!
tiddler.tags.contains( config.macros.emptyTrash.preventionTag ) )
{
// if Trash tiddler doesn't exist yet, create it now...
if (!store.tiddlerExists( config.macros.emptyTrash.tag ))

store.saveTiddler( config.macros.emptyTrash.tag,config.macros.emptyTrash.tag,
"<<emptyTrash>>","TrashPlugin",new Date(),null );
// set tags on tiddler
store.setTiddlerTag( title,1,config.macros.emptyTrash.tag );
store.setTiddlerTag( title,1,"excludeLists" );
store.setTiddlerTag( title,1,"excludeMissing" );
if (tiddler.tags.contains( "systemConfig" ))
store.setTiddlerTag( title,1,"systemConfigDisable" );
// close tiddler, autosave file (if set), and give user feedback
story.closeTiddler( title,true,event.shiftKey || event.altKey );
if( config.options.chkAutoSave )
saveChanges();

displayMessage(config.macros.emptyTrash.movedMsg.format( [ title,config.macros.emptyTrash.tag ] ));
}
}
else {
config.macros.emptyTrash.orig_deleteTiddler_handler.apply( this,
arguments );
}
story.refreshTiddler( config.macros.emptyTrash.tag,false,true );
return false;
};
//}}}

Eric Shulman

unread,
Feb 12, 2012, 11:46:42 PM2/12/12
to TiddlyWiki


On Feb 12, 6:42 pm, David Szego <david.sz...@gmail.com> wrote:
> Oddly, exactly 6 years after the last version, I've added a feature to
> Ido Magal's "TrashPlugin". Now the Delete button won't do anything on
> Tiddlers tagged with "dontDelete".

Actually, I helped Ido to write the initial TrashPlugin. However, Ido
has not been active in the TW community for many years, and I long ago
'adopted' the plugin on TiddlyTools, where it has been updated
*several* times since 2006, including fixes for the IE page transition
problem (where deleting tiddlers causes IE to ask "are you sure you
want to leave this page?").

With regard to your specific feature change (adding support for a
'dontDelete' tag), I can understand *why* you might want this.
However, your implementation results in *no* action at all in response
to a user clicking the 'delete' command. Without feedback, such a non-
response would make the command seem *broken* rather than it being a
specifically-intended 'safety feature'. Note also that, with the
TrashPlugin enabled, deleted tiddlers are just tagged with
"trash" (and "excludeLists", etc.) and are not actually removed from
the document until you use the <<emptyTrash>> command, and then you
get a confirmation message anyway, that helps to ensure that people
won't "accidentally" delete a critical tiddler (most of which have
fallback *shadow* definitions anyway, e.g., ViewTemplate,
EditTemplate, etc.).

What I am inclined to add to the 'official' version of the plugin is
support for a "trashWarning" tag, which would ask for *confirmation*
before trashing a tiddler tagged with that value. The warning message
would be something like:
"'%0' is an important tiddler and removing it may produce
unexpected side effects. Remove anyway?"

enjoy,
-e
Eric Shulman
TiddlyTools / ELS Design Studios

----
WAS THIS ANSWER HELPFUL? IF SO, PLEASE MAKE A DONATION
http://www.TiddlyTools.com/#Donations
note: donations are directly used to pay for food, rent,
gas, net connection, etc., so please give generously and often!

Professional TiddlyWiki Consulting Services...
Analysis, Design, and Custom Solutions:
http://www.TiddlyTools.com/#Contact

David Szego

unread,
Feb 13, 2012, 10:03:32 AM2/13/12
to TiddlyWiki
Hi Eric, thanks for the comments. I didn't know you had an "enhanced"
version on your site - I'll grab it!

Your comments are all valid. As for the warnings etc., what I was
aiming for was to *prevent* a Tiddler from being deleted. I've broken
my installs too many times by not understanding what I can wipe and
what is critical to leave in place, and I've seen many people here do
the same! So, having all my "critical" Tiddlers tagged "dontDelete"
plus this TrashPlugin tweak, works perfectly for me.

Personally, I think this kind of functionality (preventing critical
Tiddlers from being deleted) should really be part of TW core!

Cheers,
David

HansBKK

unread,
Feb 13, 2012, 9:26:13 PM2/13/12
to tiddl...@googlegroups.com
Takeaway moral of the story for everyone - check Eric's site first! 8-)

David Szego

unread,
Feb 19, 2012, 7:12:43 PM2/19/12
to TiddlyWiki
One other way to do this:

In your !ViewTemplateToolbar slice from your theme, use:

<span macro="hideWhenTagged dontDelete"><span class='toolbar'
macro='toolbar [[ToolbarCommands::ViewToolbar]]'></span></span>
<span macro="showWhenTagged dontDelete"><span class='toolbar'
macro='toolbar [[ToolbarCommands::NoDelViewToolbar]]'></span></span>

and in your ToolbarCommands Tiddler, have a table row like:

|~NoDelViewToolbar|closeTiddler closeOthers attachFile +editTiddler
easyEdit jump > bookmarks +cloneTiddler fields syncing permalink
references newHere|

...where there's no delete command.

This also gets around Eric's well-founded objection of no user
feedback when clicking "delete" in the previous suggestion
(TrashPlugin update).

Cheers,
David Szego
Reply all
Reply to author
Forward
0 new messages