diff --git a/layout/example.yml b/layout/example.yml index 7f425900..a21ff523 100644 --- a/layout/example.yml +++ b/layout/example.yml @@ -6,6 +6,7 @@ settings: commands: /start: Start the bot /help: How to use the bot + /settings: "{{ text `cmd_settings` }}" config: str: string diff --git a/layout/layout.go b/layout/layout.go index 6d5df00e..6e55e551 100644 --- a/layout/layout.go +++ b/layout/layout.go @@ -6,7 +6,6 @@ import ( "io/fs" "log" "os" - "strings" "sync" "text/template" @@ -23,7 +22,7 @@ type ( ctxs map[tele.Context]string funcs template.FuncMap - commands map[string]string + commands []tele.Command buttons map[string]Button markups map[string]Markup results map[string]Result @@ -174,19 +173,16 @@ func (lt *Layout) SetLocale(c tele.Context, locale string) { lt.mu.Unlock() } -// Commands returns a list of telebot commands, which can be +// Commands returns a list of telebot commands +// in the order they were defined in config, which can be // used in b.SetCommands later. +// "commands" must be not templates func (lt *Layout) Commands() (cmds []tele.Command) { - for k, v := range lt.commands { - cmds = append(cmds, tele.Command{ - Text: strings.TrimLeft(k, "/"), - Description: v, - }) - } - return + return lt.commands } -// CommandsLocale returns a list of telebot commands and localized description, which can be +// CommandsLocale returns a list of telebot commands and localized descriptions +// in the order they were defined in config, which can be // used in b.SetCommands later. // // Example of bot.yml: @@ -206,14 +202,16 @@ func (lt *Layout) Commands() (cmds []tele.Command) { // // b.SetCommands(lt.CommandsLocale("en"), "en") // b.SetCommands(lt.CommandsLocale("ru"), "ru") +// b.SetCommands(lt.CommandsLocale("en")) func (lt *Layout) CommandsLocale(locale string, args ...interface{}) (cmds []tele.Command) { var arg interface{} if len(args) > 0 { arg = args[0] } - for k, v := range lt.commands { - tmpl, err := lt.template(template.New(k).Funcs(lt.funcs), locale).Parse(v) + for _, cmd := range lt.commands { + tmpl, err := lt.template(template.New(cmd.Text).Funcs(lt.funcs), locale). + Parse(cmd.Description) if err != nil { log.Println("telebot/layout:", err) return nil @@ -226,7 +224,7 @@ func (lt *Layout) CommandsLocale(locale string, args ...interface{}) (cmds []tel } cmds = append(cmds, tele.Command{ - Text: strings.TrimLeft(k, "/"), + Text: cmd.Text, Description: buf.String(), }) } diff --git a/layout/layout_test.go b/layout/layout_test.go index 29f27f56..ad05804d 100644 --- a/layout/layout_test.go +++ b/layout/layout_test.go @@ -32,13 +32,26 @@ func TestLayout(t *testing.T) { assert.Equal(t, &tele.LongPoller{}, pref.Poller) assert.Equal(t, pref, ltfs.Settings()) - assert.ElementsMatch(t, []tele.Command{{ + assert.Equal(t, []tele.Command{{ Text: "start", Description: "Start the bot", }, { Text: "help", Description: "How to use the bot", + }, { + Text: "settings", + Description: "{{ text `cmd_settings` }}", }}, lt.Commands()) + assert.Equal(t, []tele.Command{{ + Text: "start", + Description: "Start the bot", + }, { + Text: "help", + Description: "How to use the bot", + }, { + Text: "settings", + Description: "Settings", + }}, lt.CommandsLocale("en")) assert.Equal(t, "string", lt.String("str")) assert.Equal(t, 123, lt.Int("num")) diff --git a/layout/locales/en.yml b/layout/locales/en.yml index 21f0b5cb..a4080d78 100644 --- a/layout/locales/en.yml +++ b/layout/locales/en.yml @@ -6,3 +6,5 @@ nested: another: example: |- This is {{ . }}. + +cmd_settings: Settings diff --git a/layout/parser.go b/layout/parser.go index f973e1db..c40cb271 100644 --- a/layout/parser.go +++ b/layout/parser.go @@ -30,7 +30,7 @@ func (lt *Layout) UnmarshalYAML(data []byte) error { var aux struct { Settings *Settings Config map[string]interface{} - Commands map[string]string + Commands yaml.MapSlice Buttons yaml.MapSlice Markups yaml.MapSlice Results yaml.MapSlice @@ -46,7 +46,22 @@ func (lt *Layout) UnmarshalYAML(data []byte) error { } lt.Config = Config{v: v} - lt.commands = aux.Commands + lt.commands = make([]tele.Command, 0, len(aux.Commands)) + for _, cmd := range aux.Commands { + var ( + text string + description string + ok bool + ) + + if text, ok = cmd.Key.(string); !ok { + continue + } + if description, ok = cmd.Value.(string); !ok { + continue + } + lt.commands = append(lt.commands, tele.Command{Text: strings.TrimLeft(text, "/"), Description: description}) + } if pref := aux.Settings; pref != nil { lt.pref = &tele.Settings{