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?mk-soft wrote: Mon Jun 20, 2022 8:10 pm Maybe write a template interpreter.
Here is a small starting point for an interpreter
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
