The
BeijingRelease needs an API for Plugins to read/write topics in a simple and secure manner. That way Plugins like the
EditTablePlugin are able to interact with TWiki without bypassing the official API.
- New functions in TWikiFuncModule
- readTopicText( $web, $topic, $rev, $ignorePermissions ) ==> $text
- saveTopicText( $web, $topic, $text, $ignorePermissions, $dontNotify ) ==> $oopsUrl
- setTopicEditLock( $web, $topic, $lock ) ==> $oopsUrl
- checkTopicEditLock( $web, $topic ) ==> ( $oopsUrl, $loginName, $unlockTime )
- Miscellaneous
- Feedback
readTopicText( $web, $topic, $rev, $ignorePermissions ) ==> $text
| Description: |
Read topic text, including meta data |
Parameter: $web |
Web name, e.g. "Main", or empty |
Parameter: $topic |
Topic name, e.g. "MyTopic", or "Main.MyTopic" |
Parameter: $rev |
Topic revision to read, optional. Specify the minor part of the revision, e.g. "5", not "1.5"; the top revision is returned if omitted or empty. |
Parameter: $ignorePermissions |
Set to "1" if checkAccessPermission() is already performed and OK; an oops URL is returned if user has no permission |
Return: $text |
Topic text with embedded meta data; an oops URL for calling redirectCgiQuery() is returned in case of an error |
saveTopicText( $web, $topic, $text, $ignorePermissions, $dontNotify ) ==> $oopsUrl
| Description: |
Save topic text, typically obtained by readTopicText(). Topic data usually includes meta data; the file attachment meta data is replaced by the meta data from the topic file if it exists. |
Parameter: $web |
Web name, e.g. "Main", or empty |
Parameter: $topic |
Topic name, e.g. "MyTopic", or "Main.MyTopic" |
Parameter: $text |
Topic text to save, assumed to include meta data |
Parameter: $ignorePermissions |
Set to "1" if checkAccessPermission() is already performed and OK |
Parameter: $dontNotify |
Set to "1" if not to notify users of the change |
Return: $oopsUrl |
Empty string if OK; the $oopsUrl for calling redirectCgiQuery() in case of error |
- Example:
my $oopsUrl = TWiki::Func::setTopicEditLock( $web, $topic, 1 );
if( $oopsUrl ) {
TWiki::Func::redirectCgiQuery( $query, $oopsUrl ); # assuming valid query
return;
}
my $text = TWiki::Func::readTopicText( $web, $topic ); # read topic text
# check for oops URL in case of error:
if( $text =~ /^http.*?\/oops/ ) {
TWiki::Func::redirectCgiQuery( $query, $text );
return;
}
# do topic text manipulation like:
$text =~ s/old/new/g;
# do meta data manipulation like:
$text =~ s/(META\:FIELD.*?name\=\"TopicClassification\".*?value\=\")[^\"]*/$1BugResolved/;
$oopsUrl = TWiki::Func::saveTopicText( $web, $topic, $text ); # save topic text
TWiki::Func::setTopicEditLock( $web, $topic, 0 ); # unlock topic
if( $oopsUrl ) {
TWiki::Func::redirectCgiQuery( $query, $oopsUrl );
return;
}
setTopicEditLock( $web, $topic, $lock ) ==> $oopsUrl
| Description: |
Lock topic for editing, or unlock when done |
Parameter: $web |
Web name, e.g. "Main", or empty |
Parameter: $topic |
Topic name, e.g. "MyTopic", or "Main.MyTopic" |
Parameter: $lock |
Set to 1 to lock topic, 0 to unlock |
Return: $oopsUrl |
Empty string if OK; the $oopsUrl for calling redirectCgiQuery() in case lock is already taken when trying to lock topic |
checkTopicEditLock( $web, $topic ) ==> ( $oopsUrl, $loginName, $unlockTime )
| Description: |
Check if topic has an edit lock by a user |
Parameter: $web |
Web name, e.g. "Main", or empty |
Parameter: $topic |
Topic name, e.g. "MyTopic", or "Main.MyTopic" |
Return: ( $oopsUrl, $loginName, $unlockTime ) |
The $oopsUrl for calling redirectCgiQuery(), user's $loginName, and estimated $unlockTime in minutes. The $oopsUrl and $loginName is empty if topic has no edit lock. |
Miscellaneous
I suggest to depreciate the existing
readTopic( $web, $topic ) function since it depends on the undocumented meta handling class.
--
PeterThoeny - 29 Dec 2002
Implemented, in
TWikiAlphaRelease,
TWikiBetaRelease and at TWiki.org.
Feedback
--
PeterThoeny - 30 Dec 2002
How would user read and update meta data? What would happen after saveTopicText (above)? Would some meta data be updated?
--
JohnTalintyre - 31 Dec 2002
Useful additions, this will help make
XpTrackerPlugin cleaner. There are still two deprecated methods I use in this plugin though, TWiki::Store::saveFile and TWiki::Store::readFile. These are used for a disk cache to speed up the plugin, so the files being created are not regular topics under revision control.
NavbarPlugin uses these methods too, for the same purpose.
And, while I'm here, is there any information on the recommended way for a plugin to work with multiple versions of TWiki? I could update
XpTrackerPlugin to use the newly added calls above, but would still need backwards compatability for quite a while for users still on the current TWiki release.
--
MartinWatt - 31 Dec 2002
Topic text and meta data are now serialized, e.g. is like the file format. That means, regular expressions can be applied to read and write meta data. I updated above docs with an example. It is even possible to add new meta data at the end of the text, it is preserved by subsequent read/save actions.
No changes are done to topic text and meta data (besides
META:TOPICINFO) if you just read and save a topic.
As a next step we could introduce meta data handling functions that work on the serialized content, in a similar way to the existing TWiki::Meta class. That topic is
SimplifyInternalMetaDataHandling.
Martin: For low level file I/O use
TWiki::Func::saveFile() and
TWiki::Func::readFile(). Both have been already in the 01 Dec 2001 TWiki release, so you do not have compatibility issues. You can add conditional code if needed, based on the
$TWiki::Plugins::VERSION variable. Was
'1.000' for 01 Dec 2001 release, is
'1.010' for 01 Jan 2003 release.
--
PeterThoeny - 31 Dec 2002
I would like to reverse this decision. I think that meta-data, as conceptually out-of-band data, needs to be separated from topic content on as many levels as possible. Better to document a meta-handling class than to conflate metadata and real data this way. Storing them together in the topic file is bad enough IMO and we're only making it worse by reinforcing the linkage at the level of the published API.
--
WalterMundt - 28 Mar 2004
i don't think there's anything wrong with storing the "metadata" in the same file; however, as
WalterMundt points out, they should be separate at the api level.
--
WillNorris - 28 Mar 2004
Yes, please, Walter. I'm down on both knees
begging you to do this! The arguments about meta-data in the same file with run and run, and are not relevant here. Plugins should not need to be aware of where metadata is stored. In fact, I would prefer that the
low level IO functions readTopicText and saveTopicText were removed or at least strongly discouraged in the API documentation. The reason? These low level methods make changes to the Store module much harder, and plugins much less flexible. On metadata; the old readTopic is fine, and if you want to keep it simple, no API to the meta is needed other than acknowledgement that it is a hash reference and documentation of the organisation of the keys. I can't think of any methods on meta that we absolutely require an API for. If you are feeling generous, some way of adding and removing keys might be useful. We definitely need a symmetrical saveTopic(meta,text) though.
--
CrawfordCurrie - 28 Mar 2004
I also agree. I like the fact that meta data is in the same file internally, but this should definatly not mean that it is lumped programatically together. Other's may need it to be seperated. I also don't see why plugins should be forced to try not to corrupt meta-data if they don't want to manipulate it anyway.
--
SvenDowideit - 28 Mar 2004
A small suggestion. This, and other API changes, will obviously not be usable by plugin authors who want their plugins to work with versions of TWiki prior to Cairo. So why not follow the idea proposed in
SharedCodeProposal and provide a shared-code buffer that spoof these methods for earlier TWiki releases? What I mean is, in a file in shared code called "PreCairoCompatabilityModule.pm" you could write:
sub TWiki::Func::saveTopic {
my ($meta,$text) = @_;
# interleave the meta and text and call TWiki::Func::saveTopicText
}
Then, any plugin author wanting to use the method could document in the installation of their plugin that it requires the download and installation of the
PreCairoCompatabilityModule if it is to be used with Beijing. Eventually the
MakeStrategy could also take this dependency into account when the plugin is installed.
Your changes to the RE interface can be handled the same way, simply by mapping the RE references to the appropriate TWiki:: global variable in the compatability module. This way you can advance the Func module as rapidly as you like, and as long as a compatability module is available it won't affect plugin authors.
--
CrawfordCurrie - 28 Mar 2004
Shudder, exposing meta data to Plugins
A safer and more portable approach is to provide mata data handling functions so that Plugins can manipulate meta data safely and in a portable way. In fact, also for TWiki internal use we should
SimplifyInternalMetaDataHandling!
This is a
FeatureDone topic, better to follow up in
PluginApiForHandlingMetaData.
--
PeterThoeny - 28 Mar 2004
Peter, I'll comment on exposure of meta-data in
PluginApiForHandlingMetaData. I think you were reading something into the proposal that wasn't there. But you didn't comment on my proposal for spoofing methods for earlier releases in a compatability module. Is that because you don't like the idea?
--
CrawfordCurrie - 28 Mar 2004
m