ich habe vor kurzem eine kleine Template "Engine" geschrieben (wenn man das so nennen kann), um mir eine schnelle und einfache Möglichkeit zu geben
Content entsprechend zu füllen. Der Code ist realtiv simpel gestrickt, aber dafür recht schnell. Es werden Variablen und Schleifen im Template unterstüzt.
Wie sollte das ganze verwendet werden?
- Template Laden (Datei/String/Memory)
- Content Hinzufügen (ContentID.i = AddContent(ID.i))
- Content Setzten (SetContent(ContentID.i,"VARIABLE","ERSETZTE MIT")
Bei Schleifen ist es grundlegend das selbe Prinzip, jedoch muss die SchleifenID verwendet werden (GetLoopID("SCHLEIFEN_NAME")).
Für jedes "Feld" muss das oben geschriebene erneut ausgeführt werden.
Template Variable:
{tp:var:meinVariableNamen}
Template Schleife:
Start: {tp
-- DEIN CONTENT z.B. {tp:var:meinVariableNamen_inschleife}
Ende: {tp
Es sind auch "Schleifen in Schleifen" möglich, ich habe dazu entsprechend ein Beispielcode hinzugefügt.
Hoffe das ist für euch brauchbar, ich nutze es Regelmäßig.
Code: Alles auswählen
EnableExplicit
CompilerIf Defined(FileToStringEx,#PB_Procedure)
CompilerElse
; read the file in to the memory and convert it to a string
Procedure.s FileToStringEx(File.s)
Protected *memory, String.s, Bom.i, FileID.i
If FileSize(File.s) > -1
FileID.i = ReadFile(#PB_Any,File.s)
Bom.i = ReadStringFormat(FileID.i)
If FileID.i
*memory = AllocateMemory(FileSize(File.s))
If *memory
ReadData(FileID.i,*memory,FileSize(File.s))
String.s = PeekS(*memory,FileSize(File.s),Bom.i)
FreeMemory(*memory)
CloseFile(FileID.i)
EndIf
ProcedureReturn String.s
EndIf
EndIf
EndProcedure
CompilerEndIf
Structure easy_template_fieldcontent
*Content
*Element
EndStructure
Structure easy_template_fields
ID.i
Name.s
LoopName.s
IsHolder.b
List Content.easy_template_fieldcontent()
EndStructure
Structure easy_template_templateholder
ID.i
ParentID.i
Name.s
Content.s
List Fields.easy_template_fields()
EndStructure
Structure easy_template_data
*Field
Content.s
List SelfRef.i()
EndStructure
Structure easy_template_dataholder
ContentID.i
TemplateID.i
*Template
List Elements.easy_template_data()
EndStructure
Structure easy_template_link
FieldName.s
TemplateName.s
TemplateID.i
*Template
*Field
EndStructure
Structure easy_template_fix_fields
List Fields.easy_template_link()
EndStructure
Structure easy_template
___procs.i
List Template.easy_template_templateholder()
List TemplateLink.easy_template_link()
List Content.easy_template_dataholder()
EndStructure
Interface EasyTemplate
AddField(ID.i, Name.s, isHolder.b = #False, LoopElementName.s = "")
RelinkFields(ID.i,*fields.easy_template_fix_fields)
LoadString(Content.s,ParentID.i = -1,TemplateName.s = "")
LoadMemory(*Memory,Size.i,ParentID.i = -1)
LoadFile(File.s,ParentID.i = -1)
GetLoopID(TemplateID.i,LoopName.s)
AddContent(TemplateID.i)
SetContent(ContentID.i,Name.s,Value.s)
Build.s(TemplateID.i,*ContentRef = 0)
Destroy()
EndInterface
Procedure.i EasyTemplate_AddField(*this.easy_template,ID.i,Name.s,isHolder.b = #False,LoopElementName.s = "")
Protected Found.b,IsContentID.b,IsID.b
If ListSize(*this\Template())
ForEach *this\Template()
If *this\Template()\ID.i = ID.i
IsID.b = #True
ForEach *this\Template()\Fields()
If *this\Template()\Fields()\Name.s = Name.s
Found.b = #True
Break
EndIf
Next
Break
EndIf
Next
If Not Found.b And IsID.b
AddElement(*this\Template()\Fields())
*this\Template()\Fields()\Name.s = Name.s
*this\Template()\Fields()\isHolder.b = isHolder.b
*this\Template()\Fields()\LoopName = LoopElementName.s
;Debug "Added: "+ Name.s
ProcedureReturn #True
EndIf
EndIf
EndProcedure
Procedure.i EasyTemplate_RelinkFields(*this.easy_template,ID.i,*fields.easy_template_fix_fields)
Protected *curr
If ListSize(*this\Template()) And ID.i And *fields
ForEach *this\Template()
If *this\Template()\ID.i = ID.i
ForEach *this\Template()\Fields()
AddElement(*fields\Fields())
*fields\Fields()\FieldName.s = *this\Template()\Fields()\Name.s
*fields\Fields()\Field = @*this\Template()\Fields()
*fields\Fields()\Template = @*this\Template()
*fields\Fields()\TemplateName.s = *this\Template()\Name.s
*fields\Fields()\TemplateID.i = *this\Template()\ID.i
Next
EndIf
If *this\Template()\ParentID.i = ID.i
*curr = @*this\Template()
EasyTemplate_RelinkFields(*this,*this\Template()\ID.i,*fields)
ChangeCurrentElement(*this\Template(),*curr)
EndIf
Next
EndIf
EndProcedure
Procedure.i EasyTemplate_LoadString(*this.easy_template,Content.s,ParentID.i = -1,TemplateName.s = "")
Protected Dim Extract.s(0), Extraction.s, LoopPart.s, EndElement.s
Protected Expression.i, *CurrElement, Size.i, ElementID.i, On.i, ChildElement.i
Protected StartPos.i,EndPos.i
Protected fields.easy_template_fix_fields
Expression.i = CreateRegularExpression(#PB_Any,"{tp:[^}]*}")
If Content.s And Expression.i
Size.i = ExtractRegularExpression(Expression.i,Content.s,Extract())
FreeRegularExpression(Expression.i)
If Size.i
ElementID.i = Random(ElapsedMilliseconds()) + ListSize(*this\Template())
AddElement(*this\Template())
*this\Template()\ID.i = ElementID.i
If Not ParentID.i = -1
*this\Template()\ParentID.i = ParentID.i
*this\Template()\Name.s = TemplateName.s
EndIf
*CurrElement = *this\Template()
For On.i=0 To Size.i - 1
Extraction.s = RemoveString(RemoveString(Extract(On.i),"{"),"}")
Select LCase(StringField(Extraction.s,2,":"))
Case "var"
EasyTemplate_AddField(*this,ElementID.i,StringField(Extraction.s,3,":"))
Case "loop"
If LCase(StringField(Extraction.s,4,":")) = "start"
;Debug "Found LOOP! --> "+Extract(On.i)
StartPos.i = FindString(Content.s,Extract(On.i))
EndPos.i = FindString(Content.s,"{tp:loop:"+StringField(Extraction.s,3,":")+":end}",StartPos.i)
If EndPos.i
LoopPart.s = Mid(Content.s,StartPos.i+Len(Extract(On.i)),EndPos.i - (StartPos.i + Len(Extract(On.i))))
ChildElement.i = EasyTemplate_LoadString(*this,LoopPart.s,ElementID.i,StringField(Extraction.s,3,":"))
Content.s = ReplaceString(Content.s,Extract(On.i)+LoopPart.s+"{tp:loop:"+StringField(Extraction.s,3,":")+":end}","{tp:holder:"+Str(ChildElement.i)+"}")
EasyTemplate_AddField(*this,ElementID.i,Str(ChildElement.i),#True,StringField(Extraction.s,3,":"))
EndElement.s = "{tp:loop:"+StringField(Extraction.s,3,":")+":end}"
Repeat
If Extract(On.i) = EndElement.s
Break
Else
If Not (On.i + 1) > (Size.i - 1)
On.i + 1
Else
Break
EndIf
EndIf
ForEver
EndIf
EndIf
EndSelect
Next
ChangeCurrentElement(*this\Template(),*CurrElement)
*this\Template()\Content.s = Content.s
If ParentID.i = -1
EasyTemplate_RelinkFields(*this,ElementID.i,@fields)
If ListSize(fields\Fields())
ChangeCurrentElement(*this\Template(),*CurrElement)
CopyList(fields\Fields(),*this\TemplateLink())
EndIf
EndIf
ProcedureReturn ElementID.i
EndIf
EndIf
EndProcedure
Procedure.i EasyTemplate_LoadMemory(*this.easy_template,*Memory,Size.i,ParentID.i = -1)
Protected String.s
If *Memory > 0 And *this
String.s = PeekS(*Memory,Size.i)
If String.s
ProcedureReturn EasyTemplate_LoadString(*this,String.s,ParentID.i)
EndIf
EndIf
EndProcedure
Procedure.i EasyTemplate_LoadFile(*this.easy_template,File.s,ParentID.i = -1)
Protected Content.s
If FileSize(File.s) > 0 And *this
Content.s = FileToStringEx(File.s)
If Content.s
ProcedureReturn EasyTemplate_LoadString(*this,Content.s,ParentID.i)
EndIf
EndIf
EndProcedure
Procedure.i EasyTemplate_GetLoopID(*this.easy_template,TemplateID.i,LoopName.s)
If *this
If TemplateID.i > 0 And ListSize(*this\Template()) And ListSize(*this\TemplateLink())
ForEach *this\TemplateLink()
If *this\TemplateLink()\TemplateName.s = LoopName.s
If *this\TemplateLink()\Template
ChangeCurrentElement(@*this\Template(),*this\TemplateLink()\Template)
ProcedureReturn *this\Template()\ID.i
EndIf
EndIf
Next
EndIf
EndIf
EndProcedure
Procedure.i EasyTemplate_AddContent(*this.easy_template,TemplateID.i)
Protected *ID, ContentID.i, *Content
If TemplateID.i > 0 And *this
ForEach *this\TemplateLink()
If *this\TemplateLink()\TemplateID = TemplateID.i
If *this\TemplateLink()\Template
AddElement(*this\Content())
*ID = *this\TemplateLink()\Template
ContentID.i = ListSize(*this\Content())
*Content = @*this\Content()
*this\Content()\ContentID.i = ContentID.i
*this\Content()\TemplateID.i = TemplateID.i
*this\Content()\Template = *ID
ChangeCurrentElement(*this\Template(),*ID)
ForEach *this\Template()\Fields()
AddElement(*this\Content()\Elements())
*this\Content()\Elements()\Field = @*this\Template()\Fields()
AddElement(*this\Template()\Fields()\Content())
*this\Template()\Fields()\Content()\Element = @*this\Content()\Elements()
*this\Template()\Fields()\Content()\Content = @*this\Content()
Next
ForEach *this\TemplateLink()
If *this\TemplateLink()\FieldName.s = Str(TemplateID.i)
ChangeCurrentElement(*this\Template(),*this\TemplateLink()\Template)
ChangeCurrentElement(*this\Template()\Fields(),*this\TemplateLink()\Field)
If *this\Template()\Fields()\IsHolder
If *this\Template()\Fields()\Content()\Content And *this\Template()\Fields()\Content()\Element
ChangeCurrentElement(*this\Content(),*this\Template()\Fields()\Content()\Content)
ChangeCurrentElement(*this\Content()\Elements(),*this\Template()\Fields()\Content()\Element)
AddElement(*this\Content()\Elements()\SelfRef())
*this\Content()\Elements()\SelfRef() = *Content
EndIf
EndIf
Break
EndIf
Next
ProcedureReturn ContentID.i
EndIf
Break
EndIf
Next
EndIf
EndProcedure
Procedure.i EasyTemplate_SetContent(*this.easy_template,ContentID.i,Name.s,Value.s)
If *this
If ListSize(*this\Content()) And Name.s
ForEach *this\Content()
If *this\Content()\ContentID.i = ContentID.i
ChangeCurrentElement(*this\Template(),*this\Content()\Template)
ForEach *this\Content()\Elements()
If *this\Content()\Elements()\Field
ChangeCurrentElement(*this\Template()\Fields(),*this\Content()\Elements()\Field)
If *this\Template()\Fields()\Name.s = Name.s
*this\Content()\Elements()\Content.s = Value.s
ProcedureReturn #True
EndIf
EndIf
Next
EndIf
Next
EndIf
EndIf
EndProcedure
Procedure.s EasyTemplate_Build(*this.easy_template, TemplateID.i,*ContentRef = 0)
Protected Content.s,Replacer.s
Protected ValueHolder.s
Protected NewList *SelfRef(), *currContent, *currElement, *currField, *currTemplate
Protected ChildID.i
If Not *this
ProcedureReturn "ERROR!"
EndIf
If TemplateID.i And ListSize(*this\Template())
ForEach *this\Template()
If *this\Template()\ID.i = TemplateID.i
Content.s = *this\Template()\Content.s
If *ContentRef > 0
ChangeCurrentElement(*this\Content(),*ContentRef)
ForEach *this\Content()\Elements()
ChangeCurrentElement(*this\Template()\Fields(),*this\Content()\Elements()\Field)
If Not *this\Template()\Fields()\IsHolder.b
Replacer.s = "{tp:var:"+*this\Template()\Fields()\Name.s+"}"
ValueHolder.s = *this\Content()\Elements()\Content.s
Else
Replacer.s = "{tp:holder:"+*this\Template()\Fields()\Name.s+"}"
ChildID.i = Val(*this\Template()\Fields()\Name.s)
*currContent = @*this\Content()
*currElement = @*this\Content()\Elements()
CopyList(*this\Content()\Elements()\SelfRef(),*SelfRef())
ForEach *SelfRef()
ValueHolder.s + EasyTemplate_Build(*this,ChildID.i,*SelfRef())
Next
ChangeCurrentElement(*this\Content(),*currContent)
ChangeCurrentElement(*this\Content()\Elements(),*currElement)
EndIf
Content.s = ReplaceString(Content.s,Replacer.s,ValueHolder.s)
ValueHolder.s = ""
Next
ProcedureReturn Content.s
Else
ForEach *this\Template()\Fields()
If Not *this\Template()\Fields()\IsHolder.b
Replacer.s = "{tp:var:"+*this\Template()\Fields()\Name.s+"}"
ForEach *this\Template()\Fields()\Content()
ChangeCurrentElement(*this\Content(),*this\Template()\Fields()\Content()\Content)
ChangeCurrentElement(*this\Content()\Elements(),*this\Template()\Fields()\Content()\Element)
ValueHolder.s + *this\Content()\Elements()\Content.s
Next
Else
*currTemplate = *this\Template()
*currField = *this\Template()\Fields()
Replacer.s = "{tp:holder:"+*this\Template()\Fields()\Name.s+"}"
ChildID.i = Val(*this\Template()\Fields()\Name.s)
ForEach *this\Template()\Fields()\Content()
ChangeCurrentElement(*this\Content(),*this\Template()\Fields()\Content()\Content)
ChangeCurrentElement(*this\Content()\Elements(),*this\Template()\Fields()\Content()\Element)
CopyList(*this\Content()\Elements()\SelfRef(),*SelfRef())
ForEach *SelfRef()
ValueHolder.s + EasyTemplate_Build(*this,ChildID.i,*SelfRef())
Next
ChangeCurrentElement(*this\Template(),*currTemplate)
ChangeCurrentElement(*this\Template()\Fields(),*currField)
Next
EndIf
Content.s = ReplaceString(Content.s,Replacer.s,ValueHolder.s)
ValueHolder.s = ""
Next
EndIf
Break
EndIf
Next
EndIf
Debug Content.s
ProcedureReturn Content.s
EndProcedure
Procedure.i EasyTemplate_Destroy(*this.easy_template)
ClearStructure(*this,easy_template)
InitializeStructure(*this,easy_template)
Debug "destroyed all template information.."
EndProcedure
Procedure New_EasyTemplate()
Protected *this.easy_template
*this = AllocateMemory(SizeOf(easy_template))
If *this
InitializeStructure(*this, easy_template)
*this\___procs.i = ?__easy_template_int
EndIf
ProcedureReturn *this
EndProcedure
DataSection
__easy_template_int:
Data.i @EasyTemplate_AddField()
Data.i @EasyTemplate_RelinkFields()
Data.i @EasyTemplate_LoadString()
Data.i @EasyTemplate_LoadMemory()
Data.i @EasyTemplate_LoadFile()
Data.i @EasyTemplate_GetLoopID()
Data.i @EasyTemplate_AddContent()
Data.i @EasyTemplate_SetContent()
Data.i @EasyTemplate_Build()
Data.i @EasyTemplate_Destroy()
EndDataSection
DisableExplicit
;test
;____________________________________________________________________________________
Template.s = "This is a test template"+#CRLF$+#CRLF$
Template.s + "We can do Loops,{tp:loop:mylooptitle:start}"+#CRLF$
Template.s + "this is line {tp:var:mycountervar}"+#CRLF$
Template.s + "a loop in a loop too {tp:loop:myinnerloop:start}"+#CRLF$
Template.s + "{tp:var:innerloopcontent} {tp:loop:myinnerloop:end}"+#CRLF$
Template.s + "{tp:loop:mylooptitle:end}"+#CRLF$+#CRLF$
Template.s + "Today is: {tp:var:date}"
;create the template
*easy.EasyTemplate = New_EasyTemplate()
;load content
ID.i = *easy\LoadString(Template.s)
If ID.i
;we want to add content!
MainContentID.i = *easy\AddContent(ID.i)
If MainContentID.i
*easy\SetContent(MainContentID.i,"date",FormatDate("%mm/%dd/%yyyy", Date()))
EndIf
;get the loop ID's
MyLoop.i = *easy\GetLoopID(ID.i,"mylooptitle")
MyInnerLoop.i = *easy\GetLoopID(ID.i,"myinnerloop")
;fill the main loop "mylooptitle"
If MyLoop.i
For a=0 To 100
MyLoopContent.i = *easy\AddContent(MyLoop.i)
*easy\SetContent(MyLoopContent.i,"mycountervar",Str(a))
;fill the inner loop "myinnerloop"
For B=0 To 5
MyInnerLoopContent.i = *easy\AddContent(MyInnerLoop.i)
*easy\SetContent(MyInnerLoopContent.i,"innerloopcontent","Random Value: "+Str(Random(1000)))
Next
Next
EndIf
;let's build it!
Content.s = *easy\Build(ID.i)
;to much content for the (windows) debugger, let's save it to the clipboard
If Content.s
SetClipboardText(Content.s)
EndIf
*easy\Destroy()
EndIf
Deluxe0321