mirror of
https://github.com/abhinavxd/libredesk.git
synced 2025-10-23 05:11:57 +00:00
feat: add i18n support to web templates
- Add i18n object to template funcMap for direct access - Translate all hardcoded strings in CSAT and footer templates - Add reusable translation keys to globals.messages
This commit is contained in:
20
cmd/csat.go
20
cmd/csat.go
@@ -17,7 +17,7 @@ func handleShowCSAT(r *fastglue.Request) error {
|
||||
if err != nil {
|
||||
return app.tmpl.RenderWebPage(r.RequestCtx, "error", map[string]interface{}{
|
||||
"Data": map[string]interface{}{
|
||||
"ErrorMessage": "Page not found",
|
||||
"ErrorMessage": app.i18n.T("globals.messages.pageNotFound"),
|
||||
},
|
||||
})
|
||||
}
|
||||
@@ -25,8 +25,8 @@ func handleShowCSAT(r *fastglue.Request) error {
|
||||
if csat.ResponseTimestamp.Valid {
|
||||
return app.tmpl.RenderWebPage(r.RequestCtx, "info", map[string]interface{}{
|
||||
"Data": map[string]interface{}{
|
||||
"Title": "Thank you!",
|
||||
"Message": "We appreciate you taking the time to submit your feedback.",
|
||||
"Title": app.i18n.T("globals.messages.thankYou"),
|
||||
"Message": app.i18n.T("csat.thankYouMessage"),
|
||||
},
|
||||
})
|
||||
}
|
||||
@@ -35,14 +35,14 @@ func handleShowCSAT(r *fastglue.Request) error {
|
||||
if err != nil {
|
||||
return app.tmpl.RenderWebPage(r.RequestCtx, "error", map[string]interface{}{
|
||||
"Data": map[string]interface{}{
|
||||
"ErrorMessage": "Page not found",
|
||||
"ErrorMessage": app.i18n.T("globals.messages.pageNotFound"),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
return app.tmpl.RenderWebPage(r.RequestCtx, "csat", map[string]interface{}{
|
||||
"Data": map[string]interface{}{
|
||||
"Title": "Rate your interaction with us",
|
||||
"Title": app.i18n.T("csat.pageTitle"),
|
||||
"CSAT": map[string]interface{}{
|
||||
"UUID": csat.UUID,
|
||||
},
|
||||
@@ -67,7 +67,7 @@ func handleUpdateCSATResponse(r *fastglue.Request) error {
|
||||
if err != nil {
|
||||
return app.tmpl.RenderWebPage(r.RequestCtx, "error", map[string]interface{}{
|
||||
"Data": map[string]interface{}{
|
||||
"ErrorMessage": "Invalid `rating`",
|
||||
"ErrorMessage": app.i18n.T("globals.messages.somethingWentWrong"),
|
||||
},
|
||||
})
|
||||
}
|
||||
@@ -75,7 +75,7 @@ func handleUpdateCSATResponse(r *fastglue.Request) error {
|
||||
if ratingI < 1 || ratingI > 5 {
|
||||
return app.tmpl.RenderWebPage(r.RequestCtx, "error", map[string]interface{}{
|
||||
"Data": map[string]interface{}{
|
||||
"ErrorMessage": "Invalid `rating`",
|
||||
"ErrorMessage": app.i18n.T("globals.messages.somethingWentWrong"),
|
||||
},
|
||||
})
|
||||
}
|
||||
@@ -83,7 +83,7 @@ func handleUpdateCSATResponse(r *fastglue.Request) error {
|
||||
if uuid == "" {
|
||||
return app.tmpl.RenderWebPage(r.RequestCtx, "error", map[string]interface{}{
|
||||
"Data": map[string]interface{}{
|
||||
"ErrorMessage": "Invalid `uuid`",
|
||||
"ErrorMessage": app.i18n.T("globals.messages.somethingWentWrong"),
|
||||
},
|
||||
})
|
||||
}
|
||||
@@ -98,8 +98,8 @@ func handleUpdateCSATResponse(r *fastglue.Request) error {
|
||||
|
||||
return app.tmpl.RenderWebPage(r.RequestCtx, "info", map[string]interface{}{
|
||||
"Data": map[string]interface{}{
|
||||
"Title": "Thank you!",
|
||||
"Message": "We appreciate you taking the time to submit your feedback.",
|
||||
"Title": app.i18n.T("csat.thankYou"),
|
||||
"Message": app.i18n.T("csat.thankYouMessage"),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
@@ -329,7 +329,7 @@ func initWS(user *user.Manager) *ws.Hub {
|
||||
func initTemplate(db *sqlx.DB, fs stuffbin.FileSystem, consts *constants, i18n *i18n.I18n) *tmpl.Manager {
|
||||
var (
|
||||
lo = initLogger("template")
|
||||
funcMap = getTmplFuncs(consts)
|
||||
funcMap = getTmplFuncs(consts, i18n)
|
||||
)
|
||||
tpls, err := stuffbin.ParseTemplatesGlob(funcMap, fs, "/static/email-templates/*.html")
|
||||
if err != nil {
|
||||
@@ -347,7 +347,7 @@ func initTemplate(db *sqlx.DB, fs stuffbin.FileSystem, consts *constants, i18n *
|
||||
}
|
||||
|
||||
// getTmplFuncs returns the template functions.
|
||||
func getTmplFuncs(consts *constants) template.FuncMap {
|
||||
func getTmplFuncs(consts *constants, i18n *i18n.I18n) template.FuncMap {
|
||||
return template.FuncMap{
|
||||
"RootURL": func() string {
|
||||
return consts.AppBaseURL
|
||||
@@ -367,6 +367,7 @@ func getTmplFuncs(consts *constants) template.FuncMap {
|
||||
"SiteName": func() string {
|
||||
return consts.SiteName
|
||||
},
|
||||
"i18n": i18n,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -395,7 +396,7 @@ func reloadSettings(app *App) error {
|
||||
// reloadTemplates reloads the templates from the filesystem.
|
||||
func reloadTemplates(app *App) error {
|
||||
app.lo.Info("reloading templates")
|
||||
funcMap := getTmplFuncs(app.consts.Load().(*constants))
|
||||
funcMap := getTmplFuncs(app.consts.Load().(*constants), app.i18n)
|
||||
tpls, err := stuffbin.ParseTemplatesGlob(funcMap, app.fs, "/static/email-templates/*.html")
|
||||
if err != nil {
|
||||
app.lo.Error("error parsing email templates", "error", err)
|
||||
|
14
i18n/en.json
14
i18n/en.json
@@ -307,6 +307,12 @@
|
||||
"globals.messages.reset": "Reset {name}",
|
||||
"globals.messages.lastNItems": "Last {n} {name} | Last {n} {name}",
|
||||
"globals.messages.correctEmailErrors": "Please correct the email errors",
|
||||
"globals.messages.additionalFeedback": "Additional feedback (optional)",
|
||||
"globals.messages.pleaseSelect": "Please select {name} before submitting",
|
||||
"globals.messages.poweredBy": "Powered by",
|
||||
"globals.messages.thankYou": "Thank you!",
|
||||
"globals.messages.pageNotFound": "Page not found",
|
||||
"globals.messages.somethingWentWrong": "Something went wrong",
|
||||
"form.error.min": "Must be at least {min} characters",
|
||||
"form.error.max": "Must be at most {max} characters",
|
||||
"form.error.minmax": "Must be between {min} and {max} characters",
|
||||
@@ -340,6 +346,14 @@
|
||||
"conversationStatus.alreadyInUse": "Cannot delete status as it is in use, Please remove this status from all conversations before deleting",
|
||||
"conversationStatus.cannotUpdateDefault": "Cannot update default conversation status",
|
||||
"csat.alreadySubmitted": "CSAT already submitted",
|
||||
"csat.rateYourInteraction": "Rate your recent interaction",
|
||||
"csat.rating.poor": "Poor",
|
||||
"csat.rating.fair": "Fair",
|
||||
"csat.rating.good": "Good",
|
||||
"csat.rating.great": "Great",
|
||||
"csat.rating.excellent": "Excellent",
|
||||
"csat.pageTitle": "Rate your interaction with us",
|
||||
"csat.thankYouMessage": "We appreciate you taking the time to submit your feedback.",
|
||||
"auth.csrfTokenMismatch": "CSRF token mismatch",
|
||||
"auth.invalidOrExpiredSession": "Invalid or expired session",
|
||||
"auth.invalidOrExpiredSessionClearCookie": "Invalid or expired session. Please clear your cookies and try again.",
|
||||
|
@@ -5,7 +5,7 @@
|
||||
{{ if ne SiteName "" }}
|
||||
Welcome to {{ SiteName }}
|
||||
{{ else }}
|
||||
Welcome
|
||||
Welcome to Libredesk
|
||||
{{ end }}
|
||||
</h1>
|
||||
|
||||
|
@@ -2,7 +2,7 @@
|
||||
{{ template "header" . }}
|
||||
<div class="csat-container">
|
||||
<div class="csat-header">
|
||||
<h2>Rate your recent interaction</h2>
|
||||
<h2>{{ i18n.T "csat.rateYourInteraction" }}</h2>
|
||||
{{ if .Data.Conversation.Subject }}
|
||||
<p class="conversation-subject"><i>{{ .Data.Conversation.Subject }}</i></p>
|
||||
{{ end }}
|
||||
@@ -16,7 +16,7 @@
|
||||
<div class="emoji-wrapper">
|
||||
<span class="emoji">😢</span>
|
||||
</div>
|
||||
<span class="rating-text">Poor</span>
|
||||
<span class="rating-text">{{ i18n.T "csat.rating.poor" }}</span>
|
||||
</label>
|
||||
|
||||
<input type="radio" id="rating-2" name="rating" value="2">
|
||||
@@ -24,7 +24,7 @@
|
||||
<div class="emoji-wrapper">
|
||||
<span class="emoji">😕</span>
|
||||
</div>
|
||||
<span class="rating-text">Fair</span>
|
||||
<span class="rating-text">{{ i18n.T "csat.rating.fair" }}</span>
|
||||
</label>
|
||||
|
||||
<input type="radio" id="rating-3" name="rating" value="3">
|
||||
@@ -32,7 +32,7 @@
|
||||
<div class="emoji-wrapper">
|
||||
<span class="emoji">😊</span>
|
||||
</div>
|
||||
<span class="rating-text">Good</span>
|
||||
<span class="rating-text">{{ i18n.T "csat.rating.good" }}</span>
|
||||
</label>
|
||||
|
||||
<input type="radio" id="rating-4" name="rating" value="4">
|
||||
@@ -40,7 +40,7 @@
|
||||
<div class="emoji-wrapper">
|
||||
<span class="emoji">😃</span>
|
||||
</div>
|
||||
<span class="rating-text">Great</span>
|
||||
<span class="rating-text">{{ i18n.T "csat.rating.great" }}</span>
|
||||
</label>
|
||||
|
||||
<input type="radio" id="rating-5" name="rating" value="5">
|
||||
@@ -48,18 +48,18 @@
|
||||
<div class="emoji-wrapper">
|
||||
<span class="emoji">🤩</span>
|
||||
</div>
|
||||
<span class="rating-text">Excellent</span>
|
||||
<span class="rating-text">{{ i18n.T "csat.rating.excellent" }}</span>
|
||||
</label>
|
||||
</div>
|
||||
<!-- Validation message for rating -->
|
||||
<div class="validation-message" id="ratingValidationMessage"
|
||||
style="display: none; color: #dc2626; text-align: center; margin-top: 10px; font-size: 0.9em;">
|
||||
Please select a rating before submitting.
|
||||
{{ i18n.Ts "globals.messages.pleaseSelect" "name" "rating" }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="feedback-container">
|
||||
<label for="feedback" class="feedback-label">Additional feedback (optional)</label>
|
||||
<label for="feedback" class="feedback-label">{{ i18n.T "globals.messages.additionalFeedback" }}</label>
|
||||
<textarea id="feedback" name="feedback" placeholder="" rows="6" maxlength="1000"
|
||||
onkeyup="updateCharCount(this)"></textarea>
|
||||
<div class="char-counter">
|
||||
@@ -67,7 +67,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button type="submit" class="button submit-button">Submit</button>
|
||||
<button type="submit" class="button submit-button">{{ i18n.T "globals.messages.submit" }}</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
|
@@ -31,7 +31,7 @@
|
||||
{{ define "footer" }}
|
||||
</div>
|
||||
<footer class="container">
|
||||
Powered by <a target="_blank" rel="noreferrer" href="https://libredesk.io/">Libredesk</a>
|
||||
{{ i18n.T "globals.messages.poweredBy" }} <a target="_blank" rel="noreferrer" href="https://libredesk.io/">Libredesk</a>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
|
Reference in New Issue
Block a user