seo.html 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <title>Building Admin - SEO - QOR5 Document</title>
  5. <meta name='description'>
  6. <meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
  7. <base href='/docs/'>
  8. <link href='index.css' rel='stylesheet' type='text/css'>
  9. <script type='text/javascript' defer src='index.js'></script>
  10. </head>
  11. <body>
  12. <div id='app' v-cloak>
  13. <div v-init-context:vars='{hideAside: false}' class='flex h-screen'>
  14. <div class='flex-1 flex flex-col overflow-hidden'>
  15. <div class='flex h-full'>
  16. <aside v-show='!vars.hideAside' id='menuScroller' class='flex flex-col w-80 h-full bg-gray-50 border-r border-gray-200 overflow-y-auto'>
  17. <div class='h-12'><search></search></div>
  18. <ul class='px-0 py-3 mx-0 text-base font-normal list-none text-gray-700'>
  19. <li class='m-0'>
  20. <a href='index.html' id='index.html' onclick='window.storeMenuState("index.html")' class='inline-block px-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Introduction</a>
  21. </li>
  22. <li class='cursor-default px-4 py-1 truncate break-words w-64 m-0'>Getting Started</li>
  23. <li class='m-0'>
  24. <a href='getting-started/one-minute-quick-start.html' id='getting-started/one-minute-quick-start.html' onclick='window.storeMenuState("getting-started/one-minute-quick-start.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>1 Minute Quick Start</a>
  25. </li>
  26. <li class='cursor-default px-4 py-1 truncate break-words w-64 m-0'>Building Admin</li>
  27. <li class='m-0'>
  28. <a href='basics/listing.html' id='basics/listing.html' onclick='window.storeMenuState("basics/listing.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Listing</a>
  29. </li>
  30. <li class='m-0'>
  31. <a href='basics/filter.html' id='basics/filter.html' onclick='window.storeMenuState("basics/filter.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Filters</a>
  32. </li>
  33. <li class='m-0'>
  34. <a href='presets-guide/editing-customizations.html' id='presets-guide/editing-customizations.html' onclick='window.storeMenuState("presets-guide/editing-customizations.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Editing</a>
  35. </li>
  36. <li class='m-0'>
  37. <a href='basics/brand.html' id='basics/brand.html' onclick='window.storeMenuState("basics/brand.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Brand</a>
  38. </li>
  39. <li class='m-0'>
  40. <a href='basics/menu.html' id='basics/menu.html' onclick='window.storeMenuState("basics/menu.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Menu</a>
  41. </li>
  42. <li class='m-0'>
  43. <a href='presets-guide/detail-page-for-complex-object.html' id='presets-guide/detail-page-for-complex-object.html' onclick='window.storeMenuState("presets-guide/detail-page-for-complex-object.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Detailing</a>
  44. </li>
  45. <li class='m-0'>
  46. <a href='basics/layout.html' id='basics/layout.html' onclick='window.storeMenuState("basics/layout.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Layout</a>
  47. </li>
  48. <li class='m-0'>
  49. <a href='basics/login.html' id='basics/login.html' onclick='window.storeMenuState("basics/login.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Login</a>
  50. </li>
  51. <li class='m-0'>
  52. <a href='presets-guide/permissions.html' id='presets-guide/permissions.html' onclick='window.storeMenuState("presets-guide/permissions.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Permissions</a>
  53. </li>
  54. <li class='m-0'>
  55. <a href='presets-guide/role.html' id='presets-guide/role.html' onclick='window.storeMenuState("presets-guide/role.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Role</a>
  56. </li>
  57. <li class='m-0'>
  58. <a href='basics/notification-center.html' id='basics/notification-center.html' onclick='window.storeMenuState("basics/notification-center.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Notification Center</a>
  59. </li>
  60. <li class='m-0'>
  61. <a href='basics/shortcut.html' id='basics/shortcut.html' onclick='window.storeMenuState("basics/shortcut.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Keyboard Shortcut</a>
  62. </li>
  63. <li class='m-0'>
  64. <a href='basics/confirm-dialog.html' id='basics/confirm-dialog.html' onclick='window.storeMenuState("basics/confirm-dialog.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Confirm Dialog</a>
  65. </li>
  66. <li class='m-0'>
  67. <a href='slug.html' id='slug.html' onclick='window.storeMenuState("slug.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Slug</a>
  68. </li>
  69. <li class='m-0'>
  70. <a href='seo.html' id='seo.html' onclick='window.storeMenuState("seo.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-blue-500'>SEO</a>
  71. </li>
  72. <li class='m-0'>
  73. <a href='activity-log.html' id='activity-log.html' onclick='window.storeMenuState("activity-log.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Activity Log</a>
  74. </li>
  75. <li class='m-0'>
  76. <a href='basics/worker.html' id='basics/worker.html' onclick='window.storeMenuState("basics/worker.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Worker</a>
  77. </li>
  78. <li class='m-0'>
  79. <a href='basics/l10n.html' id='basics/l10n.html' onclick='window.storeMenuState("basics/l10n.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Localization</a>
  80. </li>
  81. <li class='cursor-default px-4 py-1 truncate break-words w-64 m-0'>Web Application</li>
  82. <li class='m-0'>
  83. <a href='basics/page-func-and-event-func.html' id='basics/page-func-and-event-func.html' onclick='window.storeMenuState("basics/page-func-and-event-func.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Page Func and Event Func</a>
  84. </li>
  85. <li class='m-0'>
  86. <a href='advanced-functions/the-go-html-builder.html' id='advanced-functions/the-go-html-builder.html' onclick='window.storeMenuState("advanced-functions/the-go-html-builder.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>The Go HTML builder</a>
  87. </li>
  88. <li class='m-0'>
  89. <a href='presets-guide/its-the-whole-house.html' id='presets-guide/its-the-whole-house.html' onclick='window.storeMenuState("presets-guide/its-the-whole-house.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Not just scaffolding, it&#39;s the whole house</a>
  90. </li>
  91. <li class='m-0'>
  92. <a href='vuetify-components/lazy-portals.html' id='vuetify-components/lazy-portals.html' onclick='window.storeMenuState("vuetify-components/lazy-portals.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Lazy Portals</a>
  93. </li>
  94. <li class='m-0'>
  95. <a href='basics/layout-function-and-page-injector.html' id='basics/layout-function-and-page-injector.html' onclick='window.storeMenuState("basics/layout-function-and-page-injector.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Layout Function and Page Injector</a>
  96. </li>
  97. <li class='m-0'>
  98. <a href='basics/switch-pages-with-push-state.html' id='basics/switch-pages-with-push-state.html' onclick='window.storeMenuState("basics/switch-pages-with-push-state.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Switch Pages with Push State</a>
  99. </li>
  100. <li class='m-0'>
  101. <a href='basics/reload-page-with-a-flash.html' id='basics/reload-page-with-a-flash.html' onclick='window.storeMenuState("basics/reload-page-with-a-flash.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Reload Page with a Flash</a>
  102. </li>
  103. <li class='m-0'>
  104. <a href='basics/partial-refresh-with-portal.html' id='basics/partial-refresh-with-portal.html' onclick='window.storeMenuState("basics/partial-refresh-with-portal.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Partial Refresh with Portal</a>
  105. </li>
  106. <li class='m-0'>
  107. <a href='basics/manipulate-page-url-in-event-func.html' id='basics/manipulate-page-url-in-event-func.html' onclick='window.storeMenuState("basics/manipulate-page-url-in-event-func.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Manipulate Page URL in Event Func</a>
  108. </li>
  109. <li class='m-0'>
  110. <a href='basics/summary-of-event-response.html' id='basics/summary-of-event-response.html' onclick='window.storeMenuState("basics/summary-of-event-response.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Summary of Event Response</a>
  111. </li>
  112. <li class='m-0'>
  113. <a href='basics/scope-component.html' id='basics/scope-component.html' onclick='window.storeMenuState("basics/scope-component.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Scope Component</a>
  114. </li>
  115. <li class='m-0'>
  116. <a href='basics/event-handling.html' id='basics/event-handling.html' onclick='window.storeMenuState("basics/event-handling.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Event Handling</a>
  117. </li>
  118. <li class='m-0'>
  119. <a href='basics/form-handling.html' id='basics/form-handling.html' onclick='window.storeMenuState("basics/form-handling.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Form Handling</a>
  120. </li>
  121. <li class='cursor-default px-4 py-1 truncate break-words w-64 m-0'>UI Components</li>
  122. <li class='m-0'>
  123. <a href='vuetify-components/basic-inputs.html' id='vuetify-components/basic-inputs.html' onclick='window.storeMenuState("vuetify-components/basic-inputs.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Basic Inputs</a>
  124. </li>
  125. <li class='m-0'>
  126. <a href='vuetify-components/a-taste-of-using-vuetify-in-go.html' id='vuetify-components/a-taste-of-using-vuetify-in-go.html' onclick='window.storeMenuState("vuetify-components/a-taste-of-using-vuetify-in-go.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>A Taste of using Vuetify in Go</a>
  127. </li>
  128. <li class='m-0'>
  129. <a href='vuetify-components/linkage-select.html' id='vuetify-components/linkage-select.html' onclick='window.storeMenuState("vuetify-components/linkage-select.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Linkage Select</a>
  130. </li>
  131. <li class='m-0'>
  132. <a href='vuetify-components/auto-complete.html' id='vuetify-components/auto-complete.html' onclick='window.storeMenuState("vuetify-components/auto-complete.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Auto Complete</a>
  133. </li>
  134. <li class='m-0'>
  135. <a href='components-guide/composite-new-component-with-go.html' id='components-guide/composite-new-component-with-go.html' onclick='window.storeMenuState("components-guide/composite-new-component-with-go.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Composite new Component With Go</a>
  136. </li>
  137. <li class='m-0'>
  138. <a href='components-guide/integrate-a-heavy-vue-component.html' id='components-guide/integrate-a-heavy-vue-component.html' onclick='window.storeMenuState("components-guide/integrate-a-heavy-vue-component.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Integrate a heavy Vue Component</a>
  139. </li>
  140. <li class='cursor-default px-4 py-1 truncate break-words w-64 m-0'>Appendix</li>
  141. <li class='m-0'>
  142. <a href='appendix/all-demo-examples.html' id='appendix/all-demo-examples.html' onclick='window.storeMenuState("appendix/all-demo-examples.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>All Demo Examples</a>
  143. </li>
  144. </ul>
  145. </aside>
  146. <main class='flex flex-col w-full bg-white overflow-x-hidden overflow-y-auto'>
  147. <div id='docContentBox' class='flex flex-row w-full'>
  148. <div class='flex flex-grow flex-col w-2/3'>
  149. <div class='flex flex-row'>
  150. <button @click='vars.hideAside = !vars.hideAside' class='w-12 h-12 p-4'>
  151. <div class='w-4 h-4 fill-current text-gray-300'>
  152. <?xml version="1.0" encoding="UTF-8"?>
  153. <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16px" height="16px" viewBox="0 0 16 16" version="1.1">
  154. <g id="surface1">
  155. <path style=" stroke:none;fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 2 12 L 2 11 L 14 11 L 14 12 Z M 2 8.5 L 2 7.5 L 14 7.5 L 14 8.5 Z M 2 5 L 2 4 L 14 4 L 14 5 Z M 2 5 "/>
  156. </g>
  157. </svg>
  158. </div>
  159. </button>
  160. </div>
  161. <div id='docMainBox' class='px-16 pb-12 pt-4 overflow-auto'>
  162. <h1 class='mb-8'>SEO</h1>
  163. <div class='border-t'><p>The SEO library facilitates the optimization of Search Engine results by managing and injecting dynamic data into HTML tags.</p>
  164. <h2><a name="usage" class="anchor" href="#usage" rel="nofollow" aria-hidden="true"><span class="octicon octicon-link"></span></a>
  165. Usage</h2>
  166. <p>Initialize a <code>Collection</code> instance. The <code>Collection</code> manages all the registered models and hold global seo settings</p>
  167. <div class="highlight highlight-go"><pre>collection := seo.NewCollection()
  168. // Turn off the default inherit the upper level SEO data when the current SEO data is missing
  169. collection.SetInherited(false)
  170. </pre></div>
  171. <h3><a name="register-models-to-seo" class="anchor" href="#register-models-to-seo" rel="nofollow" aria-hidden="true"><span class="octicon octicon-link"></span></a>
  172. Register models to SEO</h3>
  173. <div class="highlight highlight-go"><pre>// Register mutiple SEO by name
  174. collection.RegisterSEOByNames(&#34;Product&#34;, &#34;Announcement&#34;)
  175. // Register a SEO by model
  176. type Product struct{
  177. Name string
  178. Setting Setting
  179. }
  180. collection.RegisterSEO(&amp;Product{})
  181. </pre></div>
  182. <h3><a name="remove-models-from-seo" class="anchor" href="#remove-models-from-seo" rel="nofollow" aria-hidden="true"><span class="octicon octicon-link"></span></a>
  183. Remove models from SEO</h3>
  184. <pre><code>// Remove by struct
  185. collection.RemoveSEO(&amp;Product{})
  186. // Remove by name
  187. collection.RemoveSEO(&#34;Not Found&#34;)
  188. </code></pre>
  189. <h2><a name="configuration" class="anchor" href="#configuration" rel="nofollow" aria-hidden="true"><span class="octicon octicon-link"></span></a>
  190. Configuration</h2>
  191. <h3><a name="change-the-default-global-seo-name" class="anchor" href="#change-the-default-global-seo-name" rel="nofollow" aria-hidden="true"><span class="octicon octicon-link"></span></a>
  192. Change the default global SEO name</h3>
  193. <div class="highlight highlight-go"><pre>collection.SetGlobalName(&#34;My Global SEO&#34;)
  194. </pre></div>
  195. <h3><a name="change-the-default-context-db-key" class="anchor" href="#change-the-default-context-db-key" rel="nofollow" aria-hidden="true"><span class="octicon octicon-link"></span></a>
  196. Change the default context db key</h3>
  197. <div class="highlight highlight-go"><pre>collection.SetDBContextKey(&#34;My DB&#34;)
  198. </pre></div>
  199. <h3><a name="change-the-default-seo-name" class="anchor" href="#change-the-default-seo-name" rel="nofollow" aria-hidden="true"><span class="octicon octicon-link"></span></a>
  200. Change the default SEO name</h3>
  201. <div class="highlight highlight-go"><pre>collection.RegisterSEO(&amp;Product{}).SetName(&#34;My Product&#34;)
  202. </pre></div>
  203. <h3><a name="register-customized-variables" class="anchor" href="#register-customized-variables" rel="nofollow" aria-hidden="true"><span class="octicon octicon-link"></span></a>
  204. Register customized variables</h3>
  205. <div class="highlight highlight-go"><pre>collection.RegisterSEO(&amp;Product{}).
  206. RegisterContextVariables(&#34;og:image&#34;, func(obj interface{}, _ *Setting, _ *http.Request) string {
  207. // this will render &#34;og:image&#34; with the value of the object in the current request
  208. return obj.image.url
  209. }).
  210. RegisterContextVariables(&#34;Name&#34;, func(obj interface{}, _ *Setting, _ *http.Request) string {
  211. return obj.Name
  212. })
  213. </pre></div>
  214. <h3><a name="register-setting-variable" class="anchor" href="#register-setting-variable" rel="nofollow" aria-hidden="true"><span class="octicon octicon-link"></span></a>
  215. Register setting variable</h3>
  216. <p>This variable will be saved in the database and available as a global variable while editing SEO settings.</p>
  217. <div class="highlight highlight-go"><pre>collection.RegisterSEO(&amp;Product{}).RegisterSettingVaribles(struct{ProductTag string}{})
  218. </pre></div>
  219. <h3><a name="render-seo-html-data" class="anchor" href="#render-seo-html-data" rel="nofollow" aria-hidden="true"><span class="octicon octicon-link"></span></a>
  220. Render SEO html data</h3>
  221. <div class="highlight highlight-go"><pre>// Render Global SEO
  222. collection.RenderGlobal(request)
  223. // Render SEO by name
  224. collection.Render(&#34;product&#34;, request)
  225. // Render SEO by model
  226. collection.Render(Product{}, request)
  227. </pre></div>
  228. <h2><a name="customization" class="anchor" href="#customization" rel="nofollow" aria-hidden="true"><span class="octicon octicon-link"></span></a>
  229. Customization</h2>
  230. <p>You can customize your SEO settings by implementing the interface and adding functions such as l10n and publish.</p>
  231. <highlightjs :language='"go"' :code='"type QorSEOSettingInterface interface {\n\tGetName() string\n\tSetName(string)\n\tGetSEOSetting() Setting\n\tSetSEOSetting(Setting)\n\tGetVariables() Variables\n\tSetVariables(Variables)\n\tGetTitle() string\n\tGetDescription() string\n\tGetKeywords() string\n\tGetOpenGraphURL() string\n\tGetOpenGraphType() string\n\tGetOpenGraphImageURL() string\n\tGetOpenGraphImageFromMediaLibrary() media_library.MediaBox\n\tGetOpenGraphMetadata() []OpenGraphMetadata\n}\n"'></highlightjs>
  232. <p>Suppose <code>MySEOSetting</code> implemented the above interface</p>
  233. <div class="highlight highlight-go"><pre>type MySEOSetting struct{
  234. QorSEOSetting
  235. // publish
  236. // l10n
  237. }
  238. </pre></div>
  239. <p>Use <code>SetSettingModel</code> function to set it</p>
  240. <div class="highlight highlight-go"><pre>collection.SetSettingModel(&amp;MySEOSetting{})
  241. </pre></div>
  242. <h2>Example</h2>
  243. <highlightjs :language='"go"' :code='"var SeoCollection *seo.Collection\n\nfunc ConfigureSeo(b *presets.Builder, db *gorm.DB) {\n\tSeoCollection = seo.NewCollection()\n\tSeoCollection.RegisterSEO(\u0026models.Post{}).RegisterContextVariables(\n\t\t\"Title\",\n\t\tfunc(object interface{}, _ *seo.Setting, _ *http.Request) string {\n\t\t\tif article, ok := object.(models.Post); ok {\n\t\t\t\treturn article.Title\n\t\t\t}\n\t\t\treturn \"\"\n\t\t},\n\t).RegisterSettingVaribles(struct{ Test string }{})\n\tSeoCollection.RegisterSEOByNames(\"Not Found\", \"Internal Server Error\")\n\tSeoCollection.Configure(b, db)\n}\n"'></highlightjs>
  244. <h2><a name="definition" class="anchor" href="#definition" rel="nofollow" aria-hidden="true"><span class="octicon octicon-link"></span></a>Definition</h2>
  245. <p><code>Collection</code> manages all the registered models and hold global seo settings.</p>
  246. <highlightjs :language='"go"' :code='"type Collection struct {\n\tregisteredSEO []*SEO\n\tglobalName string //default name is GlobalSEO\n\tinherited bool //default is true. the order is model seo setting, system seo setting, global seo setting\n\tdbContextKey interface{} // get db from context\n\tsettingModel interface{} // db model\n}\n"'></highlightjs>
  247. <p><code>SEO</code> provides system-level default page matadata.</p>
  248. <highlightjs :language='"go"' :code='"type SEO struct {\n\tname string\n\tmodelTyp reflect.Type\n\tcontextVariables map[string]contextVariablesFunc // fetch context variables from request\n\tsettingVariables interface{} // fetch setting variables from db\n}\n"'></highlightjs>
  249. <p>You can use seo setting at the model level, but you need to register the model to the system SEO</p>
  250. <highlightjs :language='"go"' :code='"type Product struct {\n\tName string\n\tSEO Setting\n}\n"'></highlightjs>
  251. <highlightjs :language='"go"' :code='"collection.RegisterSEO(\u0026Product{})"'></highlightjs>
  252. </div>
  253. </div>
  254. </div>
  255. <div class='font-medium text-base hidden xl:block text-gray-600 pt-4'>
  256. <div class='sticky top-4 w-52'>On This Page<toc></toc></div>
  257. </div>
  258. </div>
  259. <search-result></search-result></main>
  260. </div>
  261. </div>
  262. </div>
  263. </div>
  264. </body>
  265. </html>