mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2024-11-23 10:07:19 +00:00
Adopt new URL scheme for permalinks
Instead of using `%00` as a separator we do the more conventional `#!<target-title>:<story filter>`.
This commit is contained in:
parent
327b53a641
commit
a5e9ef9b5f
@ -25,6 +25,8 @@ var DEFAULT_HISTORY_TITLE = "$:/HistoryList";
|
||||
// Default tiddlers
|
||||
var DEFAULT_TIDDLERS_TITLE = "$:/DefaultTiddlers";
|
||||
|
||||
// Favicon tiddler
|
||||
var FAVICON_TITLE = "$:/favicon.ico";
|
||||
|
||||
var widget = require("$:/core/modules/widgets/widget.js");
|
||||
|
||||
@ -75,34 +77,37 @@ exports.startup = function() {
|
||||
// Clear outstanding tiddler store change events to avoid an unnecessary refresh cycle at startup
|
||||
$tw.wiki.clearTiddlerEventQueue();
|
||||
// Decode the hash portion of our URL
|
||||
var parts = [];
|
||||
var target,
|
||||
storyFilter;
|
||||
if($tw.locationHash.charAt(1) === "!") {
|
||||
parts = decodeURIComponent($tw.locationHash.substr(2)).split("\u0000")
|
||||
var hash = $tw.locationHash.substr(2),
|
||||
split = hash.indexOf(":");
|
||||
if(split === -1) {
|
||||
target = decodeURIComponent(hash.trim());
|
||||
} else {
|
||||
target = decodeURIComponent(hash.substr(0,split - 1).trim());
|
||||
storyFilter = decodeURIComponent(hash.substr(split + 1).trim());
|
||||
}
|
||||
}
|
||||
if(parts[0]) {
|
||||
// Set the history
|
||||
var historyList = [{title: parts[0]}];
|
||||
$tw.wiki.setTiddlerData(DEFAULT_HISTORY_TITLE, historyList, {"current-tiddler": parts[0]});
|
||||
// Set the story
|
||||
var story = [];
|
||||
for(var t=1; t<parts.length; t++) {
|
||||
if(parts[t]) {
|
||||
story.push(parts[t]);
|
||||
}
|
||||
// If a target tiddler was specified add it to the history stack
|
||||
if(target && target !== "") {
|
||||
// The target tiddler doesn't need double square brackets, but we'll silently remove them if they're present
|
||||
if(target.indexOf("[[") === 0 && target.substr(-2) === "]]") {
|
||||
target = target.substr(2,target.length - 4);
|
||||
}
|
||||
// If the story is empty use the default tiddlers
|
||||
if(story.length === 0) {
|
||||
story = getDefaultTiddlers();
|
||||
}
|
||||
// If the target tiddler isn't included then splice it in at the top
|
||||
if(story.indexOf(parts[0]) === -1) {
|
||||
story.unshift(parts[0]);
|
||||
}
|
||||
$tw.wiki.addTiddler({title: DEFAULT_STORY_TITLE, text: "", list: story},$tw.wiki.getModificationFields());
|
||||
} else {
|
||||
// Display the default tiddlers if the hash portion was empty
|
||||
displayDefaultTiddlers();
|
||||
$tw.wiki.addToHistory(target);
|
||||
}
|
||||
// Use the story filter specified in the hash, or the default tiddlers
|
||||
if(!storyFilter || storyFilter === "") {
|
||||
storyFilter = $tw.wiki.getTiddlerText(DEFAULT_TIDDLERS_TITLE);
|
||||
}
|
||||
var storyList = $tw.wiki.filterTiddlers(storyFilter);
|
||||
// If the target tiddler isn't included then splice it in at the top
|
||||
if(target && storyList.indexOf(target) === -1) {
|
||||
storyList.unshift(target);
|
||||
}
|
||||
// Save the story list
|
||||
$tw.wiki.addTiddler({title: DEFAULT_STORY_TITLE, text: "", list: storyList},$tw.wiki.getModificationFields());
|
||||
// Set up the syncer object
|
||||
$tw.syncer = new $tw.Syncer({wiki: $tw.wiki});
|
||||
// Host-specific startup
|
||||
@ -205,20 +210,25 @@ exports.startup = function() {
|
||||
}
|
||||
});
|
||||
// Set up the favicon
|
||||
var faviconTitle = "$:/favicon.ico",
|
||||
faviconLink = document.getElementById("faviconLink"),
|
||||
var faviconLink = document.getElementById("faviconLink"),
|
||||
setFavicon = function() {
|
||||
var tiddler = $tw.wiki.getTiddler(faviconTitle);
|
||||
var tiddler = $tw.wiki.getTiddler(FAVICON_TITLE);
|
||||
if(tiddler) {
|
||||
faviconLink.setAttribute("href","data:" + tiddler.fields.type + ";base64," + tiddler.fields.text);
|
||||
}
|
||||
};
|
||||
setFavicon();
|
||||
$tw.wiki.addEventListener("change",function(changes) {
|
||||
if($tw.utils.hop(changes,faviconTitle)) {
|
||||
if($tw.utils.hop(changes,FAVICON_TITLE)) {
|
||||
setFavicon();
|
||||
}
|
||||
});
|
||||
// Set up location hash update
|
||||
$tw.wiki.addEventListener("change",function(changes) {
|
||||
if($tw.utils.hop(changes,DEFAULT_STORY_TITLE) || $tw.utils.hop(changes,DEFAULT_HISTORY_TITLE)) {
|
||||
updateLocationHash();
|
||||
}
|
||||
});
|
||||
// Set up the styles
|
||||
var styleTemplateTitle = "$:/core/ui/PageStylesheet",
|
||||
styleParser = $tw.wiki.parseTiddler(styleTemplateTitle);
|
||||
@ -266,24 +276,11 @@ exports.startup = function() {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
Helper to display the default tiddlers
|
||||
*/
|
||||
function displayDefaultTiddlers() {
|
||||
// Get the default tiddlers
|
||||
var defaultTiddlersTitle = "$:/DefaultTiddlers",
|
||||
defaultTiddlersTiddler = $tw.wiki.getTiddler(defaultTiddlersTitle),
|
||||
defaultTiddlers = [];
|
||||
if(defaultTiddlersTiddler) {
|
||||
defaultTiddlers = $tw.wiki.filterTiddlers(defaultTiddlersTiddler.fields.text);
|
||||
}
|
||||
// Initialise the story
|
||||
var story = [];
|
||||
for(var t=0; t<defaultTiddlers.length; t++) {
|
||||
story[t] = defaultTiddlers[t];
|
||||
}
|
||||
$tw.wiki.addTiddler({title: DEFAULT_STORY_TITLE, text: "", list: story},$tw.wiki.getModificationFields());
|
||||
$tw.wiki.addTiddler({title: DEFAULT_STORY_TITLE, text: "", list: getDefaultTiddlers()},$tw.wiki.getModificationFields());
|
||||
}
|
||||
|
||||
function getDefaultTiddlers() {
|
||||
@ -295,6 +292,16 @@ function getDefaultTiddlers() {
|
||||
return defaultTiddlers;
|
||||
}
|
||||
|
||||
function updateLocationHash() {
|
||||
var storyList = $tw.wiki.getTiddlerList(DEFAULT_STORY_TITLE),
|
||||
historyList = $tw.wiki.getTiddlerData(DEFAULT_HISTORY_TITLE,[]);
|
||||
var targetTiddler = "";
|
||||
if(historyList.length > 0) {
|
||||
targetTiddler = historyList[historyList.length-1].title;
|
||||
}
|
||||
location.hash = "#!" + encodeURIComponent(targetTiddler) + ":" + encodeURIComponent($tw.utils.stringifyList(storyList));
|
||||
}
|
||||
|
||||
/*
|
||||
Main render function for PageMacros, which includes the PageTemplate
|
||||
*/
|
||||
|
@ -133,15 +133,7 @@ title: a title string or an array of title strings
|
||||
fromPageRect: page coordinates of the origin of the navigation
|
||||
*/
|
||||
NavigatorWidget.prototype.addToHistory = function(title,fromPageRect) {
|
||||
var titles = $tw.utils.isArray(title) ? title : [title];
|
||||
// Add a new record to the top of the history stack
|
||||
if(this.historyTitle) {
|
||||
var historyList = this.wiki.getTiddlerData(this.historyTitle,[]);
|
||||
$tw.utils.each(titles,function(title) {
|
||||
historyList.push({title: title, fromPageRect: fromPageRect});
|
||||
});
|
||||
this.wiki.setTiddlerData(this.historyTitle,historyList,{"current-tiddler": titles[titles.length-1]});
|
||||
}
|
||||
this.wiki.addToHistory(title,fromPageRect,this.historyTitle);
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -1070,7 +1070,7 @@ exports.readFile = function(file,callback) {
|
||||
/*
|
||||
Check whether the specified draft tiddler has been modified
|
||||
*/
|
||||
$tw.Wiki.prototype.isDraftModified = function(title) {
|
||||
exports.isDraftModified = function(title) {
|
||||
var tiddler = this.getTiddler(title);
|
||||
if(!tiddler.isDraft()) {
|
||||
return false;
|
||||
@ -1091,4 +1091,21 @@ $tw.Wiki.prototype.isDraftModified = function(title) {
|
||||
});
|
||||
};
|
||||
|
||||
/*
|
||||
Add a new record to the top of the history stack
|
||||
title: a title string or an array of title strings
|
||||
fromPageRect: page coordinates of the origin of the navigation
|
||||
historyTitle: title of history tiddler (defaults to $:/HistoryList)
|
||||
*/
|
||||
exports.addToHistory = function(title,fromPageRect,historyTitle) {
|
||||
historyTitle = historyTitle || "$:/HistoryList";
|
||||
var titles = $tw.utils.isArray(title) ? title : [title];
|
||||
// Add a new record to the top of the history stack
|
||||
var historyList = this.getTiddlerData(historyTitle,[]);
|
||||
$tw.utils.each(titles,function(title) {
|
||||
historyList.push({title: title, fromPageRect: fromPageRect});
|
||||
});
|
||||
this.setTiddlerData(historyTitle,historyList,{"current-tiddler": titles[titles.length-1]});
|
||||
};
|
||||
|
||||
})();
|
||||
|
@ -6,6 +6,8 @@ type: text/vnd.tiddlywiki
|
||||
|
||||
Permalinks allow direct links to individual tiddlers within a TiddlyWiki.
|
||||
|
||||
! Simple Permalinks
|
||||
|
||||
The simplest form of permalink is a single target tiddler title appended to the base URL with "#!":
|
||||
|
||||
http://tiddlywiki.com/#!HelloThere
|
||||
@ -14,13 +16,26 @@ The tiddler title can contain spaces if required:
|
||||
|
||||
[[http://tiddlywiki.com/#!Using TiddlyWiki on Node.js]]
|
||||
|
||||
The permalink can also specify the story list of tiddlers that should be opened alongside the target tiddler. The tiddler titles are separated by `%00`:
|
||||
Note that double square brackets are not required around the target tiddler title; however, if present they are silently removed.
|
||||
|
||||
http://tiddlywiki.com/#!Tiddlers%00Tags%00TiddlerFields%00Tiddlers
|
||||
! Story Permalinks
|
||||
|
||||
In this form, the first tiddler title is taken to be the target tiddler, and the remaining titles give the sequence of tiddlers in the story list.
|
||||
The permalink can also specify the story list of tiddlers that should be opened alongside the target tiddler as a [[TiddlerFilter|TiddlerFilters]]:
|
||||
|
||||
[[http://tiddlywiki.com/#!TiddlerFields:Tiddlers TiddlerTags TiddlerFields ContentType]]
|
||||
|
||||
If the target tiddler isn't present in the story list then it is automatically inserted at the top. This means that the following two examples both target the tiddler `Tiddlers` within the story sequence `Tiddlers`, `Tags`, `TiddlerFields`:
|
||||
|
||||
http://tiddlywiki.com/#!Tiddlers%00Tags%00TiddlerFields
|
||||
http://tiddlywiki.com/#!Tiddlers%00Tiddlers%00Tags%00TiddlerFields
|
||||
[[http://tiddlywiki.com/#!Tiddlers:Tags TiddlerFields]]
|
||||
|
||||
[[http://tiddlywiki.com/#!Tiddlers:Tiddlers Tags TiddlerFields]]
|
||||
|
||||
It is also possible to specify a story filter without specifying a target tiddler for navigation:
|
||||
|
||||
<a href="http://tiddlywiki.com/#!:[tags[task]]">~http://tiddlywiki.com/#!:[tags[task]]</a>
|
||||
|
||||
! About URL encoding
|
||||
|
||||
There are technical restrictions on the legal characters in an URL fragment. To allow all tiddler titles to be addressed, illegal characters are subject to a process called "URL encoding" whereby problematic characters are replaced by their numeric code. For example, the space character is replaced with `%20`.
|
||||
|
||||
Both the target tiddler title and the story filter should be URL encoded (but not the separating colon). TiddlyWiki generates properly encoded URLs which can look quite ugly. However, in practice browsers will usually perfectly happily process arbitrary characters in URL fragments. Thus when creating permalinks manually you can choose to ignore URL encoding.
|
||||
|
Loading…
Reference in New Issue
Block a user