module_templates.go 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. package modules
  2. import (
  3. "html"
  4. "io/ioutil"
  5. "net/url"
  6. "os"
  7. "path/filepath"
  8. "strings"
  9. "golang-fave/engine/assets"
  10. "golang-fave/engine/builder"
  11. "golang-fave/engine/consts"
  12. "golang-fave/engine/utils"
  13. "golang-fave/engine/wrapper"
  14. )
  15. func (this *Modules) templates_GetThemeFiles(wrap *wrapper.Wrapper) []string {
  16. var result []string
  17. files, err := ioutil.ReadDir(wrap.DTemplate)
  18. if err == nil {
  19. for _, file := range files {
  20. if len(file.Name()) > 0 && file.Name()[0] == '.' {
  21. continue
  22. }
  23. if len(file.Name()) > 0 && strings.ToLower(file.Name()) == "robots.txt" {
  24. continue
  25. }
  26. result = append(result, file.Name())
  27. }
  28. }
  29. return result
  30. }
  31. func (this *Modules) RegisterModule_Templates() *Module {
  32. return this.newModule(MInfo{
  33. Mount: "templates",
  34. Name: "Templates",
  35. Order: 802,
  36. System: true,
  37. Icon: assets.SysSvgIconView,
  38. Sub: &[]MISub{
  39. {Mount: "default", Name: "Template editor", Show: true, Icon: assets.SysSvgIconEdit},
  40. {Mount: "create", Name: "Add new template", Show: true, Icon: assets.SysSvgIconPlus},
  41. {Mount: "restore", Name: "Restore", Show: true, Icon: assets.SysSvgIconRestore},
  42. },
  43. }, nil, func(wrap *wrapper.Wrapper) (string, string, string) {
  44. content := ""
  45. sidebar := ""
  46. if wrap.CurrSubModule == "" || wrap.CurrSubModule == "default" {
  47. content += this.getBreadCrumbs(wrap, &[]consts.BreadCrumb{
  48. {Name: "Template editor"},
  49. })
  50. files := this.templates_GetThemeFiles(wrap)
  51. if len(files) > 0 {
  52. selected_file, _ := url.QueryUnescape(wrap.R.URL.Query().Get("file"))
  53. if !(selected_file != "" && utils.InArrayString(files, selected_file)) {
  54. selected_file = files[0]
  55. }
  56. list_of_system_files := ``
  57. list_of_user_files := ``
  58. for _, file := range files {
  59. selected := ""
  60. if file == selected_file {
  61. selected = " selected"
  62. }
  63. if wrap.IsSystemMountedTemplateFile(file) {
  64. list_of_system_files += `<option value="` + html.EscapeString(file) +
  65. `"` + selected + `>` + html.EscapeString(file) + `</option>`
  66. } else {
  67. list_of_user_files += `<option value="` + html.EscapeString(file) +
  68. `"` + selected + `>` + html.EscapeString(file) + `</option>`
  69. }
  70. }
  71. list_of_files := list_of_system_files
  72. if list_of_user_files != "" {
  73. list_of_files += `<option disabled>&mdash;</option>`
  74. list_of_files += list_of_user_files
  75. }
  76. fcont := []byte(``)
  77. fcont, _ = ioutil.ReadFile(wrap.DTemplate + string(os.PathSeparator) + selected_file)
  78. fext := filepath.Ext(selected_file)
  79. if len(fext) > 2 {
  80. fext = fext[1:]
  81. }
  82. content += builder.DataForm(wrap, []builder.DataFormField{
  83. {
  84. Kind: builder.DFKHidden,
  85. Name: "action",
  86. Value: "templates-edit-theme-file",
  87. },
  88. {
  89. Kind: builder.DFKText,
  90. Caption: "Theme file",
  91. Name: "file",
  92. Value: "0",
  93. CallBack: func(field *builder.DataFormField) string {
  94. buttons := ``
  95. if wrap.IsSystemMountedTemplateFile(selected_file) {
  96. buttons += `<button type="button" class="btn btn-success" onclick="return fave.ActionThemeFile('templates-restore-file','` + selected_file + `','Are you sure want to restore theme file?');" style="position:absolute;right:0;">Restore</button>`
  97. } else {
  98. buttons += `<button type="button" class="btn btn-danger" onclick="return fave.ActionThemeFile('templates-delete-file','` + selected_file + `','Are you sure want to delete theme file?');" style="position:absolute;right:0;">Delete</button>`
  99. }
  100. return `<div class="form-group n1">` +
  101. `<div class="row">` +
  102. `<div class="col-12">` +
  103. `<div style="position:relative;">` +
  104. buttons +
  105. `<select class="form-control ignore-lost-data" id="lbl_file" name="file" onchange="setTimeout(function(){$('#lbl_file').val('` + selected_file + `')},500);document.location='/cp/` + wrap.CurrModule + `/?file='+encodeURI(this.value);">` +
  106. list_of_files +
  107. `</select>` +
  108. `</div>` +
  109. `</div>` +
  110. `</div>` +
  111. `</div>`
  112. },
  113. },
  114. {
  115. Kind: builder.DFKText,
  116. CallBack: func(field *builder.DataFormField) string {
  117. return `<div class="form-group last"><div class="row"><div class="col-12"><textarea class="form-control tmpl-editor" name="content" data-emode="` + fext + `" placeholder="" autocomplete="off">` + html.EscapeString(string(fcont)) + `</textarea></div></div></div>`
  118. },
  119. },
  120. {
  121. Kind: builder.DFKSubmit,
  122. CallBack: func(field *builder.DataFormField) string {
  123. return `<div class="row d-lg-none"><div class="col-12"><div class="pt-3"><button type="submit" class="btn btn-primary" data-target="add-edit-button">Save</button></div></div></div>`
  124. },
  125. },
  126. })
  127. sidebar += `<button class="btn btn-primary btn-sidebar" id="add-edit-button">Save</button>`
  128. } else {
  129. content += `<div class="sys-messages">
  130. <div class="alert alert-warning" role="alert">
  131. <strong>Error!</strong> No any file found in theme folder
  132. </div>
  133. </div>`
  134. }
  135. } else if wrap.CurrSubModule == "create" {
  136. content += this.getBreadCrumbs(wrap, &[]consts.BreadCrumb{
  137. {Name: "Add new template"},
  138. })
  139. content += builder.DataForm(wrap, []builder.DataFormField{
  140. {
  141. Kind: builder.DFKHidden,
  142. Name: "action",
  143. Value: "templates-create-theme-file",
  144. },
  145. {
  146. Kind: builder.DFKText,
  147. Caption: "Theme file",
  148. Name: "file",
  149. Value: "0",
  150. CallBack: func(field *builder.DataFormField) string {
  151. return `<div class="form-group n1">` +
  152. `<div class="row">` +
  153. `<div class="col-12">` +
  154. `<div style="position:relative;">` +
  155. `<input class="form-control ignore-lost-data" type="text" id="lbl_name" name="name" value="" minlength="1" maxlength="250" placeholder="New template file name without extension" autocomplete="off" required>` +
  156. `</div>` +
  157. `</div>` +
  158. `</div>` +
  159. `</div>`
  160. },
  161. },
  162. {
  163. Kind: builder.DFKText,
  164. CallBack: func(field *builder.DataFormField) string {
  165. return `<div class="form-group last"><div class="row"><div class="col-12"><textarea class="form-control tmpl-editor" name="content" data-emode="html" placeholder="" autocomplete="off"></textarea></div></div></div>`
  166. },
  167. },
  168. {
  169. Kind: builder.DFKSubmit,
  170. CallBack: func(field *builder.DataFormField) string {
  171. return `<div class="row d-lg-none"><div class="col-12"><div class="pt-3"><button type="submit" class="btn btn-primary" data-target="add-edit-button">Save</button></div></div></div>`
  172. },
  173. },
  174. })
  175. sidebar += `<button class="btn btn-primary btn-sidebar" id="add-edit-button">Add</button>`
  176. } else if wrap.CurrSubModule == "restore" {
  177. content += this.getBreadCrumbs(wrap, &[]consts.BreadCrumb{
  178. {Name: "Restore"},
  179. })
  180. content += builder.DataForm(wrap, []builder.DataFormField{
  181. {
  182. Kind: builder.DFKText,
  183. CallBack: func(field *builder.DataFormField) string {
  184. return `<div class="form-group last"><div class="row"><div class="col-12"><div class="alert alert-danger" style="margin:0;"><strong>WARNING!</strong><br>This action will restore current theme files to original, you will lost you theme changes!<br>Think twice before run this action! If you still want to do this, please press <b>Restore</b> red button!</div></div></div></div>`
  185. },
  186. },
  187. {
  188. Kind: builder.DFKSubmit,
  189. CallBack: func(field *builder.DataFormField) string {
  190. return `<div class="row d-lg-none"><div class="col-12"><div class="pt-3"><button type="button" class="btn btn-danger" onclick="return fave.ActionThemeFile('templates-restore-file-all','all','WARNING! Are you sure want to restore all theme files?');">Restore</button></div></div></div>`
  191. },
  192. },
  193. })
  194. sidebar += `<button class="btn btn-danger btn-sidebar" onclick="return fave.ActionThemeFile('templates-restore-file-all','all','WARNING! Are you sure want to restore all theme files?');" id="add-edit-button">Restore</button>`
  195. }
  196. return this.getSidebarModules(wrap), content, sidebar
  197. })
  198. }