From VisualWorks® NonCommercial, 7.2 of November 3, 2003 on November 20, 2003 at 12:41:13 pm Template Smalltalk Core.Object false none contents variables variableMarker sdsu-util sdsu-util Template class instance creation fromFile: aString ^self fromString: (aString asFilename contentsOfEntireFile) fromString: aString ^super new setContents: aString Template A document (html or others) template. Place holders or variables in the template are indicated by textbetween two variableMarkers. For example in 'Hi @@@name@@@.' name is a variable. At runtime variables can be replaced with any object that implements 'asString'. Default value of a variable is an empty string. Sample use: | a | a := Template fromString: 'a@@@cat@@@b@@@dog@@@c'. a replace: 'cat' with: 'nancy'. a asString. "returns anancybc" a reset; replace: 'cat' with: 'pete' Instance Variables: contents <OrderedCollection> strings and variables that make up the template variables <Dictionary keys: string values: VariableBinding> Fast index of variables variableMarker <String> strings used to delimit a variable. Currently @@@ Template converting asString | output | output := WriteStream on: (String new: 100). self printOn: output. ^output contents Template accessing at: aString put: anObject self replace: aString with: anObject replace: aString with: anObject | placeHolder | placeHolder := variables at: aString. placeHolder value: anObject. reset ^variables do: [ :variable | variable value: '' ] variables ^variables keys Template private defaultVariableMarker ^'@@@' split: aString "aString is text with variables. Variables surrounded by '@@@'. Split the string at each variable. Return an ordered collection of text and variables, in the orderer they appear in aString" | splitString splitStart | splitString := OrderedCollection new: 30. splitStart := 1. [splitStart <= aString size] whileTrue: [| startMarker | startMarker := aString findString: variableMarker startingAt: splitStart. startMarker = 0 ifTrue: [startMarker := aString size + 1]. "handle last split" splitString add: (aString copyFrom: splitStart to: startMarker - 1). splitStart := startMarker + variableMarker size]. ^splitString variableAt: aStringKey ^variables at: aStringKey ifAbsentPut: [Association key: aStringKey value: (String new: 0)] Template instance creation setContents: aString variableMarker := self defaultVariableMarker. variables := Dictionary new. contents := self split: aString. 2 to: contents size by: 2 do: [:index | | aVariableKey | aVariableKey := contents at: index. contents at: index put: (self variableAt: aVariableKey ) ]. Template printing printOn: aStream contents keysAndValuesDo: [:index :value | index odd ifTrue: [aStream nextPutAll: value] ifFalse: [aStream nextPutAll: value value asString]]