= Wiki Rename = The base feature has now landed on trunk for [milestone:0.12], see r9362 and r9363. Among the various possibilities for performing a rename, this implementation aims at simplicity. The page name is modified "in-place", i.e. the object identity is mutated and as such, the whole history is kept and becomes associated to the renamed wiki page. You need to be a `WIKI_ADMIN` in order to be able to rename a page (or at the very least, have the new `WIKI_RENAME` permission). == How it works == '''Example:''' renaming !WikiStart to !ProjectHome - before the rename: ||= pagename =||= text =||= comment=|| || !WikiStart || version1 || comment1 || || !WikiStart || version2 || comment2 || || !WikiStart || version3 || comment3 || - after the rename: ||= pagename =||= text =||= comment=|| || !ProjectHome || version1 || comment1 || || !ProjectHome || version2 || comment2 || || !ProjectHome || version3 || comment3 || the !WikiStart page will be (optionally) recreated with a redirection to the new page: ||= pagename =||= text =||= comment=|| || !WikiStart || See !ProjectHome || !WikiStart → !ProjectHome || Note that this is very similar to how [http://meta.wikimedia.org/wiki/Help:Moving_a_page moving a page in MediaWiki] works. == Overview of the changes == - added new `WikiPage.rename` and `Attachment.reparent_all` methods - added new `wiki_rename.html` template and the corresponding handler methods, `WikiModule._render_confirm_rename` and `WikiModule._do_rename` methods == Discussion == Feel free to provide feedback. * Would be nice to have a [http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.2 HTTP 301 redirect] from the old wiki page to the new one, to keep searchengine rankings etc. - (cboos) see ticket:3718#comment:3 (rather than #976) * Another TODO: optionally rename sub-pages as well, and more generally, have the possibility to do batch renames - (cboos) yes, see comment:8:ticket:4412 * Another TODO: would be nice to have an entry in the history of the page including the name, date and optional comment of the rename event. - Looking at existing code from [th:wiki:WikiRenamePlugin WikiRenamePlugin] could help, see: http://trac-hacks.org/browser/wikirenameplugin/0.11/wikirename/util.py#L55 * Another TODO: also rename all links to renamed pages on all other pages and create for this a new version for all affected pages - Cabbiepete: This sounds like an excellent idea currently re-organising the wiki structure is quite painful. - Before re-inventing the wheel again a hint to look at [th:wiki:WikiRenamePlugin WikiRenamePlugin], this is done here: http://trac-hacks.org/browser/wikirenameplugin/0.11/wikirename/util.py#L76 * cboos: well, that's rather an example of how to '''not''' implement this. To do it correctly, the wiki parser has to provide some direct support for this (#4431, with an eye on keeping enough information in the syntax nodes for being able to modify the original text in place, or alternatively have a ''wiki source'' formatter that can be specialized) * mitar: but it works, quite well ;-) * More robust error handling: what happens if a reparent fails mid-way (e.g. permission issue for one attachment)? The whole transaction is rolled back, but some attachment ''files'' could have been moved already. Should we try to move them back? Should we warn the user about what already got moved? After fixing the permission issue, a new rename should work, which might not be the case if the attachment table and the files are not in sync. - We have the same issue when deleting pages. Actually, any time a filesystem change must be atomic with a DB change. I thought about adding some kind of "post-commit task list" where e.g. the attachment reparenting method registers a callable with the transaction to be executed after a successful commit. So the transaction would complete, and only then would all the items in the list be called to execute FS operations. * Yes, what about the following approach in 3 steps: 1. before the DB transaction: copy all the attachments to the new location in the FS 2. only if 1. succeeds, perform the DB transaction 3. if 1. succeeded, perform a clean-up step: - ''post-commit'' if 2. has also succeeded, we can try to remove the files at their old location. - ''post-rollback'': if 2. has failed, we can try to undo step 1. by removing the copied files. This depends on the actual reason of the failure, don't do that if the failure is due to a concurrent rename attempt which succeeded ;-) If either of these FS clean-up task failed, bad luck but at least the DB and FS are consistent, the FS can eventually be cleaned manually afterwards. * Making the whole rename process more modular by introducing a !WikiPageRename !ExtensionPoint would be critical for some plugins. This was suggested (by coderanger) for [th:wiki:WikiRenamePlugin WikiRenamePlugin] before and discussed as key element for any plugin support (see [th:ticket:457]th-ticket 457). Since [th:wiki:TagsPlugin TagsPlugin], [th:wiki:FlexibleWikiPlugin FlexibleWikiPlugin] and certainly others are both, popular and depending on their own db table with references to wiki pages by name, helping them to keep their db tables in sync should be mandatory. - there is support for this already, see: - `WikiChangeListener.wiki_page_renamed(page, old_page_name)` - `IAttachmentChangeListener.attachment_reparented(attachment, old_parent_realm, old_parent_id)` (to be documented) - (rblank) Considering the discussion above about transactions, maybe we should also move the calls to the listeners into the transaction, instead of after the commit, so that DB updates by plugins are also done in the context of the transaction? - I agree, and even more: if any plugin not only uses wiki page names as reference in db table(s) but in any filesystem-related form there would be the need to allow the same two-staged change process with signal (commit|roll-back); however, I don't know of such a plugin by now, so maybe this is irrelevant and we really just need to integrate changes for db tables via the `WikiChangeListener`. - I doubt the current `WikiChangeListener` will allow for sending signal (commit|roll-back) after the first call, so you think of modifying this extension point? * This is great, but how does the user actually do it? E.g., is it by a command in trac-admin, or is there a "Rename Page" link at the bottom of the page, or both? - both are possible: for TracAdmin it's [[TracAdminHelp(wiki rename)]] and for the interface, it depends on having the WIKI_RENAME permission (and the WIKI_CREATE for the target page). That's mentioned in TracPermissions, but maybe TracWiki could be expanded a bit. ---- See also: #1106, TracDev/Proposals/AdvancedWikiOperations