genmessage is a message generator to easy translate your Go application.
you only have to fill the messages.toml
file.
Installation
go install github.com/zakaria-chahboun/genmessage
Usage
You have to create a messages.toml
file, example:
# messages.toml file
[[Messages]]
Code = "err_user_access_denied"
Status = "danger"
[Messages.Templates]
english = "Incorrect Username or Password! Try again."
arabic = "إسم المستخدم أو كلمة المرور غير صحيحة! حاول من جديد."
[[Messages]]
Code = "last_date_bill_pay"
Status = "info"
Variables = {date="datetime"}
[Messages.Templates]
english = "The last date for paying bills is {date}."
arabic = "آخر أجل لتستديد الفواتير هو {date}"
[[Messages]]
Code = "err_stock_limit_exceeded"
Status = "warning"
Variables = {name="string", quantity="int"}
[Messages.Templates]
english = "Stock limit exceeded! Only {quantity} left in stock {name}."
arabic = "تم تجاوز حد المخزون! لم يتبقى سوى {quantity} من مخزون {name}."
or just create it by -init
tag
genmessage -init
Generate go file
# you will export "messages.go" by default
genmessage
# or export a custom file name: e.g "name.go"
genmessage -export name
The result will be like that:
package messages
import (
"fmt"
"time"
)
type Message struct {
Code string
Status string
Message string
}
/* new type */
type lang string
/* to store locally the currect languege used in app */
var currectLang lang
/* to set the currect languege used in app */
func SetCurrectLang(languege lang) {
currectLang = languege
}
/* enum: Message.Code */
const (
ErrUserAccessDenied = "err_user_access_denied"
LastDateBillPay = "last_date_bill_pay"
ErrStockLimitExceeded = "err_stock_limit_exceeded"
)
/* enum: Message.Status */
const (
StatusDanger = "danger"
StatusInfo = "info"
StatusWarning = "warning"
)
/* enum: Message.Templates.{lang} */
const (
LangEnglish lang = "english"
LangArabic lang = "arabic"
)
func CreateErrUserAccessDenied() (m *Message) {
m = &Message{}
m.Code = ErrUserAccessDenied
m.Status = StatusDanger
switch string(currectLang) {
case "arabic":
m.Message = fmt.Sprintf("إسم المستخدم أو كلمة المرور غير صحيحة! حاول من جديد.")
case "english":
m.Message = fmt.Sprintf("Incorrect Username or Password! Try again.")
}
return
}
func CreateLastDateBillPay(
date time.Time,
) (m *Message) {
m = &Message{}
m.Code = LastDateBillPay
m.Status = StatusInfo
switch string(currectLang) {
case "arabic":
m.Message = fmt.Sprintf("آخر أجل لتستديد الفواتير هو %v", date.Format("2006-01-02 15:04:05"))
case "english":
m.Message = fmt.Sprintf("The last date for paying bills is %v.", date.Format("2006-01-02 15:04:05"))
}
return
}
func CreateErrStockLimitExceeded(
name string,
quantity int,
) (m *Message) {
m = &Message{}
m.Code = ErrStockLimitExceeded
m.Status = StatusWarning
switch string(currectLang) {
case "arabic":
m.Message = fmt.Sprintf("تم تجاوز حد المخزون! لم يتبقى سوى %d من مخزون %s.", quantity, name)
case "english":
m.Message = fmt.Sprintf("Stock limit exceeded! Only %d left in stock %s.", quantity, name)
}
return
}
In error case, You will have a pretty cool message:
Fields
- Required fields:
Code
,[Messages.Templates]
- Optional fields:
Status
,Variables
In [Messages.Templates]
there is no rule to create the name of languages. You can write any field name you want:
[Messages.Templates]
english = "...."
arabic = "...."
#or
[Messages.Templates]
en = "...."
ar = "...."
#or
[Messages.Templates]
anglais = "...."
arabe = "...."
#or 😁
[Messages.Templates]
blabla1 = "...."
blabla2 = "...."
But the languages fields must be identical in all messages.
Variables and Types
You can add Variables
in your message, These types are allowed:
int
, float
, string
, date
, time
, datetime
Of course you can add these variables as paramaters in the message. You can call a variables many times in the message:
[[Messages]]
Code = "test"
Variables = {name="string"}
[Messages.Templates]
en = "My name is {name}, Can you call me {name} 👀?"
Use the message as an error
You can use these message as errors. Just add another go file in the same location. e.g errors.go
:
package messages
func (this *Message) Error() string {
return this.Code + " : " + this.Message
}
Now you can easily return it like error:
package main
import (
"fmt"
"your-module/messages"
)
init () {
messages.SetCurrectLang(messages.LangEnglish)
}
func main() {
err := login("horaa","123456")
if err != nil {
fmt.Println(err)
}
}
func login(name, pass string) error {
// a way of login
// ....
// error case
return CreateErrUserAccessDenied()
}