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:
		| @@ -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, | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Jeremy Ruston
					Jeremy Ruston