1
0
mirror of https://github.com/Jermolene/TiddlyWiki5 synced 2025-10-31 07:32:59 +00:00

Split "transclude" widget into a separate "tiddler" and "transclude" widget

Belatedly realised that the design would be clearer without these two
separate concepts being conflated into a single widget.

As a result of this change, any other widget or template that generates
transclude widgets has needed adjustment.
This commit is contained in:
Jeremy Ruston
2013-08-24 16:45:45 +01:00
parent 6c5239603c
commit be06257430
19 changed files with 259 additions and 151 deletions

View File

@@ -6,38 +6,7 @@ module-type: widget
The transclude widget includes another tiddler into the tiddler being rendered.
Attributes:
target: the title of the tiddler to transclude
template: the title of the tiddler to use as a template for the transcluded tiddler
The simplest case is to just supply a target tiddler:
{{{
<$transclude target="Foo"/>
}}}
This will render the tiddler Foo within the current tiddler. If the tiddler Foo includes
the view widget (or other widget that reference the fields of the current tiddler), then the
fields of the tiddler Foo will be accessed.
If you want to transclude the tiddler as a template, so that the fields referenced by the view
widget are those of the tiddler doing the transcluding, then you can instead specify the tiddler
as a template:
{{{
<$transclude template="Foo"/>
}}}
The effect is the same as the previous example: the text of the tiddler Foo is rendered. The
difference is that the view widget will access the fields of the tiddler doing the transcluding.
The `target` and `template` attributes may be combined:
{{{
<$transclude template="Bar" target="Foo"/>
}}}
Here, the text of the tiddler `Bar` will be transcluded, with the widgets within it accessing the fields
of the tiddler `Foo`.
title: the title of the tiddler to transclude
\*/
(function(){
@@ -55,65 +24,49 @@ var TranscludeWidget = function(renderer) {
TranscludeWidget.prototype.generate = function() {
var self = this,
tr, templateParseTree, templateTiddler;
templateParseTree;
// Get the render target details
this.targetTitle = this.renderer.getAttribute("target",this.renderer.tiddlerTitle);
this.targetField = this.renderer.getAttribute("field");
this.targetIndex = this.renderer.getAttribute("index");
// Get the render tree for the template
this.templateTitle = undefined;
if(this.renderer.parseTreeNode.children && this.renderer.parseTreeNode.children.length > 0) {
// Use the child nodes as the template if we've got them
templateParseTree = this.renderer.parseTreeNode.children;
this.transcludeTitle = this.renderer.getAttribute("title",this.renderer.tiddlerTitle);
this.transcludeField = this.renderer.getAttribute("field");
this.transcludeIndex = this.renderer.getAttribute("index");
// Check for recursion
if(this.renderer.renderTree.checkContextRecursion(this.renderer.parentRenderer,{
transcludeTitle: this.transcludeTitle,
transcludeField: this.transcludeField,
transcludeIndex: this.transcludeIndex
})) {
templateParseTree = [{type: "text", text: "Tiddler recursion error in transclude widget"}];
} else {
this.templateTitle = this.renderer.getAttribute("template",this.targetTitle);
// Check for recursion
if(this.renderer.renderTree.checkContextRecursion(this.renderer.parentRenderer,{
tiddlerTitle: this.targetTitle,
templateTitle: this.templateTitle
})) {
templateParseTree = [{type: "text", text: "Tiddler recursion error in transclude widget"}];
var parser;
if(this.transcludeField === "text" || (!this.transcludeField && !this.transcludeIndex)) {
parser = this.renderer.renderTree.wiki.parseTiddler(this.transcludeTitle,{parseAsInline: !this.renderer.parseTreeNode.isBlock});
} else {
var parser;
if(this.targetField === "text" || (!this.targetField && !this.targetIndex)) {
parser = this.renderer.renderTree.wiki.parseTiddler(this.templateTitle,{parseAsInline: !this.renderer.parseTreeNode.isBlock});
} else {
var tiddler,text;
if(this.targetField) {
tiddler = this.renderer.renderTree.wiki.getTiddler(this.targetTitle);
text = tiddler ? tiddler.fields[this.targetField] : "";
if(text === undefined) {
text = "";
}
parser = this.renderer.renderTree.wiki.parseText("text/vnd.tiddlywiki",text,{parseAsInline: !this.renderer.parseTreeNode.isBlock});
} else if(this.targetIndex) {
text = this.renderer.renderTree.wiki.extractTiddlerDataItem(this.targetTitle,this.targetIndex,"");
parser = this.renderer.renderTree.wiki.parseText("text/vnd.tiddlywiki",text,{parseAsInline: !this.renderer.parseTreeNode.isBlock});
var tiddler,text;
if(this.transcludeField) {
tiddler = this.renderer.renderTree.wiki.getTiddler(this.transcludeTitle);
text = tiddler ? tiddler.fields[this.transcludeField] : "";
if(text === undefined) {
text = "";
}
parser = this.renderer.renderTree.wiki.parseText("text/vnd.tiddlywiki",text,{parseAsInline: !this.renderer.parseTreeNode.isBlock});
} else if(this.transcludeIndex) {
text = this.renderer.renderTree.wiki.extractTiddlerDataItem(this.transcludeTitle,this.transcludeIndex,"");
parser = this.renderer.renderTree.wiki.parseText("text/vnd.tiddlywiki",text,{parseAsInline: !this.renderer.parseTreeNode.isBlock});
}
templateParseTree = parser ? parser.tree : [];
}
templateParseTree = parser ? parser.tree : [];
}
// Set up the attributes for the wrapper element
var classes = ["tw-transclude"];
if(this.renderer.hasAttribute("class")) {
$tw.utils.pushTop(classes,this.renderer.getAttribute("class").split(" "));
}
if(!this.renderer.renderTree.wiki.tiddlerExists(this.targetTitle) && !this.renderer.renderTree.wiki.isShadowTiddler(this.targetTitle)) {
$tw.utils.pushTop(classes,"tw-tiddler-missing");
}
// Save the context for this renderer node
this.renderer.context = {
tiddlerTitle: this.targetTitle,
templateTitle: this.templateTitle
transcludeTitle: this.transcludeTitle,
transcludeField: this.transcludeField,
transcludeIndex: this.transcludeIndex
};
// Initialise events
this.events = [];
// Trap and update tag modification events
this.events.push({name: "tw-remove-tag", handlerFunction: function(event) {
event.currentTag = self.targetTitle;
return true;
}});
// Set the element
this.tag = this.renderer.parseTreeNode.isBlock ? "div" : "span";
this.attributes = {};
@@ -130,12 +83,8 @@ TranscludeWidget.prototype.generate = function() {
};
TranscludeWidget.prototype.refreshInDom = function(changedAttributes,changedTiddlers) {
// Set the class for missing tiddlers
if(this.targetTitle && changedTiddlers[this.targetTitle]) {
$tw.utils.toggleClass(this.renderer.domNode,"tw-tiddler-missing",!this.renderer.renderTree.wiki.tiddlerExists(this.targetTitle));
}
// Check if any of our attributes have changed, or if a tiddler we're interested in has changed
if(changedAttributes.target || changedAttributes.template || (this.templateTitle && changedTiddlers[this.templateTitle])) {
if(changedAttributes.transcludeField || changedAttributes.transcludeIndex || (this.transcludeTitle && changedTiddlers[this.transcludeTitle])) {
// Regenerate and rerender the widget and replace the existing DOM node
this.generate();
var oldDomNode = this.renderer.domNode,