Hi,
Is there a kind of "template engine" in PB? Thinking of something like e.g. Jinja or similar. Essentially creating a HTML, TXT or other file where you put in variables to replace at runtime like "Hello {{name}}".
I'm currently not intending to use it for web purposes, but more for generating things like invoices or cue sheets etc.
Best,
Mat
Template engine?
Re: Template engine?
Simple way ...
Code: Select all
;-TOP
Global NewList Names.s()
Global Header.s = "Hello {{Name}}"
Global Titel.s
AddElement(Names())
Names() = "Tom"
AddElement(Names())
Names() = "Jerry"
ForEach Names()
Titel = ReplaceString(Header, "{{Name}}", Names())
Debug Titel
Next
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
Re: Template engine?
Thanks, that's definitely a way for simple use cases. The idea of the template engine would be to out logic I side of the template instead of the code - for simple replacement that here might be the way to go, but conditionals and loops In the template are the main thing I'm looking for.
From what I gather through translation, it seems to go in a similar direction as mk-softs suggestion, if the source is available it would be interesting, especially the docx part.
So as different example, such as template would be like (in Jinja)
Code: Select all
{% for item in collection %}
The item name is: {{item["name"]}}
The price is {{item["price"]}}
{% if item["price"] < 50 %}
Cheap item!
{% endif %}
{% endfor %}
Code: Select all
The item name is: Item A
The price is 150
The item name is: B
The price is 30
Cheap Item!
Re: Template engine?
Maybe write a template interpreter.
Here is a small starting point for an interpreter
Here is a small starting point for an interpreter
Code: Select all
;-TOP beginning by mk-soft
; ***************************************************************************************
; Part Of SplitStringArray.pbi
; Link: https://www.purebasic.fr/english/viewtopic.php?t=69557
Procedure SplitParameterArray(String.s, Array Result.s(1))
Protected *String.character
Protected *Start, *End, exit, lock, do, len, temp.s, cnt, c1
Protected level
Dim Result(0)
*String = @String
If *String = 0
ProcedureReturn 0
EndIf
*Start = *String
*End = *String
c1 = 0
Repeat
If *String\c = 0
exit = #True
*End = *String
Else
If *String\c = '"'
If Not lock
lock = #True
Else
lock = #False
EndIf
EndIf
If Not lock
If *String\c = '('
If level = 0
If #True ; Get Functionname
len = (*String - *Start) / SizeOf(character)
If Len > 0
temp = PeekS(*Start, len)
ReplaceString(temp, #TAB$, " ", #PB_String_InPlace)
temp = Trim(temp)
cnt = CountString(temp, " ")
If cnt
temp = StringField(temp, cnt + 1, " ")
EndIf
Result(c1) = temp
EndIf
EndIf
*Start = *String + SizeOf(character)
EndIf
level + 1
ElseIf *String\c = ')'
level - 1
If level = 0
do = #True
exit = #True
*End = *String
EndIf
ElseIf *String\c = ',' And level = 1
do = #True
*End = *String
EndIf
EndIf
EndIf
If do
c1 + 1
If ArraySize(Result()) < c1
ReDim Result(c1 + 10)
EndIf
len = (*End - *Start) / SizeOf(character)
If Len > 0
Result(c1) = Trim(PeekS(*Start, len))
Else
Result(c1) = ""
EndIf
*Start = *String + SizeOf(character)
do = #False
EndIf
*String + SizeOf(character)
Until exit
ReDim Result(c1)
ProcedureReturn c1
EndProcedure
; ***************************************************************************************
Structure udtCollection
CollectionName.s
Map itemText.s()
Map itemValue.d()
EndStructure
Global NewList Collection.udtCollection()
Procedure.s TemplateInterpreter(Text.s, *Collection.udtCollection)
Protected r1.s, pos1, pos2, temp.s, cnt
Dim param.s(0)
With *Collection
Repeat
pos1 = FindString(text, "{{")
If pos1
r1 + Left(text, pos1 - 1)
pos2 = FindString(text, "}}", pos1)
If pos2
temp = Mid(Text, pos1 + 2, pos2 - pos1 -2)
cnt = SplitParameterArray(temp, param())
If cnt >= 1
Select param(0)
Case "itemText"
If FindMapElement(\itemText(), param(1))
r1 + \itemText()
EndIf
Case "itemValue"
If FindMapElement(\itemValue(), param(1))
Select cnt
Case 1
r1 + StrD(\itemValue())
Case 2
r1 + StrD(\itemValue(), Val(param(2)))
EndSelect
EndIf
EndSelect
EndIf
Text = Mid(text, pos2 + 2)
EndIf
Else
r1 + text
Break
EndIf
ForEver
EndWith
ProcedureReturn r1
EndProcedure
; ----
;Test
AddElement(Collection())
With Collection()
\itemText("name") = "Apple"
\itemValue("price") = 13.99
EndWith
AddElement(Collection())
With Collection()
\itemText("name") = "bears"
\itemValue("price") = 9.80
EndWith
sVal.s = "The item name is: {{itemText(name)}} " + #LF$ +
"The price is {{itemValue(price,2)}}" + #LF$ + #LF$
ForEach Collection()
Debug TemplateInterpreter(sVal, Collection())
Next
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
Re: Template engine?
Thank you so much! So I'll take it that there is no (known) template engine available?
Then I'll try my hand at writing my own with your starting point (or try a different direction for the few projects I have in mind).
Thank you again