Add support for JSON-formatted tiddler store, and make it the default (#5708)

* Add support for JSON-formatted tiddler store, and make it the default

The change to `getTiddlersAsJson()` is to allow experimentation

* Move JSON tiddlers into their own store area, and fix support for encrypted tiddlers

Also add a dummy old-style store area for backwards compatibility

The current arrangement is that JSON tiddlers will always override old-style tiddlers.

* Use the deserialiser mechanism to decode the content

* Refactor $:/core/modules/deserializers.js before we start extending it

Cleaning up the helper function names and ordering

* Drop support for the "systemArea" div

It was only used in really old v5.0.x

* Update deserializer to support JSON store format and add some tests

* Life UI restrictions on characters in fieldnames

* Add another test case

* Correct mis-merge

* Remove toLowerCase() methods applied to fieldnames

* Insert line breaks in output of getTiddlersAsJson (#5786)

Rather than have the entire store on one line, insert a line break
after each tiddler.

* Refactor #5786 for backwards compatibility

* Only read .tiddlywiki-tiddler-store blocks from script tags

Prompted by @simonbaird's comment here: https://github.com/Jermolene/TiddlyWiki5/pull/5708#discussion_r648833367

* Clean up escaping of unsafe script characters

It seems that escaping `<` is sufficient

* Add docs from @saqimtiaz

Thanks @saqimtiaz

* Docs tweaks

* Remove excess whitespace

Thanks @simonbaird

* Fix templates for lazy loading

* Remove obsolete item from release note

* Clean up whitespace

* Docs for the jsontiddler widget

* Fix whitespace

Fixes #5840

* Comments

* Fix newlines in JSON store area

* Remove obsolete docs change

Co-authored-by: Simon Baird <simon.baird@gmail.com>
This commit is contained in:
Jeremy Ruston 2021-07-14 09:15:30 +01:00 committed by GitHub
parent 155525708b
commit d455072f13
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
49 changed files with 506 additions and 161 deletions

View File

@ -1724,13 +1724,20 @@ $tw.modules.define("$:/boot/tiddlerdeserializer/dom","tiddlerdeserializer",{
},
t,result = [];
if(node) {
for(t = 0; t < node.childNodes.length; t++) {
var type = (node.getAttribute && node.getAttribute("type")) || null;
if(type) {
// A new-style container with an explicit deserialization type
result = $tw.wiki.deserializeTiddlers(type,node.textContent);
} else {
// An old-style container of classic DIV-based tiddlers
for(t = 0; t < node.childNodes.length; t++) {
var childNode = node.childNodes[t],
tiddlers = extractTextTiddlers(childNode);
tiddlers = tiddlers || extractModuleTiddlers(childNode);
if(tiddlers) {
result.push.apply(result,tiddlers);
}
}
}
}
return result;
@ -1739,17 +1746,23 @@ $tw.modules.define("$:/boot/tiddlerdeserializer/dom","tiddlerdeserializer",{
$tw.loadTiddlersBrowser = function() {
// In the browser, we load tiddlers from certain elements
var containerIds = [
"libraryModules",
"modules",
"bootKernelPrefix",
"bootKernel",
"styleArea",
"storeArea",
"systemArea"
var containerSelectors = [
// IDs for old-style v5.1.x tiddler stores
"#libraryModules",
"#modules",
"#bootKernelPrefix",
"#bootKernel",
"#styleArea",
"#storeArea",
"#systemArea",
// Classes for new-style v5.2.x JSON tiddler stores
"script.tiddlywiki-tiddler-store"
];
for(var t=0; t<containerIds.length; t++) {
$tw.wiki.addTiddlers($tw.wiki.deserializeTiddlers("(DOM)",document.getElementById(containerIds[t])));
for(var t=0; t<containerSelectors.length; t++) {
var nodes = document.querySelectorAll(containerSelectors[t]);
for(var n=0; n<nodes.length; n++) {
$tw.wiki.addTiddlers($tw.wiki.deserializeTiddlers("(DOM)",nodes[n]));
}
}
};

View File

@ -41,7 +41,6 @@ Error/WhileSaving: Error while saving
Error/XMLHttpRequest: XMLHttpRequest error code
InternalJavaScriptError/Title: Internal JavaScript Error
InternalJavaScriptError/Hint: Well, this is embarrassing. It is recommended that you restart TiddlyWiki by refreshing your browser
InvalidFieldName: Illegal characters in field name "<$text text=<<fieldName>>/>". Fields can only contain lowercase letters, digits and the characters underscore (`_`), hyphen (`-`) and period (`.`)
LayoutSwitcher/Description: Open the layout switcher
LazyLoadingWarning: <p>Trying to load external content from ''<$text text={{!!_canonical_uri}}/>''</p><p>If this message doesn't disappear, either the tiddler content type doesn't match the type of the external content, or you may be using a browser that doesn't support external content for wikis loaded as standalone files. See https://tiddlywiki.com/#ExternalText</p>
LoginToTiddlySpace: Login to TiddlySpace

View File

@ -12,63 +12,8 @@ Functions to deserialise tiddlers from a block of text
/*global $tw: false */
"use strict";
/*
Utility function to parse an old-style tiddler DIV in a *.tid file. It looks like this:
<div title="Title" creator="JoeBloggs" modifier="JoeBloggs" created="201102111106" modified="201102111310" tags="myTag [[my long tag]]">
<pre>The text of the tiddler (without the expected HTML encoding).
</pre>
</div>
Note that the field attributes are HTML encoded, but that the body of the <PRE> tag is not encoded.
When these tiddler DIVs are encountered within a TiddlyWiki HTML file then the body is encoded in the usual way.
*/
var parseTiddlerDiv = function(text /* [,fields] */) {
// Slot together the default results
var result = {};
if(arguments.length > 1) {
for(var f=1; f<arguments.length; f++) {
var fields = arguments[f];
for(var t in fields) {
result[t] = fields[t];
}
}
}
// Parse the DIV body
var startRegExp = /^\s*<div\s+([^>]*)>(\s*<pre>)?/gi,
endRegExp,
match = startRegExp.exec(text);
if(match) {
// Old-style DIVs don't have the <pre> tag
if(match[2]) {
endRegExp = /<\/pre>\s*<\/div>\s*$/gi;
} else {
endRegExp = /<\/div>\s*$/gi;
}
var endMatch = endRegExp.exec(text);
if(endMatch) {
// Extract the text
result.text = text.substring(match.index + match[0].length,endMatch.index);
// Process the attributes
var attrRegExp = /\s*([^=\s]+)\s*=\s*(?:"([^"]*)"|'([^']*)')/gi,
attrMatch;
do {
attrMatch = attrRegExp.exec(match[1]);
if(attrMatch) {
var name = attrMatch[1];
var value = attrMatch[2] !== undefined ? attrMatch[2] : attrMatch[3];
result[name] = value;
}
} while(attrMatch);
return result;
}
}
return undefined;
};
exports["application/x-tiddler-html-div"] = function(text,fields) {
return [parseTiddlerDiv(text,fields)];
return [deserializeTiddlerDiv(text,fields)];
};
exports["application/json"] = function(text,fields) {
@ -105,30 +50,34 @@ Parse an HTML file into tiddlers. There are three possibilities:
# An ordinary HTML file
*/
exports["text/html"] = function(text,fields) {
// Check if we've got a store area
var results = [];
// Check if we've got an old-style store area
var storeAreaMarkerRegExp = /<div id=["']?storeArea['"]?( style=["']?display:none;["']?)?>/gi,
match = storeAreaMarkerRegExp.exec(text);
if(match) {
// If so, it's either a classic TiddlyWiki file or an unencrypted TW5 file
// First read the normal tiddlers
var results = deserializeTiddlyWikiFile(text,storeAreaMarkerRegExp.lastIndex,!!match[1],fields);
// Then any system tiddlers
var systemAreaMarkerRegExp = /<div id=["']?systemArea['"]?( style=["']?display:none;["']?)?>/gi,
sysMatch = systemAreaMarkerRegExp.exec(text);
if(sysMatch) {
results.push.apply(results,deserializeTiddlyWikiFile(text,systemAreaMarkerRegExp.lastIndex,!!sysMatch[1],fields));
}
storeAreaMatch = storeAreaMarkerRegExp.exec(text);
if(storeAreaMatch) {
// If so, we've got tiddlers in classic TiddlyWiki format or unencrypted old-style TW5 format
results.push.apply(results,deserializeStoreArea(text,storeAreaMarkerRegExp.lastIndex,!!storeAreaMatch[1],fields));
}
// Check for new-style store areas
var newStoreAreaMarkerRegExp = /<script class="tiddlywiki-tiddler-store" type="([^"]*)">/gi,
newStoreAreaMatch = newStoreAreaMarkerRegExp.exec(text),
haveHadNewStoreArea = !!newStoreAreaMatch;
while(newStoreAreaMatch) {
results.push.apply(results,deserializeNewStoreArea(text,newStoreAreaMarkerRegExp.lastIndex,newStoreAreaMatch[1],fields));
newStoreAreaMatch = newStoreAreaMarkerRegExp.exec(text);
}
// Return if we had either an old-style or a new-style store area
if(storeAreaMatch || haveHadNewStoreArea) {
return results;
}
// Otherwise, check whether we've got an encrypted file
var encryptedStoreArea = $tw.utils.extractEncryptedStoreArea(text);
if(encryptedStoreArea) {
// If so, attempt to decrypt it using the current password
return $tw.utils.decryptStoreArea(encryptedStoreArea);
} else {
// Check whether we've got an encrypted file
var encryptedStoreArea = $tw.utils.extractEncryptedStoreArea(text);
if(encryptedStoreArea) {
// If so, attempt to decrypt it using the current password
return $tw.utils.decryptStoreArea(encryptedStoreArea);
} else {
// It's not a TiddlyWiki so we'll return the entire HTML file as a tiddler
return deserializeHtmlFile(text,fields);
}
// It's not a TiddlyWiki so we'll return the entire HTML file as a tiddler
return deserializeHtmlFile(text,fields);
}
};
@ -142,7 +91,19 @@ function deserializeHtmlFile(text,fields) {
return [result];
}
function deserializeTiddlyWikiFile(text,storeAreaEnd,isTiddlyWiki5,fields) {
function deserializeNewStoreArea(text,storeAreaEnd,type,fields) {
var endOfScriptRegExp = /<\/script>/gi;
endOfScriptRegExp.lastIndex = storeAreaEnd;
var match = endOfScriptRegExp.exec(text);
if(match) {
var scriptContent = text.substring(storeAreaEnd,match.index);
return $tw.wiki.deserializeTiddlers(type,scriptContent);
} else {
return [];
}
}
function deserializeStoreArea(text,storeAreaEnd,isTiddlyWiki5,fields) {
var results = [],
endOfDivRegExp = /(<\/div>\s*)/gi,
startPos = storeAreaEnd,
@ -151,7 +112,7 @@ function deserializeTiddlyWikiFile(text,storeAreaEnd,isTiddlyWiki5,fields) {
var match = endOfDivRegExp.exec(text);
while(match) {
var endPos = endOfDivRegExp.lastIndex,
tiddlerFields = parseTiddlerDiv(text.substring(startPos,endPos),fields,{type: defaultType});
tiddlerFields = deserializeTiddlerDiv(text.substring(startPos,endPos),fields,{type: defaultType});
if(!tiddlerFields) {
break;
}
@ -169,4 +130,59 @@ function deserializeTiddlyWikiFile(text,storeAreaEnd,isTiddlyWiki5,fields) {
return results;
}
/*
Utility function to parse an old-style tiddler DIV in a *.tid file. It looks like this:
<div title="Title" creator="JoeBloggs" modifier="JoeBloggs" created="201102111106" modified="201102111310" tags="myTag [[my long tag]]">
<pre>The text of the tiddler (without the expected HTML encoding).
</pre>
</div>
Note that the field attributes are HTML encoded, but that the body of the <PRE> tag is not encoded.
When these tiddler DIVs are encountered within a TiddlyWiki HTML file then the body is encoded in the usual way.
*/
var deserializeTiddlerDiv = function(text /* [,fields] */) {
// Slot together the default results
var result = {};
if(arguments.length > 1) {
for(var f=1; f<arguments.length; f++) {
var fields = arguments[f];
for(var t in fields) {
result[t] = fields[t];
}
}
}
// Parse the DIV body
var startRegExp = /^\s*<div\s+([^>]*)>(\s*<pre>)?/gi,
endRegExp,
match = startRegExp.exec(text);
if(match) {
// Old-style DIVs don't have the <pre> tag
if(match[2]) {
endRegExp = /<\/pre>\s*<\/div>\s*$/gi;
} else {
endRegExp = /<\/div>\s*$/gi;
}
var endMatch = endRegExp.exec(text);
if(endMatch) {
// Extract the text
result.text = text.substring(match.index + match[0].length,endMatch.index);
// Process the attributes
var attrRegExp = /\s*([^=\s]+)\s*=\s*(?:"([^"]*)"|'([^']*)')/gi,
attrMatch;
do {
attrMatch = attrRegExp.exec(match[1]);
if(attrMatch) {
var name = attrMatch[1];
var value = attrMatch[2] !== undefined ? attrMatch[2] : attrMatch[3];
result[name] = value;
}
} while(attrMatch);
return result;
}
}
return undefined;
};
})();

View File

@ -17,7 +17,7 @@ Export our filter function
*/
exports.contains = function(source,operator,options) {
var results = [],
fieldname = (operator.suffix || "list").toLowerCase();
fieldname = operator.suffix || "list";
if(operator.prefix === "!") {
source(function(tiddler,title) {
if(tiddler) {

View File

@ -17,7 +17,7 @@ Export our filter function
*/
exports.field = function(source,operator,options) {
var results = [],indexedResults,
fieldname = (operator.suffix || operator.operator || "title").toLowerCase();
fieldname = operator.suffix || operator.operator || "title";
if(operator.prefix === "!") {
if(operator.regexp) {
source(function(tiddler,title) {

View File

@ -17,7 +17,7 @@ Export our filter function
*/
exports.regexp = function(source,operator,options) {
var results = [],
fieldname = (operator.suffix || "title").toLowerCase(),
fieldname = operator.suffix || "title",
regexpString, regexp, flags = "", match,
getFieldString = function(tiddler,title) {
if(tiddler) {

View File

@ -741,9 +741,8 @@ exports.isValidFieldName = function(name) {
if(!name || typeof name !== "string") {
return false;
}
name = name.toLowerCase().trim();
var fieldValidatorRegEx = /^[a-z0-9\-\._]+$/mg;
return fieldValidatorRegEx.test(name);
// Since v5.2.x, there are no restrictions on characters in field names
return name;
};
/*

View File

@ -73,26 +73,12 @@ FieldManglerWidget.prototype.handleRemoveFieldEvent = function(event) {
FieldManglerWidget.prototype.handleAddFieldEvent = function(event) {
var tiddler = this.wiki.getTiddler(this.mangleTitle),
addition = this.wiki.getModificationFields(),
hadInvalidFieldName = false,
addField = function(name,value) {
var trimmedName = name.toLowerCase().trim();
if(!$tw.utils.isValidFieldName(trimmedName)) {
if(!hadInvalidFieldName) {
alert($tw.language.getString(
"InvalidFieldName",
{variables:
{fieldName: trimmedName}
}
));
hadInvalidFieldName = true;
return;
}
} else {
if(!value && tiddler) {
value = tiddler.fields[trimmedName];
}
addition[trimmedName] = value || "";
var trimmedName = name.trim();
if(!value && tiddler) {
value = tiddler.fields[trimmedName];
}
addition[trimmedName] = value || "";
return;
};
addition.title = this.mangleTitle;

View File

@ -0,0 +1,84 @@
/*\
title: $:/core/modules/widgets/jsontiddler.js
type: application/javascript
module-type: widget
Render a tiddler as JSON text
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
var Widget = require("$:/core/modules/widgets/widget.js").widget;
var JSONTiddlerWidget = function(parseTreeNode,options) {
this.initialise(parseTreeNode,options);
};
/*
Inherit from the base widget class
*/
JSONTiddlerWidget.prototype = new Widget();
/*
Render this widget into the DOM
*/
JSONTiddlerWidget.prototype.render = function(parent,nextSibling) {
var self = this;
this.parentDomNode = parent;
this.computeAttributes();
this.execute();
// Collect the fields from the optional base tiddler
var fields = {};
if(this.attTiddler) {
var tiddler = this.wiki.getTiddler(this.attTiddler);
if(tiddler) {
fields = tiddler.getFieldStrings({exclude: this.attExclude.split(" ")});
}
}
// Add custom fields specified in attributes starting with $
$tw.utils.each(this.attributes,function(attribute,name) {
if(name.charAt(0) === "$") {
fields[name.slice(1)] = attribute;
}
});
// JSONify
var json = JSON.stringify(fields);
// Escape unsafe script characters
if(this.attEscapeUnsafeScriptChars) {
json = json.replace(/</g,"\\u003C");
}
// Update the DOM
var textNode = this.document.createTextNode(json);
parent.insertBefore(textNode,nextSibling);
this.domNodes.push(textNode);
};
/*
Compute the internal state of the widget
*/
JSONTiddlerWidget.prototype.execute = function() {
this.attTiddler = this.getAttribute("tiddler");
this.attExclude = this.getAttribute("exclude","");
this.attEscapeUnsafeScriptChars = this.getAttribute("escapeUnsafeScriptChars","no") === "yes";
};
/*
Selectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering
*/
JSONTiddlerWidget.prototype.refresh = function(changedTiddlers) {
var changedAttributes = this.computeAttributes();
if($tw.utils.count(changedAttributes) > 0 || (this.attTiddler && changedTiddlers[this.attTiddler])) {
this.refreshSelf();
return true;
} else {
return false;
}
};
exports.jsontiddler = JSONTiddlerWidget;
})();

View File

@ -0,0 +1,4 @@
title: $:/core/templates/html-json-skinny-tiddler
<$list filter="[<numTiddlers>compare:number:gteq[1]] ~[<counter>!match[1]]">`,`<$text text=<<newline>>/></$list>
<$jsontiddler tiddler=<<currentTiddler>> exclude="text" escapeUnsafeScriptChars="yes"/>

View File

@ -0,0 +1,3 @@
title: $:/core/templates/html-json-tiddler
<$list filter="[<counter>!match[1]]">`,`<$text text=<<newline>>/></$list><$jsontiddler tiddler=<<currentTiddler>> escapeUnsafeScriptChars="yes"/>

View File

@ -1,14 +1,37 @@
title: $:/core/templates/store.area.template.html
<$reveal type="nomatch" state="$:/isEncrypted" text="yes">
`<div id="storeArea" style="display:none;">`
<$list filter=<<saveTiddlerFilter>> template="$:/core/templates/html-div-tiddler"/>
<$list filter={{{ [<skinnySaveTiddlerFilter>] }}} template="$:/core/templates/html-div-skinny-tiddler"/>
`</div>`
</$reveal>
<$reveal type="match" state="$:/isEncrypted" text="yes">
`<!--~~ Encrypted tiddlers ~~-->`
`<pre id="encryptedStoreArea" type="text/plain" style="display:none;">`
<$encrypt filter=<<saveTiddlerFilter>>/>
`</pre>`
</$reveal>
\whitespace trim
<!-- Unencrypted -->
<$list filter="[[$:/isEncrypted]get[text]else[no]match[no]]">
<$list filter="[[storeAreaFormat]is[variable]getvariable[]else[json]match[json]]">
<!-- New-style JSON store area, with an old-style store area for compatibility with v5.1.x tooling -->
`<script class="tiddlywiki-tiddler-store" type="application/json">[`
<$vars newline={{{ [charcode[10]] }}}>
<$text text=<<newline>>/>
<$list filter=<<saveTiddlerFilter>> counter="counter" template="$:/core/templates/html-json-tiddler"/>
<$vars numTiddlers={{{ [subfilter<saveTiddlerFilter>count[]] }}}>
<$list filter={{{ [<skinnySaveTiddlerFilter>] }}} counter="counter" template="$:/core/templates/html-json-skinny-tiddler"/>
</$vars>
<$text text=<<newline>>/>
</$vars>
`]</script>`
`<div id="storeArea" style="display:none;">`
`</div>`
</$list>
<$list filter="[[storeAreaFormat]is[variable]getvariable[]else[json]match[div]]">
<!-- Old-style DIV/PRE-based store area -->
<$reveal type="nomatch" state="$:/isEncrypted" text="yes">
`<div id="storeArea" style="display:none;">`
<$list filter=<<saveTiddlerFilter>> template="$:/core/templates/html-div-tiddler"/>
<$list filter={{{ [<skinnySaveTiddlerFilter>] }}} template="$:/core/templates/html-div-skinny-tiddler"/>
`</div>`
</$reveal>
</$list>
</$list>
<!-- Encrypted -->
<$list filter="[[$:/isEncrypted]get[text]else[no]match[yes]]">
`<!--~~ Encrypted tiddlers ~~-->`
`<pre id="encryptedStoreArea" type="text/plain" style="display:none;">`
<$encrypt filter=<<saveTiddlerFilter>>/>
`</pre>`
</$list>

View File

@ -8,6 +8,7 @@ Welcome to the developer documentation for TiddlyWiki (https://tiddlywiki.com/).
* An assignment by Christian Jurke and Christian Heigele, two students working on their Master's degree in Information Technology at the Gießen University of Applied Sciences (Technische Hochschule Mittelhessen). Their work can be seen in the [[Introduction]] and the tiddlers that link from it.
* New developer documentation
** [[Data Storage in Single File TiddlyWiki]]
** [[Continuous Deployment]]
** [[GitHub Branches]]
** HookMechanism
@ -29,4 +30,4 @@ Welcome to the developer documentation for TiddlyWiki (https://tiddlywiki.com/).
** [[Scripts for building tiddlywiki.com]]
** SyncAdaptorModules
** WidgetModules
** WikiRuleModules
** WikiRuleModules

View File

@ -3,12 +3,4 @@ modified: 20140710081051087
tags: doc
title: Data-Storage
TW has two approaches to save the user data. These approaches depends on way you use TW. either you use node.js as a server for TW its saves the tiddlers as plain text in different files or you use TW as standalone in a browser it persists the data within the HTML-File in two Div-Areas depending on whether the encryption of the TiddlyWiki is activated or not. If the TiddlyWiki is not encrypted the data is stored in the Div-Area called "~StoreArea". Every created Tiddler is stored in a own Div-area with a few custom values. An example of a saved Tiddler is shown below (\prettyref{lst:data-div}).
```html
<div created="20140611153703343" modified="20140611153734589" tags="testTag" testfield="testvalue" title="TestTiddler" type="text/plain">
<pre>testText</pre>
</div>
```
The Div-Area has the same attributes like the standard tillder fields, listed in [[TiddlerFields|https://tiddlywiki.com/#TiddlerFields]], all attributes which are not in this list are parsed as a custom field. The only required attribute is the name attribute, all other attributes are optional.\\
With a activated encryption the data is stored in a special Div-Area called "encryptedStoreArea". TiddlyWiki uses the Standford [[JavaScript Crypto Libary|http://bitwiseshiftleft.github.io/sjcl/]]. The encrypted Tiddlers are saved in a JSON string within this Div-Area.
{{Data Storage}}

View File

@ -0,0 +1,97 @@
created: 20210525165258247
modified: 20210614134705320
tags: Data-Storage doc [[Data Storage]]
title: Data Storage in Single File TiddlyWiki
The single file version of ~TiddlyWiki saves the tiddlers within the HTML file.
Version 5.2.0 of ~TiddlyWiki introduced a new format for how tiddlers are saved within the HTML file.
---
!! Up to and including ~TiddlyWiki v5.1.23
Tiddlers are saved within the HTML file in one of two `<div>` tags depending on whether the TiddlyWiki is configured to encrypt its content or not.
!!! Without encryption
If the ~TiddlyWiki is not encrypted the data is stored in a `<div>` tag with an `id` attribute of "storeArea".
```html
<div id="storeArea" style="display:none;">
```
Within the store area `<div>`, each tiddler is stored in its own div.
//Tiddler DIV//
Each tiddler `<div>` has an attribute corresponding to each of the tiddler's fields, except the text field which is saved within a `pre` tag within the `<div>`. Note that all attributes and therefore field names must be lowercase letters, digits or the characters `-` (dash), `_` (underscore) and `.` (period). The only attribute that is required is `title`, all other attributes are optional. All attribute values and the text field within the `pre` tag are HTML encoded.
Example:
```html
<div id="storeArea" style="display:none;">
<div created="20140611153703343" modified="20140611153734589" tags="testTag" testfield="testvalue" title="TestTiddler" type="text/plain">
<pre>testText</pre>
</div>
</div>
```
!!! With encryption
If the ~TiddlyWiki is configured to encrypt its content, the tiddlers are stored as as an encrypted JSON string in a `<pre>` tag with the `id` attribute "encryptedStoreArea".
```html
<pre id="encryptedStoreArea" type="text/plain" style="display:none;">
```
~TiddlyWiki uses the [[Stanford JavaScript Crypto Library|http://bitwiseshiftleft.github.io/sjcl/]].
---
!! From ~TiddlyWiki v5.2.0
From v5.2.0 onwards, ~TiddlyWiki introduces a new JSON based format for the tiddler store area for unencrypted content, while retaining support for the older store area formats described above for backwards compatibility. The store area format remains unchanged for encrypted content.
!!! Without encryption
By default, all tiddlers are now stored as an array of JSON objects inside a `<script>` tag with the `class` attribute "tiddlywiki-tiddler-store" and the `type` "application/json". For better readability, every tiddler object begins on a new line. There are no longer any restrictions on characters that are allowed in tiddler field names. However, `<script>` tag store areas must encode the `<` character to `\u003c`.
```html
<script class="tiddlywiki-tiddler-store" type="application/json">[
{"title":"XLSX Utilities Edition","created":"20161023202301847","modified":"20161023202301847","tags":"Editions","type":"text/vnd.tiddlywiki","text":"The ''XLSX Utilities'' edition of TiddlyWiki contains tools to work with `.XLSX` spreadsheets generated by applications like Microsoft Excel and Google Sheets. It can be used in the browser or under Node.js.\n\nhttps://tiddlywiki.com/editions/xlsx-utils/\r\n"},
{"text":"In accordance with the [[Philosophy of Tiddlers]], documentation tiddlers are typically short and interlinked.\n\nWhen a tiddler seems as if it needs to contain subheadings, this is often a sign that it should in fact be split into several tiddlers. But it is reasonable for a [[reference tiddler|Reference Tiddlers]] to consist of an untitled introductory section followed by a titled section of details.\n\nConsistency of terminology is essential if the reader is not to become confused. Consistent typography and punctuation lend a professional quality to the documentation. Macros can improve the consistency and maintainability of the text.\n\nUse numbered lists for step-by-step instructions, and bullet points for lists whose order is arbitrary. Use a definition list in preference to a bulleted list if each bulleted item would begin with a term and a colon. If at all possible, avoid burdening the reader with a nested list.\n\nUse a table when information naturally falls into three or more columns, and also for lists of parameters, attributes, etc in [[reference tiddlers|Reference Tiddlers]].\n\nAvoid periods at the end of list items, headings and table cell text.\n\nThe documentation describes the current reality of ~TiddlyWiki. Avoid discussing future aspirations.\n","title":"Tiddler Structure","tags":"[[Improving TiddlyWiki Documentation]]","modified":"20210207124737959","created":"20150110183300000"}
]</script>
```
To retain compatibility with external tools that might insert tiddlers by directly manipulating the ~TiddlyWiki HTML file, the older format `<div>` store area is still present in the HTML file immediately after the new `<script>` tag store area:
```html
<script class="tiddlywiki-tiddler-store" type="application/json">[
{"title":"XLSX Utilities Edition","created":"20161023202301847","modified":"20161023202301847","tags":"Editions","type":"text/vnd.tiddlywiki","text":"The ''XLSX Utilities'' edition of TiddlyWiki contains tools to work with `.XLSX` spreadsheets generated by applications like Microsoft Excel and Google Sheets. It can be used in the browser or under Node.js.\n\nhttps://tiddlywiki.com/editions/xlsx-utils/\r\n"},
{"text":"In accordance with the [[Philosophy of Tiddlers]], documentation tiddlers are typically short and interlinked.\n\nWhen a tiddler seems as if it needs to contain subheadings, this is often a sign that it should in fact be split into several tiddlers. But it is reasonable for a [[reference tiddler|Reference Tiddlers]] to consist of an untitled introductory section followed by a titled section of details.\n\nConsistency of terminology is essential if the reader is not to become confused. Consistent typography and punctuation lend a professional quality to the documentation. Macros can improve the consistency and maintainability of the text.\n\nUse numbered lists for step-by-step instructions, and bullet points for lists whose order is arbitrary. Use a definition list in preference to a bulleted list if each bulleted item would begin with a term and a colon. If at all possible, avoid burdening the reader with a nested list.\n\nUse a table when information naturally falls into three or more columns, and also for lists of parameters, attributes, etc in [[reference tiddlers|Reference Tiddlers]].\n\nAvoid periods at the end of list items, headings and table cell text.\n\nThe documentation describes the current reality of ~TiddlyWiki. Avoid discussing future aspirations.\n","title":"Tiddler Structure","tags":"[[Improving TiddlyWiki Documentation]]","modified":"20210207124737959","created":"20150110183300000"}
]</script><div id="storeArea" style="display:none;"></div>
```
Any tiddlers in the older format `<div>` store area are also loaded before tiddlers from the new `<script>` store area.
!!! Multiple store areas and precedence
Tiddlers from the new `<script>` tag store areas are loaded in the order of their store areas in the HTML file. Therefore if the same tiddler exists in two different `<script>` tag store areas, the tiddler from the later store area takes precedence. Note however that tiddlers from `<script>` tag store areas always take precedence over tiddlers from the older format `<div>` store area. Therefore a tiddler from the older `<div>` store area can never overwrite a tiddler from a `<script>` tag store area.
Note that all `<script>` tags with the `class` attribute "tiddlywiki-tiddler-store" have their content parsed as JSON and loaded as tiddlers. This allows external tools to easily insert tiddlers into an HTML file by appending additional `<script>` tag(s) at the very end of the HTML file:
```html
</html>
<script class="tiddlywiki-tiddler-store" type="application/json">[
{"created":"20210525212411223","text":"This is some test text","tags":"[[test tag]] [[another tag]]","title":"My new tiddler to insert","modified":"20210525212430577"}
]</script>
```
Additional topics:
* [[Extracting tiddlers from a single file TiddlyWiki]]

View File

@ -0,0 +1,10 @@
created: 20140708085814626
modified: 20210525165526997
tags: doc
title: Data Storage
~TiddlyWiki has two approaches to saving the user data (tiddlers) depending on whether you are using the single file version, or are using the node.js server.
~TiddlyWiki on node.js saves each tiddler in a separate text file. For details on the file formats supported for tiddlers on node.js, see [[Tiddler Files|https://tiddlywiki.com/#TiddlerFiles]].
The single file version of ~TiddlyWiki saves the tiddlers within the HTML file. See [[Data Storage in Single File TiddlyWiki]]

View File

@ -0,0 +1,4 @@
title: dezerializer test data case 1
type: text/html
<!doctype html>

View File

@ -0,0 +1,12 @@
title: dezerializer test data case 2
type: text/html
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Test Data</title>
</head>
<body>
</body>
</html>

View File

@ -0,0 +1,18 @@
title: dezerializer test data case 3
type: text/html
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Test Data</title>
</head>
<body>
<!--~~ Ordinary tiddlers ~~-->
<div id="storeArea" style="display:none;"><div title="Hello &quot;There&quot;" type="text/vnd.tiddlywiki">
<pre>Abacus</pre>
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,19 @@
title: dezerializer test data case 4
type: text/html
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Test Data</title>
</head>
<body>
<!--~~ Ordinary tiddlers ~~-->
<div id="storeArea" style="display:none;"><div title="Hello &quot;There&quot;" type="text/vnd.tiddlywiki">
<pre>Abacus</pre>
</div>
</div>
<script class="tiddlywiki-tiddler-store" type="application/json">[{"title":"Hello \"There\"","text":"Calculator"}]</script>
</body>
</html>

View File

@ -0,0 +1,20 @@
title: dezerializer test data case 5
type: text/html
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Test Data</title>
</head>
<body>
<!--~~ Ordinary tiddlers ~~-->
<div id="storeArea" style="display:none;"><div title="Hello &quot;There&quot;" type="text/vnd.tiddlywiki">
<pre>Abacus</pre>
</div>
</div>
<script class="tiddlywiki-tiddler-store" type="application/json">[{"title":"Hello \"There\"","text":"Calculator"}]</script>
</body>
</html>
<script class="tiddlywiki-tiddler-store" type="application/json">[{"title":"Hello \"There\"","text":"Protractor"}]</script>

View File

@ -0,0 +1,39 @@
/*\
title: test-deserializers.js
type: application/javascript
tags: [[$:/tags/test-spec]]
Tests various core deserializers
\*/
(function(){
/* jslint node: true, browser: true */
/* eslint-env node, browser, jasmine */
/* eslint no-mixed-spaces-and-tabs: ["error", "smart-tabs"]*/
/* global $tw, require */
"use strict";
describe("deserializer tests", function() {
function executeTestCase(title,expectedOutput) {
it("test case " + title, function() {
var tiddler = $tw.wiki.getTiddler(title);
expect($tw.wiki.deserializeTiddlers(tiddler.fields.type,tiddler.fields.text)).toEqual(expectedOutput);
});
}
executeTestCase("dezerializer test data case 1",[ { text: '<!doctype html>\n', type: 'text/html' } ]);
executeTestCase("dezerializer test data case 2",[ { text: '<!doctype html>\n<html lang="en">\n<head>\n\t<meta charset="utf-8">\n\t<title>Test Data</title>\n</head>\n<body>\n</body>\n</html>\n', type: 'text/html' } ]);
executeTestCase("dezerializer test data case 3",[ { title: 'Hello "There"', text: 'Abacus', type: 'text/vnd.tiddlywiki' } ]);
executeTestCase("dezerializer test data case 4",[ { title: 'Hello "There"', text: 'Abacus', type: 'text/vnd.tiddlywiki' }, { title: 'Hello "There"', text: 'Calculator'} ]);
executeTestCase("dezerializer test data case 5",[ { title: 'Hello "There"', text: 'Abacus', type: 'text/vnd.tiddlywiki' }, { title: 'Hello "There"', text: 'Calculator'} , { title: 'Hello "There"', text: 'Protractor'} ]);
});
})();

View File

@ -0,0 +1,22 @@
title: JSONTiddlerWidget
created: 20210630100923398
modified: 20210630100923398
tags: Widgets
caption: jsontiddler
! Introduction
The jsontiddler widget renders the fields of a tiddler to display as a JSON object. The fields of the tiddler can be customised or excluded.
The jsontiddler widget is used in system templates to generate JSON representations of tiddlers for saving.
! Content and Attributes
The content of the `<$jsontiddler>` widget is ignored.
|!Attribute |!Description |
|tiddler |Optional title of the tiddler from which the fields are to be displayed |
|exclude |Optional space separated list of fields to be excluded |
|escapeUnsafeScriptChars |If set to "yes" then the `<` character will be escaped to the equivalent `\u003C` encoding |
|//{any attributes starting with $}// |Each attribute name (without the leading `$`) specifies a field to be modified with the attribute value providing the value to assign to the field |

View File

@ -37,7 +37,6 @@ Error/WhileSaving: حدث خطأ أثناء الحفظ
InternalJavaScriptError/Hint: حسنا، هذا أمر محرج. من المستحسن إعادة تشغيل تدلي ويكي عن طريق إنعاش المتصفح الخاص بك
InternalJavaScriptError/Title: خطأ جافا سكربت داخلي
InvalidFieldName: أحرف غير صحيحة في اسم الحقل "<$text text=<<fieldName>>/>". يمكن أن تحتوي الحقول فقط على الأحرف الانجليزية الصغيرة والأرقام والأحرف السفلية (`_`) والواصلة (` -`) والنقطة (`.`)
LoginToTiddlySpace: تسجيل الدخول إلى تدلي سبيس
Manager/Controls/FilterByTag/None: (بلا)

View File

@ -35,7 +35,6 @@ Error/WhileSaving: S'ha produït un error en desar
Error/XMLHttpRequest: Codi d'error XMLHttpRequest
InternalJavaScriptError/Hint: Bé, això és compromès. Es recomana que reinicieu TiddlyWiki actualitzant el navegador
InternalJavaScriptError/Title: S'ha produït un error intern de JavaScript
InvalidFieldName: Hi ha caràcters il·legals al nom del camp "<$text text=<<fieldName>>/>". Els camps només poden utilitzar minúscules, digits i els caràcters subratllat (`_`), guió (`-`) i punt (`.`)
LazyLoadingWarning: <p>S'està tractant de carregar contingut extern de ''<$text text={{!!_canonical_uri}}/>''</p><p>Si aquest missatge no desapareix, o bé el tipus de contingut del tiddler no coincideix amb el tipus de contingut extern o bé esteu utilitzant un navegador que no admet contingut extern per als wikis carregats com a fitxers independents. Mireu https://tiddlywiki.com/#ExternalText</p>
LoginToTiddlySpace: Inicieu la sessió a TiddlySpace
Manager/Controls/FilterByTag/None: (cap)

View File

@ -12,7 +12,6 @@ DefaultNewTiddlerTitle: Nový Tiddler
DropMessage: Zde pusťte (nebo zmáčknutím Esc zrušte)
Encryption/ConfirmClearPassword: Chcete ztušit heslo? Tím se zruší šifrování této wiki
Encryption/PromptSetPassword: Nastavte nové heslo pro tuto TiddlyWiki
InvalidFieldName: Neplatné znaky v názvu pole "<$text text=<<fieldName>>/>". Název může obsahovat pouze malá písmena, čísla, podtržítko (`_`), pomlčku (`-`) a tečku (`.`)
MissingTiddler/Hint: Chybějící tiddler "<$text text=<<currentTiddler>>/>" - klikněte na {{||$:/core/ui/Buttons/edit}} pro jeho vytvoření
RecentChanges/DateFormat: DD. MM. YYYY
SystemTiddler/Tooltip: Toto je systémový tiddler

View File

@ -30,7 +30,6 @@ Error/SavingToTWEdit: Fejl ved gemning til TWEdit
Error/WhileSaving: Fejl ved gemning
InternalJavaScriptError/Hint: Oh, dette er pinligt. Det anbefales at du genstarter TiddlyWiki ved at opfriske din browser
InternalJavaScriptError/Title: Intern JavaScript fejl
InvalidFieldName: Illegale tegn i felt navn "<$text text=<<fieldName>>/>". Felter kan kun indeholde små bogstaver, tal og tegnene undersstreg (`_`), bindestreg (`-`) og punktum (`.`)
LazyLoadingWarning: <p>indlæser ekstern tekst fra ''<$text text={{!!_canonical_uri}}/>''</p><p>Hvis denne besked ikke forsvinder, bruger du måske en browser, som ikke understøtter ekstern tekst i denne konfiguration. Se https://tiddlywiki.com/#ExternalText</p>
LoginToTiddlySpace: Login til TiddlySpace
Manager/Controls/FilterByTag/Prompt: Filtrer efter tag:

View File

@ -34,7 +34,6 @@ Error/WhileSaving: Σφάλμα κατά την αποθήκευση
Error/XMLHttpRequest: XMLHttpRequest κωδικός σφάλματος
InternalJavaScriptError/Hint: Λοιπόν, αυτό είναι αδιέξοδο. Συνιστάτε να επανεκκινήσετε το TiddlyWiki κάνοντας ανανέωση στον φυλλομετρητή σας
InternalJavaScriptError/Title: Εσωτερικό σφάλμα σε JavaScript
InvalidFieldName: Μη έγκυροι χαρακτήρες στο όνομα πεδίου "<$text text=<<fieldName>>/>". Τα ονόματα πεδίων μπορούν να περιέχουν μόνο πεζούς χαρακτήρες, ψηφία και τους χαρακτήρες κάτω παύλα (`_`), μείον (`-`) και τελεία (`.`)
LazyLoadingWarning: <p>Γίνεται φόρτωση εξωτερικού κειμένου από ''<$text text={{!!_canonical_uri}}/>''</p><p>Αν αυτό το μήνυμα δεν εξαφανιστεί ίσως το πρόγραμμα περιήγησης που χρησιμοποιείται να μην υποστηρίζει εξωτερικό κείμενο στις τρέχουσες του ρυθμίσεις. Δείτε σχετικά στο https://tiddlywiki.com/#ExternalText</p>
LoginToTiddlySpace: Είσοδος χρήστη στο TiddlySpace
Manager/Controls/FilterByTag/None: (κανένα)

View File

@ -41,7 +41,6 @@ Error/WhileSaving: Error al guardar
Error/XMLHttpRequest: Código de error XMLHttpRequest
InternalJavaScriptError/Hint: Hay un problema. Se recomienda que reinicies TiddlyWiki
InternalJavaScriptError/Title: Error interno de JavaScript
InvalidFieldName: Caracteres ilegales en el campo "<$text text=<<fieldName>>/>"<br> Los campos sólo pueden contener letras en minúscula, dígitos y los caracteres guión bajo (`_`), guión corto (`-`) y punto (`.`)
LayoutSwitcher/Description: Abre el selector de diseño
LazyLoadingWarning: <p>Cargando texto externo desde ''<$text text={{!!_canonical_uri}}/>''</p><p>Si este mensaje no desaparece, puede que se deba a que estás usando un navegador que con esta configuración no permite texto externo</br> Vea https://tiddlywiki.com/#ExternalText</p>
LoginToTiddlySpace: Inicia sesión en TiddlySpace

View File

@ -34,7 +34,6 @@ Error/WhileSaving: خطا در حین ذخیره
Error/XMLHttpRequest: XMLHttpRequest error code
InternalJavaScriptError/Hint: اوه این خجالت آوره. پیشنهاد می‌کنیم که با ریفرش کردن مرورگرتون تیدلی‌ویکی رو دوباره باز کنین
InternalJavaScriptError/Title: خطای JavaScript داخلی
InvalidFieldName: Illegal characters in field name "<$text text=<<fieldName>>/>". Fields can only contain lowercase letters, digits and the characters underscore (`_`), hyphen (`-`) and period (`.`)
LazyLoadingWarning: <p>Loading external text from ''<$text text={{!!_canonical_uri}}/>''</p><p>If this message doesn't disappear you may be using a browser that doesn't support external text in this configuration. See https://tiddlywiki.com/#ExternalText</p>
LoginToTiddlySpace: Login to TiddlySpace
Manager/Controls/FilterByTag/None: (هیچ)

View File

@ -41,7 +41,6 @@ Error/WhileSaving: Erreur lors de l'enregistrement
Error/XMLHttpRequest: Code d'erreur XMLHttpRequest
InternalJavaScriptError/Title: Erreur interne JavaScript
InternalJavaScriptError/Hint: C'est assez embarrassant. Il est recommandé de rafraîchir l'affichage de votre navigateur
InvalidFieldName: Caractères illicites dans le nom du champ « <$text text=<<fieldName>>/> ». Les champs ne peuvent contenir que des lettres minuscules non accentuées et les caractères souligné (`_`), tiret (`-`) et point (`.`)
LayoutSwitcher/Description: Ouvre le commutateur de mise en page
LazyLoadingWarning: <p>Tentative de chargement d'un contenu externe ''<$text text={{!!_canonical_uri}}/>''</p><p>Si ce message ne disparaît pas, il est possible que vous deviez ajuster le type de contenu du tiddler en fonction du type de votre contenu externe, ou vous utilisez peut-être un navigateur qui n'accepte pas les contenus externes dans cette configuration. Voir https://tiddlywiki.com/#ExternalText</p>
LoginToTiddlySpace: Identification sur TiddlySpace

View File

@ -29,7 +29,6 @@ Error/SavingToTWEdit: שגיאה בשמירה TWEdit
Error/WhileSaving: שגיאה בשמירה
Error/XMLHttpRequest: XMLHttpRequest קוד שגיאה
InternalJavaScriptError/Hint: מביך, אך מומלץ שתאתחל מחדש על ידי רפרוש הדפדפן
InvalidFieldName: סימנים לא חוקיים בשם השדה "<$text text=<<fieldName>>/>". Fields can only contain lowercase letters, digits and the characters underscore (`_`), hyphen (`-`) and period (`.`)
LoginToTiddlySpace: היכנס ל TiddlySpace
MissingTiddler/Hint: טידלר חסר "<$text text=<<currentTiddler>>/>" -לחץ {{||$:/core/ui/Buttons/edit}} כדי ליצור
No: לא

View File

@ -12,7 +12,6 @@ DefaultNewTiddlerTitle: नया Tiddler
DropMessage: यहाँ ड्रॉप (या रद्द करने से बचने के लिए क्लिक करें)
Encryption/ConfirmClearPassword: आप पासवर्ड को स्पष्ट करना चाहते हैं? यह एन्क्रिप्शन को हटा देगा जब इस विकि बचत लागू किया
Encryption/PromptSetPassword: इस टिड्लीविकि के लिए एक नया पासवर्ड सेट करें
InvalidFieldName: फ़ील्ड के नाम पर अवैध वर्ण "<$ पाठ पाठ = << FIELDNAME >> />"। फील्ड्स केवल छोटे अक्षरों, अंकों में हो सकते हैं और अक्षर, हाइफन (`-`) और अवधि (_``) अंडरस्कोर (`.`)
MissingTiddler/Hint: लापता Tiddler बनाने के लिए "<$ पाठ पाठ = << currentTiddler >> />" - क्लिक करें {{$: / कोर / छवियों / संपादित करें बटन}} बनाने के लिए
RecentChanges/DateFormat: दिनांक / माह / वर्ष
SystemTiddler/Tooltip: यह एक ऐसी प्रणाली tiddler है

View File

@ -12,7 +12,6 @@ DefaultNewTiddlerTitle: Nove nota
DropMessage: Lassa cader ci (o clicca Esc pro cancellar)
Encryption/ConfirmClearPassword: Desira tu remover le contrasigno? Isto va remover le usate codification quando iste wiki es conservate
Encryption/PromptSetPassword: Fixa un nove contrasigno pro iste TiddlyWiki
InvalidFieldName: Signos illegal in le quadro "<$text text=<<fieldName>>/>". Quadros pote solmente continer litteras minuscule, cifras e le signos sublineate (`_`), ligamine (`-`) and puncto (`.`)
MissingTiddler/Hint: Notas mancante "<$text text=<<currentTiddler>>/>" - clicca {{||$:/core/ui/Buttons/edit}} pro crear
RecentChanges/DateFormat: le DD de MMM YYYY
SystemTiddler/Tooltip: Isto es un notitia de systema

View File

@ -19,7 +19,6 @@ Encryption/PromptSetPassword: Imposta una nuova pasword per questo ~TiddlyWiki
Encryption/RepeatPassword: Ripeti password
Encryption/SetPassword: Imposta password
Encryption/Username: NomeUtente
InvalidFieldName: Caratteri non consentiti nel campo nome "<$text text=<<fieldName>>/>". I campi nome possono solo contenere lettere minuscole, numeri ed i caratteri sottolineato (`_`), meno (`-`) e punto (`.`)
MissingTiddler/Hint: Frammento mancante "<$text text=<<currentTiddler>>/>" - clicca {{||$:/core/ui/Buttons/edit}} per crearlo
OfficialPluginLibrary: Libreria ufficiale plugin ~TiddlyWiki
PluginReloadWarning: Salva {{$:/core/ui/Buttons/save-wiki}} e ricarica {{$:/core/ui/Buttons/refresh}} per consentire alle modifiche ai plugin di avere effetto

View File

@ -11,7 +11,6 @@ ConfirmOverwriteTiddler: 本当にこの tiddler "<$text text=<<title>>/>" を
DropMessage: ドロップしてください。(止めるには、キャンセルをクリックしてください。)
Encryption/ConfirmClearPassword: パスワードを削除すると暗号化も解除されますが、本当にパスワードを削除しますか?
Encryption/PromptSetPassword: パスワードを入力してください。
InvalidFieldName: フィールド名に不正な文字が使われています "<$text text=<<fieldName>>/>". フィールド名に使用できるのは英小文字かアンダースコア(`_`)、ハイフン(`-`)、ピリオド(`.`)のみです。
MissingTiddler/Hint: 未作成の tiddler "<$text text=<<currentTiddler>>/>" - クリック {{||$:/core/ui/Buttons/edit}} して作成
RecentChanges/DateFormat: YYYY-MM-DD
SystemTiddler/Tooltip: これはシステム tiddler です

View File

@ -33,7 +33,6 @@ Error/WhileSaving: 저장하는 동안 오류
Error/XMLHttpRequest: XMLHttpRequest 오류 코드
InternalJavaScriptError/Hint: 아이 창피해. 브라우저를 새로 고쳐 티들리위키를 다시 시작할 것을 권장합니다
InternalJavaScriptError/Title: 내부 자바스크립트 오류
InvalidFieldName: "<$text text=<<fieldName>>/>" 필드 이름에 잘못된 문자가 있습니다. 필드는 소문자, 숫자 및 밑줄 문자 (`_`), 하이픈 (`-`) 및 마침표 (`.`)만을 포함할 수 있습니다.
LazyLoadingWarning: <p>''<$text text={{!!_canonical_uri}}/>''에서 바깥 텍스트를 불러오는 중입니다</p><p>이 메시지가 사라지지 않으면 이 구성에서 바깥 텍스트를 지원하지 않는 브라우저를 사용하고 있을 수 있습니다. [[https://tiddlywiki.com/#ExternalText]]를 보세요</p>
LoginToTiddlySpace: TiddlySpace에 로그인
MissingTiddler/Hint: "<$text text=<<currentTiddler>>/>" 티들러가 없습니다 - 만드려면 {{||$:/core/ui/Buttons/edit}}을 클릭하세요

View File

@ -38,7 +38,6 @@ Error/WhileSaving: Fout bij opslaan
Error/XMLHttpRequest: XMLHttpRequest foutcode
InternalJavaScriptError/Hint: Er is een probleem. Herstart TiddlyWiki door je browser te verversen
InternalJavaScriptError/Title: Interne JavaScript fout
InvalidFieldName: Illegale lettertekens in veldnaam "<$text text=<<fieldName>>/>". Velden kunnen alleen kleine letters, cijfers en de lettertekens liggend streepje (`_`), koppelteken (`-`) en punt (`.`)
LazyLoadingWarning: <p>Er wordt externe tekst geladen van ''<$text text={{!!_canonical_uri}}/>''</p><p>Als deze mededeling niet verdwijnt ondersteunt de gebruikte browser in deze configuratie mogelijk geen externe tekst. Zie https://tiddlywiki.com/#ExternalText</p>
LoginToTiddlySpace: Login bij TiddlySpace
Manager/Controls/FilterByTag/None: (geen)

View File

@ -12,7 +12,6 @@ DefaultNewTiddlerTitle: ਨਿਊ Tiddler
DropMessage: ਇੱਥੇ ਛੱਡੋ (ਜ ਰੱਦ ਕਰਨ ਲਈ ਬਚ ਕਲਿੱਕ ਕਰੋ)
Encryption/ConfirmClearPassword: ਤੁਸੀ ਪਾਸਵਰਡ ਨੂੰ ਸਾਫ਼ ਕਰਨਾ ਚਾਹੁੰਦੇ ਹੋ? ਇਹ ਇੰਕ੍ਰਿਪਸ਼ਨ ਹਟਾਉਣ ਤੇ ਇਸ ਵਿਕੀ 'ਨੂੰ ਬਚਾਉਣ ਲਈ ਲਾਗੂ ਕੀਤਾ ਜਾਵੇਗਾ
Encryption/PromptSetPassword: TiddlyWiki ਲਈ ਇੱਕ ਪਾਸਵਰਡ ਸੈੱਟ ਕਰੋ
InvalidFieldName: ਖੇਤਰ ਦੇ ਨਾਮ ਵਿੱਚ ਗਲਤ ਅੱਖਰ "<$ ਪਾਠ = << >> fieldName />". ਖੇਤਰ ਸਿਰਫ ਛੋਟੇ ਅੱਖਰ, ਅੰਕ ਹੋ ਸਕਦੇ ਹਨ ਅਤੇ ਅੱਖਰ, ਹਾਈਫਨ (`-`) ਅਤੇ ਦੀ ਮਿਆਦ (_``) ਜ਼ੋਰ (`.`)
MissingTiddler/Hint: Tiddler ਗੁੰਮ ਹੈ "<$ ਪਾਠ = << >> currentTiddler />" - ਕਲਿੱਕ ਕਰੋ {{$ / core / images / ਸੋਧ-ਬਟਨ}} ਨੂੰ ਬਣਾਉਣ ਲਈ
RecentChanges/DateFormat: ਮਿਤੀ /ਮਹੀਨੇ /ਸਾਲ
SystemTiddler/Tooltip: ਇਹ ਇੱਕ ਸਿਸਟਮ tiddler ਹੈ

View File

@ -33,7 +33,6 @@ Error/WhileSaving: Erro ao gravar
Error/XMLHttpRequest: Código de erro XMLHttpRequest
InternalJavaScriptError/Hint: Bem, isto é embaraçoso. Para corrigir, reinicie a sua TiddlyWiki recarregando a página em seu navegador. Normalmente o atalho é (F5)
InternalJavaScriptError/Title: Erro interno JavaScript
InvalidFieldName: Caracteres ilegais no nome do arquivo "<$text text=<<fieldName>>/>". Os campos apenas podem conter letras minúsculas, dígitos e os caracteres sublinhado (`_`), hífen (`-`) e ponto final (`.`)
LazyLoadingWarning: <p>Carregando um texto externo de ''<$text text={{!!_canonical_uri}}/>''</p><p>Se esta mensagem não desaparecer pode ser que esteja usando um navegador que não suporte textos remoto com esta configuração. Veja http://tiddlywiki.com/#ExternalText</p>
LoginToTiddlySpace: Entrar em TiddlySpace
Manager/Controls/FilterByTag/None: (nenhum)

View File

@ -35,7 +35,6 @@ Error/WhileSaving: Erro ao gravar
Error/XMLHttpRequest: Código de erro XMLHttpRequest
InternalJavaScriptError/Hint: Bem, isto é embaraçoso. Recomenda-se que reinicie a sua TiddlyWiki recarregando o seu navegador
InternalJavaScriptError/Title: Erro interno JavaScript
InvalidFieldName: Caracteres ilegais no nome do ficheiro "<$text text=<<fieldName>>/>". Os campos apenas podem conter letras minúsculas, dígitos e os caracteres subtraço (`_`), hífen (`-`) e ponto final (`.`)
LazyLoadingWarning: <p>A carregar texto externo de ''<$text text={{!!_canonical_uri}}/>''</p><p>Se esta mensagem não desaparecer pode estar a utilizar um navegador que não suporta texto remoto nesta configuração. Veja https://tiddlywiki.com/#ExternalText</p>
LoginToTiddlySpace: Entrar em TiddlySpace
Manager/Controls/FilterByTag/None: (none)

View File

@ -19,7 +19,6 @@ Encryption/PromptSetPassword: Установить новый пароль дл
Encryption/RepeatPassword: Повторите пароль
Encryption/SetPassword: Введите пароль
Encryption/Username: Имя пользователя
InvalidFieldName: Недопустимые символы в названии поля "<$text text=<<fieldName>>/>". Поля могут содержать только латинские буквы нижнего регистра, цифры и символы: подчеркивание (`_`), дефис (`-`) и точку (`.`)
MissingTiddler/Hint: Заметка "<$text text=<<currentTiddler>>/>" отсутствует - нажмите {{||$:/core/ui/Buttons/edit}} чтобы её создать
OfficialPluginLibrary: Официальная Библиотека Плагинов ~TiddlyWiki
PluginReloadWarning: Пожалуйста, сохраните {{$:/core/ui/Buttons/save-wiki}} и перезапустите {{$:/core/ui/Buttons/refresh}} вики, чтобы изменения в плагинах возымели эффект.

View File

@ -12,7 +12,6 @@ DefaultNewTiddlerTitle: Nový tiddler
DropMessage: Dropnúť sem (alebo zrušiť cez escape)
Encryption/ConfirmClearPassword: Želáte si zrušiť heslo? Odstráni sa tým šifrovanie obsahu pri ukladaní wiki
Encryption/PromptSetPassword: Nastav pre tento TiddlyWiki nové heslo
InvalidFieldName: Nepovolené znaky v názve poľa "<$text text=<<fieldName>>/>". Polia môžu obsahovať iba malé písmená, číslice a podčiarnik (`_`), pomlčku (`-`) alebo bodku (`.`)
MissingTiddler/Hint: Chýbajúci tiddler "<$text text=<<currentTiddler>>/>" - ak ho chcete vytvoriť, kliknite {{||$:/core/ui/Buttons/edit}}
RecentChanges/DateFormat: DDth MMM YYYY
SystemTiddler/Tooltip: Toto je systémový tiddler

View File

@ -34,7 +34,6 @@ Error/WhileSaving: Napaka med shranjevanjem
Error/XMLHttpRequest: Koda napake XMLHttpRequest
InternalJavaScriptError/Hint: No, to je neprijetno. Priporočamo, da znova zaženete TiddlyWiki tako, da osvežite brskalnik
InternalJavaScriptError/Title: Notranja napaka JavaScript
InvalidFieldName: Neveljavni znaki v imenu polja "<$text text=<<fieldName>>/>". Imena polj lahko vsebujejo samo male črke, številke, podčrtaj (`_`), minus (`-`) in piko (`.`).
LazyLoadingWarning: <p>Nalaganje zunanjega besedila z ''<$text text={{!!_canonical_uri}}/>''</p><p>Če to sporočilo ne izgine, morda uporabljate brskalnik, ki ne podpira zunanjega besedila v tej konfiguraciji. Oglejte si http://tiddlywiki.com/#ExternalText</p>
LoginToTiddlySpace: Prijavite se v TiddlySpace
Manager/Controls/FilterByTag/None: (nobena)

View File

@ -19,7 +19,6 @@ Encryption/Password: Lösenord
Encryption/RepeatPassword: Upprepa lösenordet
Encryption/PasswordNoMatch: Lösenorden matchar inte
Encryption/SetPassword: Ställ in lösenord
InvalidFieldName: Ogiltigt tecken i namn-fältet "<$text text=<<fieldName>>/>". Fält kan bara innehålla gemena bokstäver, siffror och tecknen understreck (`_`), bindestreck (`-`) and punkt (`.`)
MissingTiddler/Hint: Saknar tiddler "<$text text=<<currentTiddler>>/>" - klicka {{||$:/core/ui/Buttons/edit}} för att skapa
OfficialPluginLibrary: Officiella ~TiddlyWiki Insticksprogramsbibliotek
PluginReloadWarning: Spara {{$:/core/ui/Buttons/save-wiki}} och ladda om {{$:/core/ui/Buttons/refresh}} för att ändringarna för insticksprogrammen ska slå igenom

View File

@ -41,7 +41,6 @@ Error/WhileSaving: 保存时,发生错误
Error/XMLHttpRequest: XMLHttpRequest 错误代码
InternalJavaScriptError/Title: 内部的 JavaScript 错误
InternalJavaScriptError/Hint: 喔,真是令人尴尬。建议刷新您的浏览器,重新启动 TiddlyWiki
InvalidFieldName: 字段名称 "<$text text=<<fieldName>>/>" 包含无效字符,字段名称只能包含小写字母、数字、底线 (`_`)、 连字号 (`-`) 和小数点 (`.`)
LayoutSwitcher/Description: 打开布局切换器
LazyLoadingWarning: <p>正在从 ''<$text text={{!!_canonical_uri}}/>'' 加载外部内容 ...</p><p>如果此信息未消失,可能是条目内容类型与外部内容的类型不匹配,或是您可能正在使用的浏览器,不支援单文件式维基的外部内容。请参阅 https://tiddlywiki.com/#ExternalText</p>
LoginToTiddlySpace: 登录 TiddlySpace

View File

@ -41,7 +41,6 @@ Error/WhileSaving: 儲存時,發生錯誤
Error/XMLHttpRequest: XMLHttpRequest 錯誤代碼
InternalJavaScriptError/Title: 內部的 JavaScript 錯誤
InternalJavaScriptError/Hint: 喔,真是令人尷尬。建議刷新您的瀏覽器,重新啟動 TiddlyWiki
InvalidFieldName: 欄位名稱 "<$text text=<<fieldName>>/>" 包含無效字元,欄位名稱只能包含小寫字母、數字、底線 (`_`)、 連接號 (`-`) 和小數點 (`.`)
LayoutSwitcher/Description: 開啟版面切換器
LazyLoadingWarning: <p>正在從 ''<$text text={{!!_canonical_uri}}/>'' 載入外部內容 ...</p><p>如果此訊息未消失,可能是條目內容類型與外部內容的類型不匹配,或是您可能正在使用的瀏覽器,不支援單檔式維基的外部內容。請參閱 https://tiddlywiki.com/#ExternalText</p>
LoginToTiddlySpace: 登入 TiddlySpace

View File

@ -0,0 +1,4 @@
title: $:/core/templates/html-json-skinny-tiddler
<$list filter="[<numTiddlers>compare:number:gteq[1]] ~[<counter>!match[1]]">`,`<$text text=<<newline>>/></$list>
<$jsontiddler tiddler=<<currentTiddler>> exclude="text" escapeUnsafeScriptChars="yes" $revision=<<changecount>> $bag="default" $_is_skinny=""/>

View File

@ -0,0 +1,4 @@
title: $:/core/templates/html-json-tiddler
<$list filter="[<counter>!match[1]]">`,`<$text text=<<newline>>/></$list>
<$jsontiddler tiddler=<<currentTiddler>> escapeUnsafeScriptChars="yes" $revision=<<changecount>> $bag="default">/>