EXAMPLES
This section contains examples of how to use the GoERP template engine. The examples are divided into different categories based on the use case.
This section contains examples of how to use the GoERP template engine. The examples are divided into different categories based on the use case.
This example demonstrates how to create a 2-stage automation process.
data
to the
next stage.{{- $warehouses := .Data.AccountAdminApi.Api.Requests.getWarehouses.Response.Get "data.warehouses" -}}
{{- $wIds := mkStringArray }}
{
"postOperations": [
{{- range $i, $warehouse := $warehouses.Array -}}
{{- $wId := ($warehouse.Get "id").String -}}
{{if $i}},{{end}}{
"ErplyApi.Api.Post.getProductStock{{$i}}": "getProductStock",
"ErplyApi.Api.PostParam.getProductStock{{$i}}.warehouseID": "{{ $wId }}",
"ErplyApi.Api.PostParam.getProductStock{{$i}}.getSuggestedPurchasePrice": "1"
}
{{- $wIds = addToStringArray $wIds $wId -}}
{{ end }}
],
"stageTo": {
"name": "pg-aut2-automation",
"data": {"wids": {{ $wIds | toJson }}}
},
"enabled": true
}
{{- $wids := (.Data.Automation.Request.Get "wids").Array -}}
{{- if .Data.Automation.ParentRequests.ErplyApi -}}
{
"postOperations": [
{{- range $i, $wid := $wids -}}
{{- $whStockResponse := index $.Data.Automation.ParentRequests.ErplyApi (printf "getProductStock%d" $i) -}}
{{- $whStockWithNegativeAmounts := ($whStockResponse.Response.Get "records.#(amountInStock<0)#").Array -}}
{{- if not $whStockWithNegativeAmounts -}}
{{- continue -}}
{{- end -}}
{{if $i}},{{end}}{
"ErplyApi.Api.Post.newRegistraton{{$i}}": "saveInventoryRegistration",
"ErplyApi.Api.PostParam.newRegistraton{{$i}}.warehouseID": "{{ $wid }}",
{{- range $ii, $el := $whStockWithNegativeAmounts -}}
{{- $rowIndex := toInt (add $ii 1) -}}
{{- $rowAmount := ($el.Get "amountInStock").String -}}{{if $ii}},{{end}}
"ErplyApi.Api.PostParam.newRegistraton{{$i}}.productID{{$rowIndex}}": "{{$el.Get "productID"}}",
"ErplyApi.Api.PostParam.newRegistraton{{$i}}.amount{{$rowIndex}}": "{{ replace $rowAmount "-" "" 1 }}",
"ErplyApi.Api.PostParam.newRegistraton{{$i}}.price{{$rowIndex}}": "{{$el.Get "suggestedPurchasePrice"}}"
{{- end -}}
}
{{- end -}}
],
"enabled": true
}
{{- end -}}
There is no way to match multiple values in one run, but you can use the pipe |
operator to run
multiple searches in a row.
friends.#(first!=Dale)#|#(first!=Roger)#.last
// Result: ["Murphy","Smith"]
In template code:
{{ $res.Get "friends.#(first!=Dale)#|#(first!=Roger)#.last" }}
// With more pipes:
{{ $res.Get "friends.#(first!=Dale)#|#(first!=Roger)#.last|@unique|@commaSepStr" }}
// Result: "Murphy,Smith"
While chaining requests:
<input
type="hidden"
name="CustomApi.Api.Query.req2.<-names"
data-preset-val="req1.Response.friends.#(first!=Dale)#|#(first!=Roger)#.last|@unique|@commaSepStr">
{
"name": {
"first": "Tom",
"last": "Anderson"
},
"age": 37,
"children": [
"Sara",
"Alex",
"Jack"
],
"fav.movie": "Deer Hunter",
"friends": [
{
"first": "Dale",
"last": "Murphy",
"age": 44,
"nets": [
"ig",
"fb",
"tw"
]
},
{
"first": "Roger",
"last": "Craig",
"age": 68,
"nets": [
"fb",
"tw"
]
},
{
"first": "Jane",
"last": "Murphy",
"age": 47,
"nets": [
"fb",
"ig"
]
},
{
"first": "John",
"last": "Smith",
"age": 49,
"nets": [
"tw"
]
}
]
}
The regular way exposes all fields to the template - this means anyone can alter the field contents before its being sent. This allows the area to be used for possible phishing attacks.
The best way to hide the fields is to move all functional fields away from the template (in this case into an automation) These automation fields are never exposed to the public and cannot be intercepted.
The following example contains 3 templates:
In this example we only render the form when nothing is sent, we also never expose the automation trigger to the template, thus a user cannot even alter its execution.
We use the input here to trigger the automation, and the only value that is being passed to the e-mailer.
<h1>Secure emailer</h1>
<p>Email from public/b2b without exposing the fields for editing</p>
<!-- Optional, we render the form only once and display a message once its already sent -->
{{ if .Data.Parameters.inputEmailField }}
{{ .Tools.AutomationEvent "check-emailer-automation" (jsonSet `{}` "email" .Data.Parameters.inputEmailField) }}
<h2>Thanks!</h2>
{{ else }}
<h2>Send me something</h2>
<form method="post">
<label for="email">Add your email</label>
<input type="string" id="email" name="inputEmailField">
<button type="submit">Send</button>
</form>
{{ end }}
{{ .Data.Parameters.inputEmailField }}
We read the email from the passed data and use it as the email, rest is hardcoded into the automation. Here we also encode an optional template to the email body.
{
"postOperations": [
{
"EMSApi.SendEmailInput.To": "{{ .Data.Automation.Request.Get "email" }}",
"EMSApi.SendEmailInput.Subject": "Secure emailer demo",
"EMSApi.SendEmailInput.ContentType": "html",
"EMSApi.SendEmailInput.Content": "<encode>{{ .Tools.ExecTemplate "check-done-page" }}</encode>",
"EMSApi.SendEmailInput.IsEncoded": "true"
}
],
"enabled": true
}
The content that will be in the email.
<h1>Thanks! email received</h1>
callTemplate
feature{{- $combinedData := mkAnyMap -}}
{{- $perPage := "10" -}}
{{- $topicId := "topic-test-case-1" -}}
{{- $pageNo := 0 -}}
{{- range $i := in 1 50 -}}
{{- $pageNo = add $pageNo 1 -}}
{{- $resp := $.Tools.CallTemplate "pg-paginated-call-script-page" (mkAnyMap "topicId" $topicId "recordsOnPage" $perPage "pageNo" $pageNo) -}}
{{- $respObj := jsonResult $resp "" -}}
{{- if eq ($respObj.Get "status").String "OK" -}}
{{- range $r := ($respObj.Get "records").Array -}}
{{- $combinedData = setAnyMapValue $combinedData ($r.Get "batchId").String ($r.Get "entries.#").Int -}}
{{- end -}}
{{- else -}}
Failure: {{ $respObj.Get "status" }}
{{- end -}}
{{- if not ($respObj.Get "hasMore").Bool -}}
{{- $combinedData = setAnyMapValue $combinedData "totalPages" $pageNo -}}
{{- break -}}
{{- end -}}
{{- end -}}
{{ $combinedData | toJson }}
{{- $res := .Data.KvsApi.Api.Requests.entryBatch -}}
{{- $sc := $res.ResponseHttpCode -}}
{{- $arr := ($res.Response.Get "data").Array -}}
{{- $perPageCount := .Data.Parameters.recordsOnPage | toInt -}}
{
"status": "{{if $sc}}{{if gt $sc 204}}{{ $res.Response.Raw }}{{ else }}OK{{ end }}{{else}}No response from API{{end}}",
"hasMore": {{if and $arr (eq (len $arr) $perPageCount)}}true{{else}}false{{end}},
"records": [
{{- range $i, $el := $arr -}}
{{if $i}},{{end}}
{
"batchId": "{{$el.Get "batchId"}}",
"entries": [{{range $j, $e := ($el.Get "entries").Array}}{{if $j}},{{end}}"{{$e.Get "key"}}->{{$e.Get "value"}}"{{end}}]
}
{{- end -}}
]
}
Method to be used where we would use a separate account to create a new erply account. And then we would like the user to navigate to the created account without showing the default erply login.
Note that there are multiple workflows this can be used for:
Since both run on the same domain then it’s enough to just run erply createInstallation. The process there will automatically set the auth cookie for the created account to the browser and since we are on the same domain then browser will automatically use it when we navigate to the created account.
<form type="post">
<input type="hidden" name="ErplyApi.Api.Post.createInstallation" value="createInstallation">
<!-- Required form fields would be here -->
<input type="text" name="ErplyApi.Api.PostParam.createInstallation.username"
value="15">
<input type="text" name="ErplyApi.Api.PostParam.createInstallation.password"
value="15">
<!-- Depending on what cluster the main account is the target url might need to be adjusted -->
<input type="hidden" name="Form.Redirect" value="https://template-engine-eu10.erply.com/[[ .Data.ErplyApi.Api.Requests.createInstallation.Response.Get `records.0.clientCode` ]]/en/store">
</form>
Available from goerp version 1.314.0
In cases where the main app is on a different custom domain. In these case we cannot set cross domain cookies. Instead, we can pass the session key in the query parameter, goerp will take care of the session creation itself.
<form type="post">
<input type="hidden" name="ErplyApi.Api.Post.createInstallation" value="createInstallation">
<!-- Required form fields would be here -->
<input type="text" name="ErplyApi.Api.PostParam.createInstallation.username"
value="15">
<input type="text" name="ErplyApi.Api.PostParam.createInstallation.password"
value="15">
<!-- Depending on what cluster the main account is the target url might need to be adjusted -->
<input type="hidden" name="Form.Redirect" value="https://template-engine-eu10.erply.com/[[ .Data.ErplyApi.Api.Requests.createInstallation.Response.Get `records.0.clientCode` ]]/en/store?authKey=[[ .Data.ErplyApi.Api.Requests.createInstallation.Response.Get `records.0.sessionKey` ]]">
</form>
By default, accounts do not have any goerp applications installed. If we need to navigate to a new application then we would need to set the application up to auto install.
Requirements:
Also note that passing the key is only needed if we want to navigate the user to a bo user view. If the user is to be navigated to a public page view then there is no need to pass the auth key.