module_index.go 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363
  1. package modules
  2. import (
  3. "html"
  4. "net/http"
  5. "golang-fave/engine/assets"
  6. "golang-fave/engine/builder"
  7. "golang-fave/engine/consts"
  8. "golang-fave/engine/fetdata"
  9. "golang-fave/engine/utils"
  10. "golang-fave/engine/wrapper"
  11. )
  12. func (this *Modules) index_GetTemplateSelectOptions(wrap *wrapper.Wrapper, template string) string {
  13. result := ``
  14. selected := ""
  15. // index.html
  16. if template == "index" {
  17. selected = " selected"
  18. }
  19. result += `<option title="index.html" value="index"` + selected + `>index.html</option>`
  20. selected = ""
  21. // page.html
  22. if template == "" || template == "page" {
  23. selected = " selected"
  24. }
  25. result += `<option title="page.html" value="page"` + selected + `>page.html</option>`
  26. selected = ""
  27. return result
  28. }
  29. func (this *Modules) RegisterModule_Index() *Module {
  30. return this.newModule(MInfo{
  31. Mount: "index",
  32. Name: "Pages",
  33. Order: 0,
  34. Icon: assets.SysSvgIconPage,
  35. Sub: &[]MISub{
  36. {Mount: "default", Name: "List of pages", Show: true, Icon: assets.SysSvgIconList},
  37. {Mount: "add", Name: "Add new page", Show: true, Icon: assets.SysSvgIconPlus},
  38. {Mount: "modify", Name: "Modify page", Show: false},
  39. },
  40. }, func(wrap *wrapper.Wrapper) {
  41. // Front-end
  42. row := &utils.MySql_page{}
  43. rou := &utils.MySql_user{}
  44. err := wrap.DB.QueryRow(
  45. wrap.R.Context(),
  46. `SELECT
  47. fave_pages.id,
  48. fave_pages.user,
  49. fave_pages.template,
  50. fave_pages.name,
  51. fave_pages.alias,
  52. fave_pages.content,
  53. fave_pages.meta_title,
  54. fave_pages.meta_keywords,
  55. fave_pages.meta_description,
  56. UNIX_TIMESTAMP(fave_pages.datetime) as datetime,
  57. fave_pages.active,
  58. fave_users.id,
  59. fave_users.first_name,
  60. fave_users.last_name,
  61. fave_users.email,
  62. fave_users.admin,
  63. fave_users.active
  64. FROM
  65. fave_pages
  66. LEFT JOIN fave_users ON fave_users.id = fave_pages.user
  67. WHERE
  68. fave_pages.active = 1 and
  69. fave_pages.alias = ?
  70. LIMIT 1;`,
  71. wrap.R.URL.Path,
  72. ).Scan(
  73. &row.A_id,
  74. &row.A_user,
  75. &row.A_template,
  76. &row.A_name,
  77. &row.A_alias,
  78. &row.A_content,
  79. &row.A_meta_title,
  80. &row.A_meta_keywords,
  81. &row.A_meta_description,
  82. &row.A_datetime,
  83. &row.A_active,
  84. &rou.A_id,
  85. &rou.A_first_name,
  86. &rou.A_last_name,
  87. &rou.A_email,
  88. &rou.A_admin,
  89. &rou.A_active,
  90. )
  91. if err != nil && err != wrapper.ErrNoRows {
  92. // System error 500
  93. wrap.LogCpError(&err)
  94. utils.SystemErrorPageEngine(wrap.W, err)
  95. return
  96. } else if err == wrapper.ErrNoRows {
  97. // User error 404 page
  98. wrap.RenderFrontEnd("404", fetdata.New(wrap, true, nil, nil), http.StatusNotFound)
  99. return
  100. }
  101. // Render template
  102. wrap.RenderFrontEnd(row.A_template, fetdata.New(wrap, false, row, rou), http.StatusOK)
  103. }, func(wrap *wrapper.Wrapper) (string, string, string) {
  104. content := ""
  105. sidebar := ""
  106. if wrap.CurrSubModule == "" || wrap.CurrSubModule == "default" {
  107. content += this.getBreadCrumbs(wrap, &[]consts.BreadCrumb{
  108. {Name: "List of pages"},
  109. })
  110. content += builder.DataTable(
  111. wrap,
  112. "fave_pages",
  113. "id",
  114. "DESC",
  115. &[]builder.DataTableRow{
  116. {
  117. DBField: "id",
  118. },
  119. {
  120. DBField: "template",
  121. },
  122. {
  123. DBField: "name",
  124. NameInTable: "Page / URL",
  125. CallBack: func(values *[]string) string {
  126. name := `<a href="/cp/` + wrap.CurrModule + `/modify/` + (*values)[0] + `/">` + html.EscapeString((*values)[2]) + `</a>`
  127. alias := html.EscapeString((*values)[3])
  128. template := html.EscapeString((*values)[1]) + ".html"
  129. return `<div>` + name + `</div><div class="template"><small>` + template + `</small></div><div><small>` + alias + `</small></div>`
  130. },
  131. },
  132. {
  133. DBField: "alias",
  134. },
  135. {
  136. DBField: "datetime",
  137. DBExp: "UNIX_TIMESTAMP(`datetime`)",
  138. NameInTable: "Date / Time",
  139. Classes: "d-none d-md-table-cell",
  140. CallBack: func(values *[]string) string {
  141. t := int64(utils.StrToInt((*values)[4]))
  142. return `<div>` + utils.UnixTimestampToFormat(t, "02.01.2006") + `</div>` +
  143. `<div><small>` + utils.UnixTimestampToFormat(t, "15:04:05") + `</small></div>`
  144. },
  145. },
  146. {
  147. DBField: "active",
  148. NameInTable: "Active",
  149. Classes: "d-none d-sm-table-cell",
  150. CallBack: func(values *[]string) string {
  151. return builder.CheckBox(utils.StrToInt((*values)[5]))
  152. },
  153. },
  154. },
  155. func(values *[]string) string {
  156. return builder.DataTableAction(&[]builder.DataTableActionRow{
  157. {
  158. Icon: assets.SysSvgIconView,
  159. Href: (*values)[3],
  160. Hint: "View",
  161. Target: "_blank",
  162. },
  163. {
  164. Icon: assets.SysSvgIconEdit,
  165. Href: "/cp/" + wrap.CurrModule + "/modify/" + (*values)[0] + "/",
  166. Hint: "Edit",
  167. },
  168. {
  169. Icon: assets.SysSvgIconRemove,
  170. Href: "javascript:fave.ActionDataTableDelete(this,'index-delete','" +
  171. (*values)[0] + "','Are you sure want to delete page?');",
  172. Hint: "Delete",
  173. Classes: "delete",
  174. },
  175. })
  176. },
  177. "/cp/"+wrap.CurrModule+"/",
  178. nil,
  179. nil,
  180. true,
  181. )
  182. } else if wrap.CurrSubModule == "add" || wrap.CurrSubModule == "modify" {
  183. if wrap.CurrSubModule == "add" {
  184. content += this.getBreadCrumbs(wrap, &[]consts.BreadCrumb{
  185. {Name: "Add new page"},
  186. })
  187. } else {
  188. content += this.getBreadCrumbs(wrap, &[]consts.BreadCrumb{
  189. {Name: "Modify page"},
  190. })
  191. }
  192. data := utils.MySql_page{
  193. A_id: 0,
  194. A_user: 0,
  195. A_template: "",
  196. A_name: "",
  197. A_alias: "",
  198. A_content: "",
  199. A_meta_title: "",
  200. A_meta_keywords: "",
  201. A_meta_description: "",
  202. A_datetime: 0,
  203. A_active: 0,
  204. }
  205. if wrap.CurrSubModule == "modify" {
  206. if len(wrap.UrlArgs) != 3 {
  207. return "", "", ""
  208. }
  209. if !utils.IsNumeric(wrap.UrlArgs[2]) {
  210. return "", "", ""
  211. }
  212. err := wrap.DB.QueryRow(
  213. wrap.R.Context(),
  214. `SELECT
  215. id,
  216. user,
  217. template,
  218. name,
  219. alias,
  220. content,
  221. meta_title,
  222. meta_keywords,
  223. meta_description,
  224. active
  225. FROM
  226. fave_pages
  227. WHERE
  228. id = ?
  229. LIMIT 1;`,
  230. utils.StrToInt(wrap.UrlArgs[2]),
  231. ).Scan(
  232. &data.A_id,
  233. &data.A_user,
  234. &data.A_template,
  235. &data.A_name,
  236. &data.A_alias,
  237. &data.A_content,
  238. &data.A_meta_title,
  239. &data.A_meta_keywords,
  240. &data.A_meta_description,
  241. &data.A_active,
  242. )
  243. if *wrap.LogCpError(&err) != nil {
  244. return "", "", ""
  245. }
  246. }
  247. btn_caption := "Add"
  248. if wrap.CurrSubModule == "modify" {
  249. btn_caption = "Save"
  250. }
  251. content += builder.DataForm(wrap, []builder.DataFormField{
  252. {
  253. Kind: builder.DFKHidden,
  254. Name: "action",
  255. Value: "index-modify",
  256. },
  257. {
  258. Kind: builder.DFKHidden,
  259. Name: "id",
  260. Value: utils.IntToStr(data.A_id),
  261. },
  262. {
  263. Kind: builder.DFKText,
  264. Caption: "Page name",
  265. Name: "name",
  266. Value: data.A_name,
  267. Required: true,
  268. Min: "1",
  269. Max: "255",
  270. },
  271. {
  272. Kind: builder.DFKText,
  273. Caption: "Page alias",
  274. Name: "alias",
  275. Value: data.A_alias,
  276. Hint: "Example: /about-us/ or /about-us.html",
  277. Max: "255",
  278. },
  279. {
  280. Kind: builder.DFKText,
  281. Caption: "Page template",
  282. Name: "template",
  283. Value: "0",
  284. CallBack: func(field *builder.DataFormField) string {
  285. return `<div class="form-group n2">` +
  286. `<div class="row">` +
  287. `<div class="col-md-3">` +
  288. `<label for="lbl_template">Page template</label>` +
  289. `</div>` +
  290. `<div class="col-md-9">` +
  291. `<div>` +
  292. `<select class="selectpicker form-control" id="lbl_template" name="template" data-live-search="true">` +
  293. this.index_GetTemplateSelectOptions(wrap, data.A_template) +
  294. `</select>` +
  295. `</div>` +
  296. `</div>` +
  297. `</div>` +
  298. `</div>`
  299. },
  300. },
  301. {
  302. Kind: builder.DFKTextArea,
  303. Caption: "Page content",
  304. Name: "content",
  305. Value: data.A_content,
  306. Classes: "wysiwyg",
  307. },
  308. {
  309. Kind: builder.DFKText,
  310. Caption: "Meta title",
  311. Name: "meta_title",
  312. Value: data.A_meta_title,
  313. Max: "255",
  314. },
  315. {
  316. Kind: builder.DFKText,
  317. Caption: "Meta keywords",
  318. Name: "meta_keywords",
  319. Value: data.A_meta_keywords,
  320. Max: "255",
  321. },
  322. {
  323. Kind: builder.DFKTextArea,
  324. Caption: "Meta description",
  325. Name: "meta_description",
  326. Value: data.A_meta_description,
  327. Max: "510",
  328. },
  329. {
  330. Kind: builder.DFKCheckBox,
  331. Caption: "Active",
  332. Name: "active",
  333. Value: utils.IntToStr(data.A_active),
  334. },
  335. {
  336. Kind: builder.DFKSubmit,
  337. Value: btn_caption,
  338. Target: "add-edit-button",
  339. },
  340. })
  341. if wrap.CurrSubModule == "add" {
  342. sidebar += `<button class="btn btn-primary btn-sidebar" id="add-edit-button">Add</button>`
  343. } else {
  344. sidebar += `<button class="btn btn-primary btn-sidebar" id="add-edit-button">Save</button>`
  345. }
  346. }
  347. return this.getSidebarModules(wrap), content, sidebar
  348. })
  349. }