mindroot 9.11.0__py3-none-any.whl → 9.13.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of mindroot might be problematic. Click here for more details.

Files changed (417) hide show
  1. mindroot/coreplugins/admin/static/js/model-preferences-v2.js +1 -1
  2. mindroot/coreplugins/home/templates/home.jinja2 +1 -0
  3. mindroot/docs/Makefile +20 -0
  4. mindroot/docs/_build/doctrees/chat_with_assistant.doctree +0 -0
  5. mindroot/docs/_build/doctrees/developer_documentation.doctree +0 -0
  6. mindroot/docs/_build/doctrees/environment.pickle +0 -0
  7. mindroot/docs/_build/doctrees/getting_started.doctree +0 -0
  8. mindroot/docs/_build/doctrees/index.doctree +0 -0
  9. mindroot/docs/_build/doctrees/install_plugins_with_tools.doctree +0 -0
  10. mindroot/docs/_build/doctrees/installation.doctree +0 -0
  11. mindroot/docs/_build/doctrees/llm_api_key.doctree +0 -0
  12. mindroot/docs/_build/doctrees/llm_plugin_installation.doctree +0 -0
  13. mindroot/docs/_build/doctrees/programming_task.doctree +0 -0
  14. mindroot/docs/_build/doctrees/source/ahp.doctree +0 -0
  15. mindroot/docs/_build/doctrees/source/mindroot.coreplugins.admin.doctree +0 -0
  16. mindroot/docs/_build/doctrees/source/mindroot.coreplugins.api_keys.doctree +0 -0
  17. mindroot/docs/_build/doctrees/source/mindroot.coreplugins.chat.doctree +0 -0
  18. mindroot/docs/_build/doctrees/source/mindroot.coreplugins.chat_avatar.doctree +0 -0
  19. mindroot/docs/_build/doctrees/source/mindroot.coreplugins.check_list.doctree +0 -0
  20. mindroot/docs/_build/doctrees/source/mindroot.coreplugins.credits.doctree +0 -0
  21. mindroot/docs/_build/doctrees/source/mindroot.coreplugins.doctree +0 -0
  22. mindroot/docs/_build/doctrees/source/mindroot.coreplugins.email.doctree +0 -0
  23. mindroot/docs/_build/doctrees/source/mindroot.coreplugins.env_manager.doctree +0 -0
  24. mindroot/docs/_build/doctrees/source/mindroot.coreplugins.events.doctree +0 -0
  25. mindroot/docs/_build/doctrees/source/mindroot.coreplugins.index.doctree +0 -0
  26. mindroot/docs/_build/doctrees/source/mindroot.coreplugins.index.handlers.doctree +0 -0
  27. mindroot/docs/_build/doctrees/source/mindroot.coreplugins.jwt_auth.doctree +0 -0
  28. mindroot/docs/_build/doctrees/source/mindroot.coreplugins.l8n.doctree +0 -0
  29. mindroot/docs/_build/doctrees/source/mindroot.coreplugins.mcp_.doctree +0 -0
  30. mindroot/docs/_build/doctrees/source/mindroot.coreplugins.persona.doctree +0 -0
  31. mindroot/docs/_build/doctrees/source/mindroot.coreplugins.startup.doctree +0 -0
  32. mindroot/docs/_build/doctrees/source/mindroot.coreplugins.subscriptions.doctree +0 -0
  33. mindroot/docs/_build/doctrees/source/mindroot.coreplugins.usage.doctree +0 -0
  34. mindroot/docs/_build/doctrees/source/mindroot.coreplugins.user_service.doctree +0 -0
  35. mindroot/docs/_build/doctrees/source/mindroot.doctree +0 -0
  36. mindroot/docs/_build/doctrees/source/mindroot.lib.auth.doctree +0 -0
  37. mindroot/docs/_build/doctrees/source/mindroot.lib.doctree +0 -0
  38. mindroot/docs/_build/doctrees/source/mindroot.lib.json_str_block.doctree +0 -0
  39. mindroot/docs/_build/doctrees/source/mindroot.lib.plugins.doctree +0 -0
  40. mindroot/docs/_build/doctrees/source/mindroot.lib.providers.backup.doctree +0 -0
  41. mindroot/docs/_build/doctrees/source/mindroot.lib.providers.doctree +0 -0
  42. mindroot/docs/_build/doctrees/source/mindroot.registry.doctree +0 -0
  43. mindroot/docs/_build/doctrees/source/modules.doctree +0 -0
  44. mindroot/docs/_build/doctrees/source/mr_agent_expert_instr.doctree +0 -0
  45. mindroot/docs/_build/doctrees/starting_mindroot.doctree +0 -0
  46. mindroot/docs/_build/doctrees/user_documentation.doctree +0 -0
  47. mindroot/docs/_build/html/.buildinfo +4 -0
  48. mindroot/docs/_build/html/.buildinfo.bak +4 -0
  49. mindroot/docs/_build/html/_images/envvar.png +0 -0
  50. mindroot/docs/_build/html/_images/files.png +0 -0
  51. mindroot/docs/_build/html/_images/installopenrouter.png +0 -0
  52. mindroot/docs/_build/html/_images/mood.png +0 -0
  53. mindroot/docs/_build/html/_images/moon.png +0 -0
  54. mindroot/docs/_build/html/_images/openrouter.png +0 -0
  55. mindroot/docs/_build/html/_images/restart.png +0 -0
  56. mindroot/docs/_build/html/_modules/index.html +425 -0
  57. mindroot/docs/_build/html/_modules/mindroot/coreplugins/admin/agent_importer.html +292 -0
  58. mindroot/docs/_build/html/_modules/mindroot/coreplugins/admin/agent_router.html +620 -0
  59. mindroot/docs/_build/html/_modules/mindroot/coreplugins/admin/asset_manager.html +289 -0
  60. mindroot/docs/_build/html/_modules/mindroot/coreplugins/admin/command_router.html +518 -0
  61. mindroot/docs/_build/html/_modules/mindroot/coreplugins/admin/mcp_catalog_routes.html +275 -0
  62. mindroot/docs/_build/html/_modules/mindroot/coreplugins/admin/mcp_publish_routes.html +581 -0
  63. mindroot/docs/_build/html/_modules/mindroot/coreplugins/admin/mcp_registry_routes.html +623 -0
  64. mindroot/docs/_build/html/_modules/mindroot/coreplugins/admin/mcp_routes.html +347 -0
  65. mindroot/docs/_build/html/_modules/mindroot/coreplugins/admin/mod.html +163 -0
  66. mindroot/docs/_build/html/_modules/mindroot/coreplugins/admin/oauth_callback_router.html +188 -0
  67. mindroot/docs/_build/html/_modules/mindroot/coreplugins/admin/persona_handler.html +195 -0
  68. mindroot/docs/_build/html/_modules/mindroot/coreplugins/admin/persona_router.html +428 -0
  69. mindroot/docs/_build/html/_modules/mindroot/coreplugins/admin/plugin_manager.html +610 -0
  70. mindroot/docs/_build/html/_modules/mindroot/coreplugins/admin/plugin_router.html +146 -0
  71. mindroot/docs/_build/html/_modules/mindroot/coreplugins/admin/plugin_routes.html +230 -0
  72. mindroot/docs/_build/html/_modules/mindroot/coreplugins/admin/registry_settings_routes.html +253 -0
  73. mindroot/docs/_build/html/_modules/mindroot/coreplugins/admin/router.html +267 -0
  74. mindroot/docs/_build/html/_modules/mindroot/coreplugins/admin/server_router.html +271 -0
  75. mindroot/docs/_build/html/_modules/mindroot/coreplugins/admin/service_models.html +195 -0
  76. mindroot/docs/_build/html/_modules/mindroot/coreplugins/admin/settings_router.html +403 -0
  77. mindroot/docs/_build/html/_modules/mindroot/coreplugins/api_keys/api_key_manager.html +215 -0
  78. mindroot/docs/_build/html/_modules/mindroot/coreplugins/api_keys/mod.html +127 -0
  79. mindroot/docs/_build/html/_modules/mindroot/coreplugins/api_keys/router.html +170 -0
  80. mindroot/docs/_build/html/_modules/mindroot/coreplugins/chat/commands.html +565 -0
  81. mindroot/docs/_build/html/_modules/mindroot/coreplugins/chat/mod.html +118 -0
  82. mindroot/docs/_build/html/_modules/mindroot/coreplugins/chat/models.html +130 -0
  83. mindroot/docs/_build/html/_modules/mindroot/coreplugins/chat/router.html +571 -0
  84. mindroot/docs/_build/html/_modules/mindroot/coreplugins/chat/services.html +645 -0
  85. mindroot/docs/_build/html/_modules/mindroot/coreplugins/chat/widget_manager.html +258 -0
  86. mindroot/docs/_build/html/_modules/mindroot/coreplugins/chat/widget_routes.html +409 -0
  87. mindroot/docs/_build/html/_modules/mindroot/coreplugins/check_list/mod.html +460 -0
  88. mindroot/docs/_build/html/_modules/mindroot/coreplugins/credits/conversion.html +232 -0
  89. mindroot/docs/_build/html/_modules/mindroot/coreplugins/credits/ledger.html +283 -0
  90. mindroot/docs/_build/html/_modules/mindroot/coreplugins/credits/mod.html +355 -0
  91. mindroot/docs/_build/html/_modules/mindroot/coreplugins/credits/models.html +269 -0
  92. mindroot/docs/_build/html/_modules/mindroot/coreplugins/credits/router.html +306 -0
  93. mindroot/docs/_build/html/_modules/mindroot/coreplugins/credits/storage.html +257 -0
  94. mindroot/docs/_build/html/_modules/mindroot/coreplugins/email/email_provider.html +159 -0
  95. mindroot/docs/_build/html/_modules/mindroot/coreplugins/email/imap_handler.html +343 -0
  96. mindroot/docs/_build/html/_modules/mindroot/coreplugins/email/mod.html +210 -0
  97. mindroot/docs/_build/html/_modules/mindroot/coreplugins/email/services.html +172 -0
  98. mindroot/docs/_build/html/_modules/mindroot/coreplugins/email/smtp_handler.html +188 -0
  99. mindroot/docs/_build/html/_modules/mindroot/coreplugins/email/test_email_service.html +179 -0
  100. mindroot/docs/_build/html/_modules/mindroot/coreplugins/env_manager/mod.html +409 -0
  101. mindroot/docs/_build/html/_modules/mindroot/coreplugins/env_manager/router.html +147 -0
  102. mindroot/docs/_build/html/_modules/mindroot/coreplugins/events/router.html +201 -0
  103. mindroot/docs/_build/html/_modules/mindroot/coreplugins/index/handlers/agent_ops.html +195 -0
  104. mindroot/docs/_build/html/_modules/mindroot/coreplugins/index/handlers/index_ops.html +214 -0
  105. mindroot/docs/_build/html/_modules/mindroot/coreplugins/index/handlers/plugin_ops.html +263 -0
  106. mindroot/docs/_build/html/_modules/mindroot/coreplugins/index/handlers/publish.html +225 -0
  107. mindroot/docs/_build/html/_modules/mindroot/coreplugins/index/mod.html +120 -0
  108. mindroot/docs/_build/html/_modules/mindroot/coreplugins/index/models.html +148 -0
  109. mindroot/docs/_build/html/_modules/mindroot/coreplugins/index/router.html +184 -0
  110. mindroot/docs/_build/html/_modules/mindroot/coreplugins/index/utils.html +166 -0
  111. mindroot/docs/_build/html/_modules/mindroot/coreplugins/jwt_auth/middleware.html +400 -0
  112. mindroot/docs/_build/html/_modules/mindroot/coreplugins/jwt_auth/mod.html +153 -0
  113. mindroot/docs/_build/html/_modules/mindroot/coreplugins/jwt_auth/router.html +134 -0
  114. mindroot/docs/_build/html/_modules/mindroot/coreplugins/l8n/language_detection.html +296 -0
  115. mindroot/docs/_build/html/_modules/mindroot/coreplugins/l8n/middleware.html +258 -0
  116. mindroot/docs/_build/html/_modules/mindroot/coreplugins/l8n/mod.html +393 -0
  117. mindroot/docs/_build/html/_modules/mindroot/coreplugins/l8n/test_enhanced.html +408 -0
  118. mindroot/docs/_build/html/_modules/mindroot/coreplugins/l8n/test_l8n_standalone.html +379 -0
  119. mindroot/docs/_build/html/_modules/mindroot/coreplugins/l8n/test_middleware.html +394 -0
  120. mindroot/docs/_build/html/_modules/mindroot/coreplugins/l8n/utils.html +348 -0
  121. mindroot/docs/_build/html/_modules/mindroot/coreplugins/mcp_/catalog_commands.html +456 -0
  122. mindroot/docs/_build/html/_modules/mindroot/coreplugins/mcp_/catalog_manager.html +409 -0
  123. mindroot/docs/_build/html/_modules/mindroot/coreplugins/mcp_/dynamic_commands.html +267 -0
  124. mindroot/docs/_build/html/_modules/mindroot/coreplugins/mcp_/mcp_manager.html +1186 -0
  125. mindroot/docs/_build/html/_modules/mindroot/coreplugins/mcp_/mod.html +510 -0
  126. mindroot/docs/_build/html/_modules/mindroot/coreplugins/mcp_/oauth_storage.html +260 -0
  127. mindroot/docs/_build/html/_modules/mindroot/coreplugins/mcp_/server_installer.html +195 -0
  128. mindroot/docs/_build/html/_modules/mindroot/coreplugins/mcp_/testmcpclient.html +217 -0
  129. mindroot/docs/_build/html/_modules/mindroot/coreplugins/persona/init_persona.html +117 -0
  130. mindroot/docs/_build/html/_modules/mindroot/coreplugins/persona/mod.html +276 -0
  131. mindroot/docs/_build/html/_modules/mindroot/coreplugins/startup/mod.html +122 -0
  132. mindroot/docs/_build/html/_modules/mindroot/coreplugins/subscriptions/credit_integration.html +163 -0
  133. mindroot/docs/_build/html/_modules/mindroot/coreplugins/subscriptions/mod.html +1089 -0
  134. mindroot/docs/_build/html/_modules/mindroot/coreplugins/subscriptions/models.html +261 -0
  135. mindroot/docs/_build/html/_modules/mindroot/coreplugins/subscriptions/router.html +502 -0
  136. mindroot/docs/_build/html/_modules/mindroot/coreplugins/subscriptions/storage.html +413 -0
  137. mindroot/docs/_build/html/_modules/mindroot/coreplugins/subscriptions/stripe_integration.html +178 -0
  138. mindroot/docs/_build/html/_modules/mindroot/coreplugins/subscriptions/subscription_manager.html +289 -0
  139. mindroot/docs/_build/html/_modules/mindroot/coreplugins/subscriptions/webhook_handler.html +327 -0
  140. mindroot/docs/_build/html/_modules/mindroot/coreplugins/usage/handlers.html +157 -0
  141. mindroot/docs/_build/html/_modules/mindroot/coreplugins/usage/mod.html +253 -0
  142. mindroot/docs/_build/html/_modules/mindroot/coreplugins/usage/models.html +141 -0
  143. mindroot/docs/_build/html/_modules/mindroot/coreplugins/usage/reporting.html +226 -0
  144. mindroot/docs/_build/html/_modules/mindroot/coreplugins/usage/router.html +228 -0
  145. mindroot/docs/_build/html/_modules/mindroot/coreplugins/usage/storage.html +264 -0
  146. mindroot/docs/_build/html/_modules/mindroot/coreplugins/user_service/admin_init.html +234 -0
  147. mindroot/docs/_build/html/_modules/mindroot/coreplugins/user_service/email_service.html +204 -0
  148. mindroot/docs/_build/html/_modules/mindroot/coreplugins/user_service/mod.html +260 -0
  149. mindroot/docs/_build/html/_modules/mindroot/coreplugins/user_service/models.html +148 -0
  150. mindroot/docs/_build/html/_modules/mindroot/coreplugins/user_service/password_reset_service.html +336 -0
  151. mindroot/docs/_build/html/_modules/mindroot/coreplugins/user_service/role_service.html +183 -0
  152. mindroot/docs/_build/html/_modules/mindroot/coreplugins/user_service/router.html +202 -0
  153. mindroot/docs/_build/html/_modules/mindroot/lib/auth/api_key.html +129 -0
  154. mindroot/docs/_build/html/_modules/mindroot/lib/auth/auth.html +203 -0
  155. mindroot/docs/_build/html/_modules/mindroot/lib/buchatlog.html +259 -0
  156. mindroot/docs/_build/html/_modules/mindroot/lib/buchatlog2.html +500 -0
  157. mindroot/docs/_build/html/_modules/mindroot/lib/butemplates.html +415 -0
  158. mindroot/docs/_build/html/_modules/mindroot/lib/chatcontext.html +401 -0
  159. mindroot/docs/_build/html/_modules/mindroot/lib/chatlog.html +619 -0
  160. mindroot/docs/_build/html/_modules/mindroot/lib/chatlog_optimized.html +655 -0
  161. mindroot/docs/_build/html/_modules/mindroot/lib/json_escape.html +138 -0
  162. mindroot/docs/_build/html/_modules/mindroot/lib/json_str_block/json_str_block.html +213 -0
  163. mindroot/docs/_build/html/_modules/mindroot/lib/parent_templates.html +181 -0
  164. mindroot/docs/_build/html/_modules/mindroot/lib/plugins/installation.html +481 -0
  165. mindroot/docs/_build/html/_modules/mindroot/lib/plugins/l8n_static_handler.html +347 -0
  166. mindroot/docs/_build/html/_modules/mindroot/lib/plugins/loader.html +403 -0
  167. mindroot/docs/_build/html/_modules/mindroot/lib/plugins/loader_with_l8n.html +391 -0
  168. mindroot/docs/_build/html/_modules/mindroot/lib/plugins/manifest.html +450 -0
  169. mindroot/docs/_build/html/_modules/mindroot/lib/plugins/mapping.html +127 -0
  170. mindroot/docs/_build/html/_modules/mindroot/lib/plugins/paths.html +215 -0
  171. mindroot/docs/_build/html/_modules/mindroot/lib/plugins_install.html +171 -0
  172. mindroot/docs/_build/html/_modules/mindroot/lib/providers/commands.html +125 -0
  173. mindroot/docs/_build/html/_modules/mindroot/lib/providers/hooks.html +117 -0
  174. mindroot/docs/_build/html/_modules/mindroot/lib/providers/missing.html +169 -0
  175. mindroot/docs/_build/html/_modules/mindroot/lib/providers/model_preferences_v2.html +291 -0
  176. mindroot/docs/_build/html/_modules/mindroot/lib/providers/services.html +122 -0
  177. mindroot/docs/_build/html/_modules/mindroot/lib/providers.html +465 -0
  178. mindroot/docs/_build/html/_modules/mindroot/lib/route_decorators.html +175 -0
  179. mindroot/docs/_build/html/_modules/mindroot/lib/session_files.html +142 -0
  180. mindroot/docs/_build/html/_modules/mindroot/lib/streamcmd.html +246 -0
  181. mindroot/docs/_build/html/_modules/mindroot/lib/templates.html +677 -0
  182. mindroot/docs/_build/html/_modules/mindroot/lib/token_counter.html +326 -0
  183. mindroot/docs/_build/html/_modules/mindroot/migrate.html +153 -0
  184. mindroot/docs/_build/html/_modules/mindroot/registry/component_manager.html +140 -0
  185. mindroot/docs/_build/html/_modules/mindroot/registry/data_access.html +302 -0
  186. mindroot/docs/_build/html/_modules/mindroot/server.html +317 -0
  187. mindroot/docs/_build/html/_modules/mindroot/server_missing_normal_args.html +322 -0
  188. mindroot/docs/_build/html/_modules/mindroot/server_prev.html +298 -0
  189. mindroot/docs/_build/html/_sources/chat_with_assistant.rst.txt +14 -0
  190. mindroot/docs/_build/html/_sources/developer_documentation.rst.txt +26 -0
  191. mindroot/docs/_build/html/_sources/getting_started.rst.txt +139 -0
  192. mindroot/docs/_build/html/_sources/index.rst.txt +38 -0
  193. mindroot/docs/_build/html/_sources/install_plugins_with_tools.rst.txt +25 -0
  194. mindroot/docs/_build/html/_sources/installation.rst.txt +21 -0
  195. mindroot/docs/_build/html/_sources/llm_api_key.rst.txt +22 -0
  196. mindroot/docs/_build/html/_sources/llm_plugin_installation.rst.txt +27 -0
  197. mindroot/docs/_build/html/_sources/programming_task.rst.txt +10 -0
  198. mindroot/docs/_build/html/_sources/source/ahp.rst.txt +7 -0
  199. mindroot/docs/_build/html/_sources/source/mindroot.coreplugins.admin.rst.txt +189 -0
  200. mindroot/docs/_build/html/_sources/source/mindroot.coreplugins.api_keys.rst.txt +45 -0
  201. mindroot/docs/_build/html/_sources/source/mindroot.coreplugins.chat.rst.txt +93 -0
  202. mindroot/docs/_build/html/_sources/source/mindroot.coreplugins.chat_avatar.rst.txt +10 -0
  203. mindroot/docs/_build/html/_sources/source/mindroot.coreplugins.check_list.rst.txt +21 -0
  204. mindroot/docs/_build/html/_sources/source/mindroot.coreplugins.credits.rst.txt +61 -0
  205. mindroot/docs/_build/html/_sources/source/mindroot.coreplugins.email.rst.txt +77 -0
  206. mindroot/docs/_build/html/_sources/source/mindroot.coreplugins.env_manager.rst.txt +29 -0
  207. mindroot/docs/_build/html/_sources/source/mindroot.coreplugins.events.rst.txt +29 -0
  208. mindroot/docs/_build/html/_sources/source/mindroot.coreplugins.index.handlers.rst.txt +45 -0
  209. mindroot/docs/_build/html/_sources/source/mindroot.coreplugins.index.rst.txt +53 -0
  210. mindroot/docs/_build/html/_sources/source/mindroot.coreplugins.jwt_auth.rst.txt +45 -0
  211. mindroot/docs/_build/html/_sources/source/mindroot.coreplugins.l8n.rst.txt +109 -0
  212. mindroot/docs/_build/html/_sources/source/mindroot.coreplugins.mcp_.rst.txt +93 -0
  213. mindroot/docs/_build/html/_sources/source/mindroot.coreplugins.persona.rst.txt +29 -0
  214. mindroot/docs/_build/html/_sources/source/mindroot.coreplugins.rst.txt +35 -0
  215. mindroot/docs/_build/html/_sources/source/mindroot.coreplugins.startup.rst.txt +21 -0
  216. mindroot/docs/_build/html/_sources/source/mindroot.coreplugins.subscriptions.rst.txt +85 -0
  217. mindroot/docs/_build/html/_sources/source/mindroot.coreplugins.usage.rst.txt +61 -0
  218. mindroot/docs/_build/html/_sources/source/mindroot.coreplugins.user_service.rst.txt +69 -0
  219. mindroot/docs/_build/html/_sources/source/mindroot.lib.auth.rst.txt +29 -0
  220. mindroot/docs/_build/html/_sources/source/mindroot.lib.json_str_block.rst.txt +21 -0
  221. mindroot/docs/_build/html/_sources/source/mindroot.lib.plugins.rst.txt +69 -0
  222. mindroot/docs/_build/html/_sources/source/mindroot.lib.providers.backup.rst.txt +10 -0
  223. mindroot/docs/_build/html/_sources/source/mindroot.lib.providers.rst.txt +61 -0
  224. mindroot/docs/_build/html/_sources/source/mindroot.lib.rst.txt +152 -0
  225. mindroot/docs/_build/html/_sources/source/mindroot.registry.rst.txt +29 -0
  226. mindroot/docs/_build/html/_sources/source/mindroot.rst.txt +54 -0
  227. mindroot/docs/_build/html/_sources/source/modules.rst.txt +7 -0
  228. mindroot/docs/_build/html/_sources/source/mr_agent_expert_instr.rst.txt +7 -0
  229. mindroot/docs/_build/html/_sources/starting_mindroot.rst.txt +12 -0
  230. mindroot/docs/_build/html/_sources/user_documentation.rst.txt +16 -0
  231. mindroot/docs/_build/html/_static/_sphinx_javascript_frameworks_compat.js +123 -0
  232. mindroot/docs/_build/html/_static/basic.css +906 -0
  233. mindroot/docs/_build/html/_static/css/badge_only.css +1 -0
  234. mindroot/docs/_build/html/_static/css/fonts/Roboto-Slab-Bold.woff +0 -0
  235. mindroot/docs/_build/html/_static/css/fonts/Roboto-Slab-Bold.woff2 +0 -0
  236. mindroot/docs/_build/html/_static/css/fonts/Roboto-Slab-Regular.woff +0 -0
  237. mindroot/docs/_build/html/_static/css/fonts/Roboto-Slab-Regular.woff2 +0 -0
  238. mindroot/docs/_build/html/_static/css/fonts/fontawesome-webfont.eot +0 -0
  239. mindroot/docs/_build/html/_static/css/fonts/fontawesome-webfont.svg +2671 -0
  240. mindroot/docs/_build/html/_static/css/fonts/fontawesome-webfont.ttf +0 -0
  241. mindroot/docs/_build/html/_static/css/fonts/fontawesome-webfont.woff +0 -0
  242. mindroot/docs/_build/html/_static/css/fonts/fontawesome-webfont.woff2 +0 -0
  243. mindroot/docs/_build/html/_static/css/fonts/lato-bold-italic.woff +0 -0
  244. mindroot/docs/_build/html/_static/css/fonts/lato-bold-italic.woff2 +0 -0
  245. mindroot/docs/_build/html/_static/css/fonts/lato-bold.woff +0 -0
  246. mindroot/docs/_build/html/_static/css/fonts/lato-bold.woff2 +0 -0
  247. mindroot/docs/_build/html/_static/css/fonts/lato-normal-italic.woff +0 -0
  248. mindroot/docs/_build/html/_static/css/fonts/lato-normal-italic.woff2 +0 -0
  249. mindroot/docs/_build/html/_static/css/fonts/lato-normal.woff +0 -0
  250. mindroot/docs/_build/html/_static/css/fonts/lato-normal.woff2 +0 -0
  251. mindroot/docs/_build/html/_static/css/theme.css +4 -0
  252. mindroot/docs/_build/html/_static/custom.css +19 -0
  253. mindroot/docs/_build/html/_static/debug.css +69 -0
  254. mindroot/docs/_build/html/_static/doctools.js +149 -0
  255. mindroot/docs/_build/html/_static/documentation_options.js +13 -0
  256. mindroot/docs/_build/html/_static/file.png +0 -0
  257. mindroot/docs/_build/html/_static/fonts/Lato/lato-bold.eot +0 -0
  258. mindroot/docs/_build/html/_static/fonts/Lato/lato-bold.ttf +0 -0
  259. mindroot/docs/_build/html/_static/fonts/Lato/lato-bold.woff +0 -0
  260. mindroot/docs/_build/html/_static/fonts/Lato/lato-bold.woff2 +0 -0
  261. mindroot/docs/_build/html/_static/fonts/Lato/lato-bolditalic.eot +0 -0
  262. mindroot/docs/_build/html/_static/fonts/Lato/lato-bolditalic.ttf +0 -0
  263. mindroot/docs/_build/html/_static/fonts/Lato/lato-bolditalic.woff +0 -0
  264. mindroot/docs/_build/html/_static/fonts/Lato/lato-bolditalic.woff2 +0 -0
  265. mindroot/docs/_build/html/_static/fonts/Lato/lato-italic.eot +0 -0
  266. mindroot/docs/_build/html/_static/fonts/Lato/lato-italic.ttf +0 -0
  267. mindroot/docs/_build/html/_static/fonts/Lato/lato-italic.woff +0 -0
  268. mindroot/docs/_build/html/_static/fonts/Lato/lato-italic.woff2 +0 -0
  269. mindroot/docs/_build/html/_static/fonts/Lato/lato-regular.eot +0 -0
  270. mindroot/docs/_build/html/_static/fonts/Lato/lato-regular.ttf +0 -0
  271. mindroot/docs/_build/html/_static/fonts/Lato/lato-regular.woff +0 -0
  272. mindroot/docs/_build/html/_static/fonts/Lato/lato-regular.woff2 +0 -0
  273. mindroot/docs/_build/html/_static/fonts/RobotoSlab/roboto-slab-v7-bold.eot +0 -0
  274. mindroot/docs/_build/html/_static/fonts/RobotoSlab/roboto-slab-v7-bold.ttf +0 -0
  275. mindroot/docs/_build/html/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff +0 -0
  276. mindroot/docs/_build/html/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff2 +0 -0
  277. mindroot/docs/_build/html/_static/fonts/RobotoSlab/roboto-slab-v7-regular.eot +0 -0
  278. mindroot/docs/_build/html/_static/fonts/RobotoSlab/roboto-slab-v7-regular.ttf +0 -0
  279. mindroot/docs/_build/html/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff +0 -0
  280. mindroot/docs/_build/html/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff2 +0 -0
  281. mindroot/docs/_build/html/_static/jquery.js +2 -0
  282. mindroot/docs/_build/html/_static/js/badge_only.js +1 -0
  283. mindroot/docs/_build/html/_static/js/theme.js +1 -0
  284. mindroot/docs/_build/html/_static/js/versions.js +228 -0
  285. mindroot/docs/_build/html/_static/language_data.js +192 -0
  286. mindroot/docs/_build/html/_static/minus.png +0 -0
  287. mindroot/docs/_build/html/_static/plus.png +0 -0
  288. mindroot/docs/_build/html/_static/pygments.css +232 -0
  289. mindroot/docs/_build/html/_static/scripts/furo-extensions.js +0 -0
  290. mindroot/docs/_build/html/_static/scripts/furo.js +3 -0
  291. mindroot/docs/_build/html/_static/scripts/furo.js.LICENSE.txt +7 -0
  292. mindroot/docs/_build/html/_static/scripts/furo.js.map +1 -0
  293. mindroot/docs/_build/html/_static/searchtools.js +635 -0
  294. mindroot/docs/_build/html/_static/skeleton.css +296 -0
  295. mindroot/docs/_build/html/_static/sphinx_highlight.js +154 -0
  296. mindroot/docs/_build/html/_static/styles/furo-extensions.css +2 -0
  297. mindroot/docs/_build/html/_static/styles/furo-extensions.css.map +1 -0
  298. mindroot/docs/_build/html/_static/styles/furo.css +2 -0
  299. mindroot/docs/_build/html/_static/styles/furo.css.map +1 -0
  300. mindroot/docs/_build/html/chat_with_assistant.html +329 -0
  301. mindroot/docs/_build/html/developer_documentation.html +338 -0
  302. mindroot/docs/_build/html/genindex.html +4690 -0
  303. mindroot/docs/_build/html/getting_started.html +423 -0
  304. mindroot/docs/_build/html/index.html +357 -0
  305. mindroot/docs/_build/html/install_plugins_with_tools.html +336 -0
  306. mindroot/docs/_build/html/installation.html +330 -0
  307. mindroot/docs/_build/html/llm_api_key.html +337 -0
  308. mindroot/docs/_build/html/llm_plugin_installation.html +338 -0
  309. mindroot/docs/_build/html/objects.inv +0 -0
  310. mindroot/docs/_build/html/programming_task.html +326 -0
  311. mindroot/docs/_build/html/py-modindex.html +1307 -0
  312. mindroot/docs/_build/html/search.html +307 -0
  313. mindroot/docs/_build/html/searchindex.js +1 -0
  314. mindroot/docs/_build/html/source/ahp.html +302 -0
  315. mindroot/docs/_build/html/source/mindroot.coreplugins.admin.html +2212 -0
  316. mindroot/docs/_build/html/source/mindroot.coreplugins.api_keys.html +532 -0
  317. mindroot/docs/_build/html/source/mindroot.coreplugins.chat.html +1185 -0
  318. mindroot/docs/_build/html/source/mindroot.coreplugins.chat_avatar.html +311 -0
  319. mindroot/docs/_build/html/source/mindroot.coreplugins.check_list.html +441 -0
  320. mindroot/docs/_build/html/source/mindroot.coreplugins.credits.html +879 -0
  321. mindroot/docs/_build/html/source/mindroot.coreplugins.email.html +554 -0
  322. mindroot/docs/_build/html/source/mindroot.coreplugins.env_manager.html +447 -0
  323. mindroot/docs/_build/html/source/mindroot.coreplugins.events.html +338 -0
  324. mindroot/docs/_build/html/source/mindroot.coreplugins.html +1785 -0
  325. mindroot/docs/_build/html/source/mindroot.coreplugins.index.handlers.html +481 -0
  326. mindroot/docs/_build/html/source/mindroot.coreplugins.index.html +696 -0
  327. mindroot/docs/_build/html/source/mindroot.coreplugins.jwt_auth.html +432 -0
  328. mindroot/docs/_build/html/source/mindroot.coreplugins.l8n.html +933 -0
  329. mindroot/docs/_build/html/source/mindroot.coreplugins.mcp_.html +1271 -0
  330. mindroot/docs/_build/html/source/mindroot.coreplugins.persona.html +386 -0
  331. mindroot/docs/_build/html/source/mindroot.coreplugins.startup.html +327 -0
  332. mindroot/docs/_build/html/source/mindroot.coreplugins.subscriptions.html +1631 -0
  333. mindroot/docs/_build/html/source/mindroot.coreplugins.usage.html +677 -0
  334. mindroot/docs/_build/html/source/mindroot.coreplugins.user_service.html +681 -0
  335. mindroot/docs/_build/html/source/mindroot.html +811 -0
  336. mindroot/docs/_build/html/source/mindroot.lib.auth.html +407 -0
  337. mindroot/docs/_build/html/source/mindroot.lib.html +2027 -0
  338. mindroot/docs/_build/html/source/mindroot.lib.json_str_block.html +344 -0
  339. mindroot/docs/_build/html/source/mindroot.lib.plugins.html +1050 -0
  340. mindroot/docs/_build/html/source/mindroot.lib.providers.backup.html +324 -0
  341. mindroot/docs/_build/html/source/mindroot.lib.providers.html +572 -0
  342. mindroot/docs/_build/html/source/mindroot.registry.html +501 -0
  343. mindroot/docs/_build/html/source/modules.html +377 -0
  344. mindroot/docs/_build/html/source/mr_agent_expert_instr.html +302 -0
  345. mindroot/docs/_build/html/starting_mindroot.html +325 -0
  346. mindroot/docs/_build/html/user_documentation.html +333 -0
  347. mindroot/docs/_static/custom.css +19 -0
  348. mindroot/docs/chat_with_assistant.rst +14 -0
  349. mindroot/docs/conf.py +54 -0
  350. mindroot/docs/data/agents/local/Assistant/agent.json +27 -0
  351. mindroot/docs/data/agents/local/SysAdmin/agent.json +33 -0
  352. mindroot/docs/data/equivalent_flags.json +1 -0
  353. mindroot/docs/data/mcp/servers.json +9 -0
  354. mindroot/docs/data/models.json +57 -0
  355. mindroot/docs/data/plugin_manifest.json +95 -0
  356. mindroot/docs/data/preferred_models.json +12 -0
  357. mindroot/docs/data/providers.json +62 -0
  358. mindroot/docs/developer_documentation.rst +26 -0
  359. mindroot/docs/envvar.png +0 -0
  360. mindroot/docs/files.png +0 -0
  361. mindroot/docs/getting_started.rst +139 -0
  362. mindroot/docs/index.rst +38 -0
  363. mindroot/docs/install_plugins_with_tools.rst +25 -0
  364. mindroot/docs/installation.rst +21 -0
  365. mindroot/docs/installopenrouter.png +0 -0
  366. mindroot/docs/llm_api_key.rst +22 -0
  367. mindroot/docs/llm_plugin_installation.rst +27 -0
  368. mindroot/docs/make.bat +35 -0
  369. mindroot/docs/mood.png +0 -0
  370. mindroot/docs/moon.png +0 -0
  371. mindroot/docs/openrouter.png +0 -0
  372. mindroot/docs/personas/local/Assistant/avatar.png +0 -0
  373. mindroot/docs/personas/local/Assistant/faceref.png +0 -0
  374. mindroot/docs/personas/local/Assistant/persona.json +7 -0
  375. mindroot/docs/programming_task.rst +10 -0
  376. mindroot/docs/restart.png +0 -0
  377. mindroot/docs/source/ahp.rst +7 -0
  378. mindroot/docs/source/mindroot.coreplugins.admin.rst +189 -0
  379. mindroot/docs/source/mindroot.coreplugins.api_keys.rst +45 -0
  380. mindroot/docs/source/mindroot.coreplugins.chat.rst +93 -0
  381. mindroot/docs/source/mindroot.coreplugins.chat_avatar.rst +10 -0
  382. mindroot/docs/source/mindroot.coreplugins.check_list.rst +21 -0
  383. mindroot/docs/source/mindroot.coreplugins.credits.rst +61 -0
  384. mindroot/docs/source/mindroot.coreplugins.email.rst +77 -0
  385. mindroot/docs/source/mindroot.coreplugins.env_manager.rst +29 -0
  386. mindroot/docs/source/mindroot.coreplugins.events.rst +29 -0
  387. mindroot/docs/source/mindroot.coreplugins.index.handlers.rst +45 -0
  388. mindroot/docs/source/mindroot.coreplugins.index.rst +53 -0
  389. mindroot/docs/source/mindroot.coreplugins.jwt_auth.rst +45 -0
  390. mindroot/docs/source/mindroot.coreplugins.l8n.rst +109 -0
  391. mindroot/docs/source/mindroot.coreplugins.mcp_.rst +93 -0
  392. mindroot/docs/source/mindroot.coreplugins.persona.rst +29 -0
  393. mindroot/docs/source/mindroot.coreplugins.rst +35 -0
  394. mindroot/docs/source/mindroot.coreplugins.startup.rst +21 -0
  395. mindroot/docs/source/mindroot.coreplugins.subscriptions.rst +85 -0
  396. mindroot/docs/source/mindroot.coreplugins.usage.rst +61 -0
  397. mindroot/docs/source/mindroot.coreplugins.user_service.rst +69 -0
  398. mindroot/docs/source/mindroot.lib.auth.rst +29 -0
  399. mindroot/docs/source/mindroot.lib.json_str_block.rst +21 -0
  400. mindroot/docs/source/mindroot.lib.plugins.rst +69 -0
  401. mindroot/docs/source/mindroot.lib.providers.backup.rst +10 -0
  402. mindroot/docs/source/mindroot.lib.providers.rst +61 -0
  403. mindroot/docs/source/mindroot.lib.rst +152 -0
  404. mindroot/docs/source/mindroot.registry.rst +29 -0
  405. mindroot/docs/source/mindroot.rst +54 -0
  406. mindroot/docs/source/modules.rst +7 -0
  407. mindroot/docs/source/mr_agent_expert_instr.rst +7 -0
  408. mindroot/docs/starting_mindroot.rst +12 -0
  409. mindroot/docs/user_documentation.rst +16 -0
  410. mindroot/lib/providers/model_preferences_v2.py +5 -3
  411. mindroot/server.py +10 -1
  412. {mindroot-9.11.0.dist-info → mindroot-9.13.0.dist-info}/METADATA +1 -1
  413. {mindroot-9.11.0.dist-info → mindroot-9.13.0.dist-info}/RECORD +417 -10
  414. {mindroot-9.11.0.dist-info → mindroot-9.13.0.dist-info}/WHEEL +0 -0
  415. {mindroot-9.11.0.dist-info → mindroot-9.13.0.dist-info}/entry_points.txt +0 -0
  416. {mindroot-9.11.0.dist-info → mindroot-9.13.0.dist-info}/licenses/LICENSE +0 -0
  417. {mindroot-9.11.0.dist-info → mindroot-9.13.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,677 @@
1
+
2
+
3
+ <!DOCTYPE html>
4
+ <html class="writer-html5" lang="en" data-content_root="../../../">
5
+ <head>
6
+ <meta charset="utf-8" />
7
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
8
+ <title>mindroot.lib.templates &mdash; MindRoot 9.10.0 documentation</title>
9
+ <link rel="stylesheet" type="text/css" href="../../../_static/pygments.css?v=b86133f3" />
10
+ <link rel="stylesheet" type="text/css" href="../../../_static/css/theme.css?v=e59714d7" />
11
+
12
+
13
+ <script src="../../../_static/jquery.js?v=5d32c60e"></script>
14
+ <script src="../../../_static/_sphinx_javascript_frameworks_compat.js?v=2cd50e6c"></script>
15
+ <script src="../../../_static/documentation_options.js?v=3c16008f"></script>
16
+ <script src="../../../_static/doctools.js?v=9bcbadda"></script>
17
+ <script src="../../../_static/sphinx_highlight.js?v=dc90522c"></script>
18
+ <script src="../../../_static/js/theme.js"></script>
19
+ <link rel="index" title="Index" href="../../../genindex.html" />
20
+ <link rel="search" title="Search" href="../../../search.html" />
21
+ </head>
22
+
23
+ <body class="wy-body-for-nav">
24
+ <div class="wy-grid-for-nav">
25
+ <nav data-toggle="wy-nav-shift" class="wy-nav-side">
26
+ <div class="wy-side-scroll">
27
+ <div class="wy-side-nav-search" style="background: #343131" >
28
+
29
+
30
+
31
+ <a href="../../../index.html" class="icon icon-home">
32
+ MindRoot
33
+ </a>
34
+ <div role="search">
35
+ <form id="rtd-search-form" class="wy-form" action="../../../search.html" method="get">
36
+ <input type="text" name="q" placeholder="Search docs" aria-label="Search docs" />
37
+ <input type="hidden" name="check_keywords" value="yes" />
38
+ <input type="hidden" name="area" value="default" />
39
+ </form>
40
+ </div>
41
+ </div><div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="Navigation menu">
42
+ <!-- Local TOC -->
43
+ <div class="local-toc"></div>
44
+ </div>
45
+ </div>
46
+ </nav>
47
+
48
+ <section data-toggle="wy-nav-shift" class="wy-nav-content-wrap"><nav class="wy-nav-top" aria-label="Mobile navigation menu" style="background: #343131" >
49
+ <i data-toggle="wy-nav-top" class="fa fa-bars"></i>
50
+ <a href="../../../index.html">MindRoot</a>
51
+ </nav>
52
+
53
+ <div class="wy-nav-content">
54
+ <div class="rst-content">
55
+ <div role="navigation" aria-label="Page navigation">
56
+ <ul class="wy-breadcrumbs">
57
+ <li><a href="../../../index.html" class="icon icon-home" aria-label="Home"></a></li>
58
+ <li class="breadcrumb-item"><a href="../../index.html">Module code</a></li>
59
+ <li class="breadcrumb-item active">mindroot.lib.templates</li>
60
+ <li class="wy-breadcrumbs-aside">
61
+ </li>
62
+ </ul>
63
+ <hr/>
64
+ </div>
65
+ <div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
66
+ <div itemprop="articleBody">
67
+
68
+ <h1>Source code for mindroot.lib.templates</h1><div class="highlight"><pre>
69
+ <span></span><span class="kn">import</span><span class="w"> </span><span class="nn">os</span>
70
+ <span class="kn">import</span><span class="w"> </span><span class="nn">logging</span>
71
+ <span class="kn">from</span><span class="w"> </span><span class="nn">jinja2</span><span class="w"> </span><span class="kn">import</span> <span class="n">Environment</span><span class="p">,</span> <span class="n">FileSystemLoader</span><span class="p">,</span> <span class="n">ChoiceLoader</span>
72
+ <span class="kn">from</span><span class="w"> </span><span class="nn">.plugins</span><span class="w"> </span><span class="kn">import</span> <span class="n">list_enabled</span><span class="p">,</span> <span class="n">get_plugin_path</span>
73
+ <span class="kn">from</span><span class="w"> </span><span class="nn">.parent_templates</span><span class="w"> </span><span class="kn">import</span> <span class="n">get_parent_templates_env</span>
74
+ <span class="kn">import</span><span class="w"> </span><span class="nn">traceback</span>
75
+ <span class="kn">import</span><span class="w"> </span><span class="nn">sys</span>
76
+
77
+ <span class="c1"># Import l8n translation functions</span>
78
+ <span class="k">try</span><span class="p">:</span>
79
+ <span class="kn">from</span><span class="w"> </span><span class="nn">mindroot.coreplugins.l8n.utils</span><span class="w"> </span><span class="kn">import</span> <span class="n">replace_placeholders</span><span class="p">,</span> <span class="n">get_localized_file_path</span><span class="p">,</span> <span class="n">extract_plugin_root</span>
80
+ <span class="kn">from</span><span class="w"> </span><span class="nn">mindroot.coreplugins.l8n.mod</span><span class="w"> </span><span class="kn">import</span> <span class="o">*</span>
81
+ <span class="kn">from</span><span class="w"> </span><span class="nn">mindroot.coreplugins.l8n.middleware</span><span class="w"> </span><span class="kn">import</span> <span class="n">get_request_language</span>
82
+ <span class="kn">from</span><span class="w"> </span><span class="nn">mindroot.coreplugins.l8n.language_detection</span><span class="w"> </span><span class="kn">import</span> <span class="n">get_fallback_language</span>
83
+ <span class="n">L8N_AVAILABLE</span> <span class="o">=</span> <span class="kc">True</span>
84
+ <span class="k">except</span> <span class="ne">ImportError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
85
+ <span class="n">trace</span> <span class="o">=</span> <span class="n">traceback</span><span class="o">.</span><span class="n">format_exc</span><span class="p">()</span>
86
+ <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;L8n not available: </span><span class="si">{</span><span class="n">e</span><span class="si">}</span><span class="s2"> </span><span class="se">\n</span><span class="si">{</span><span class="n">trace</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
87
+ <span class="n">L8N_AVAILABLE</span> <span class="o">=</span> <span class="kc">False</span>
88
+ <span class="n">sys</span><span class="o">.</span><span class="n">exit</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
89
+
90
+ <span class="c1"># TODO: get_parent_templates_env(plugins):</span>
91
+ <span class="c1"># jinja2 environment containing only 1 template per plugin file name,</span>
92
+ <span class="c1"># the first one that is found from plugins with that name,</span>
93
+ <span class="c1"># need to look at how jinja2 loaders work</span>
94
+
95
+ <div class="viewcode-block" id="get_current_language">
96
+ <a class="viewcode-back" href="../../../source/mindroot.lib.html#mindroot.lib.templates.get_current_language">[docs]</a>
97
+ <span class="k">def</span><span class="w"> </span><span class="nf">get_current_language</span><span class="p">():</span>
98
+ <span class="w"> </span><span class="sd">&quot;&quot;&quot;Get the current language for translation.&quot;&quot;&quot;</span>
99
+ <span class="k">if</span> <span class="ow">not</span> <span class="n">L8N_AVAILABLE</span><span class="p">:</span>
100
+ <span class="k">return</span> <span class="s1">&#39;en&#39;</span>
101
+
102
+ <span class="k">try</span><span class="p">:</span>
103
+ <span class="c1"># Try to get language from request context</span>
104
+ <span class="n">lang</span> <span class="o">=</span> <span class="n">get_request_language</span><span class="p">()</span>
105
+ <span class="k">return</span> <span class="n">get_fallback_language</span><span class="p">(</span><span class="n">lang</span><span class="p">)</span> <span class="k">if</span> <span class="n">lang</span> <span class="k">else</span> <span class="s1">&#39;en&#39;</span>
106
+ <span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
107
+ <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Error getting current language: </span><span class="si">{</span><span class="n">e</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
108
+ <span class="k">return</span> <span class="s1">&#39;en&#39;</span></div>
109
+
110
+
111
+ <div class="viewcode-block" id="apply_translations_to_content">
112
+ <a class="viewcode-back" href="../../../source/mindroot.lib.html#mindroot.lib.templates.apply_translations_to_content">[docs]</a>
113
+ <span class="k">def</span><span class="w"> </span><span class="nf">apply_translations_to_content</span><span class="p">(</span><span class="n">content</span><span class="p">,</span> <span class="n">template_path</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
114
+ <span class="w"> </span><span class="sd">&quot;&quot;&quot;Apply l8n translations to template content.</span>
115
+ <span class="sd"> </span>
116
+ <span class="sd"> Args:</span>
117
+ <span class="sd"> content (str): Template content with __TRANSLATE_key__ placeholders</span>
118
+ <span class="sd"> template_path (str): Path to the template file for plugin context</span>
119
+ <span class="sd"> </span>
120
+ <span class="sd"> Returns:</span>
121
+ <span class="sd"> str or None: Content with translations applied, or None if translations are incomplete</span>
122
+ <span class="sd"> &quot;&quot;&quot;</span>
123
+ <span class="k">if</span> <span class="ow">not</span> <span class="n">L8N_AVAILABLE</span> <span class="ow">or</span> <span class="ow">not</span> <span class="n">content</span><span class="p">:</span>
124
+ <span class="k">return</span> <span class="n">content</span>
125
+
126
+ <span class="k">try</span><span class="p">:</span>
127
+ <span class="n">current_language</span> <span class="o">=</span> <span class="n">get_current_language</span><span class="p">()</span>
128
+
129
+ <span class="c1"># If we have a template path, use it for plugin context</span>
130
+ <span class="k">if</span> <span class="n">template_path</span><span class="p">:</span>
131
+ <span class="c1"># Check if translation failed (missing translations)</span>
132
+ <span class="n">translated</span> <span class="o">=</span> <span class="n">replace_placeholders</span><span class="p">(</span><span class="n">content</span><span class="p">,</span> <span class="n">current_language</span><span class="p">,</span> <span class="n">template_path</span><span class="p">)</span>
133
+ <span class="k">if</span> <span class="n">translated</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
134
+ <span class="k">return</span> <span class="kc">None</span> <span class="c1"># Signal that translations are incomplete</span>
135
+ <span class="k">return</span> <span class="n">translated</span>
136
+ <span class="k">else</span><span class="p">:</span>
137
+ <span class="c1"># Fallback: try to replace without plugin context</span>
138
+ <span class="k">return</span> <span class="n">replace_placeholders</span><span class="p">(</span><span class="n">content</span><span class="p">,</span> <span class="n">current_language</span><span class="p">)</span>
139
+ <span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
140
+ <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Error applying translations: </span><span class="si">{</span><span class="n">e</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
141
+ <span class="k">return</span> <span class="n">content</span></div>
142
+
143
+
144
+ <div class="viewcode-block" id="check_for_localized_template">
145
+ <a class="viewcode-back" href="../../../source/mindroot.lib.html#mindroot.lib.templates.check_for_localized_template">[docs]</a>
146
+ <span class="k">def</span><span class="w"> </span><span class="nf">check_for_localized_template</span><span class="p">(</span><span class="n">template_path</span><span class="p">):</span>
147
+ <span class="w"> </span><span class="sd">&quot;&quot;&quot;Check if a localized version of a template exists.</span>
148
+ <span class="sd"> </span>
149
+ <span class="sd"> Args:</span>
150
+ <span class="sd"> template_path (str): Original template path</span>
151
+ <span class="sd"> </span>
152
+ <span class="sd"> Returns:</span>
153
+ <span class="sd"> str: Path to localized template if it exists, None otherwise</span>
154
+ <span class="sd"> &quot;&quot;&quot;</span>
155
+ <span class="k">if</span> <span class="ow">not</span> <span class="n">L8N_AVAILABLE</span><span class="p">:</span>
156
+ <span class="k">return</span> <span class="kc">None</span>
157
+
158
+ <span class="k">try</span><span class="p">:</span>
159
+ <span class="n">localized_path</span> <span class="o">=</span> <span class="n">get_localized_file_path</span><span class="p">(</span><span class="n">template_path</span><span class="p">)</span>
160
+ <span class="k">if</span> <span class="n">localized_path</span><span class="o">.</span><span class="n">exists</span><span class="p">():</span>
161
+ <span class="k">return</span> <span class="nb">str</span><span class="p">(</span><span class="n">localized_path</span><span class="p">)</span>
162
+ <span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
163
+ <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Error checking for localized template: </span><span class="si">{</span><span class="n">e</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
164
+
165
+ <span class="k">return</span> <span class="kc">None</span></div>
166
+
167
+
168
+ <div class="viewcode-block" id="load_template_with_translation">
169
+ <a class="viewcode-back" href="../../../source/mindroot.lib.html#mindroot.lib.templates.load_template_with_translation">[docs]</a>
170
+ <span class="k">def</span><span class="w"> </span><span class="nf">load_template_with_translation</span><span class="p">(</span><span class="n">template_path</span><span class="p">):</span>
171
+ <span class="w"> </span><span class="sd">&quot;&quot;&quot;Load a template and apply translations if available and complete.</span>
172
+ <span class="sd"> </span>
173
+ <span class="sd"> If translations are missing for the current language, this function</span>
174
+ <span class="sd"> will fall back to serving the original template to avoid showing</span>
175
+ <span class="sd"> __TRANSLATE_key__ placeholders to users.</span>
176
+ <span class="sd"> </span>
177
+ <span class="sd"> Args:</span>
178
+ <span class="sd"> template_path (str): Path to the template file</span>
179
+ <span class="sd"> </span>
180
+ <span class="sd"> Returns:</span>
181
+ <span class="sd"> str: Template content with translations applied, or original content</span>
182
+ <span class="sd"> if translations are incomplete for the current language</span>
183
+ <span class="sd"> &quot;&quot;&quot;</span>
184
+ <span class="c1"># First check for localized version</span>
185
+ <span class="n">localized_path</span> <span class="o">=</span> <span class="n">check_for_localized_template</span><span class="p">(</span><span class="n">template_path</span><span class="p">)</span>
186
+
187
+ <span class="k">if</span> <span class="n">localized_path</span><span class="p">:</span>
188
+ <span class="c1"># Load localized template and apply translations</span>
189
+ <span class="k">try</span><span class="p">:</span>
190
+ <span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">localized_path</span><span class="p">,</span> <span class="s1">&#39;r&#39;</span><span class="p">,</span> <span class="n">encoding</span><span class="o">=</span><span class="s1">&#39;utf-8&#39;</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
191
+ <span class="n">content</span> <span class="o">=</span> <span class="n">f</span><span class="o">.</span><span class="n">read</span><span class="p">()</span>
192
+
193
+ <span class="c1"># Apply translations - if None is returned, translations are incomplete</span>
194
+ <span class="n">translated_content</span> <span class="o">=</span> <span class="n">apply_translations_to_content</span><span class="p">(</span><span class="n">content</span><span class="p">,</span> <span class="n">localized_path</span><span class="p">)</span>
195
+ <span class="k">if</span> <span class="n">translated_content</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
196
+ <span class="c1"># Fall back to original template</span>
197
+ <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;L8n: Falling back to original template due to missing translations: </span><span class="si">{</span><span class="n">template_path</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
198
+ <span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">template_path</span><span class="p">,</span> <span class="s1">&#39;r&#39;</span><span class="p">,</span> <span class="n">encoding</span><span class="o">=</span><span class="s1">&#39;utf-8&#39;</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
199
+ <span class="k">return</span> <span class="n">f</span><span class="o">.</span><span class="n">read</span><span class="p">()</span>
200
+ <span class="k">return</span> <span class="n">translated_content</span>
201
+ <span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
202
+ <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Error loading localized template </span><span class="si">{</span><span class="n">localized_path</span><span class="si">}</span><span class="s2">: </span><span class="si">{</span><span class="n">e</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
203
+
204
+ <span class="c1"># Fallback to original template</span>
205
+ <span class="k">try</span><span class="p">:</span>
206
+ <span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">template_path</span><span class="p">,</span> <span class="s1">&#39;r&#39;</span><span class="p">,</span> <span class="n">encoding</span><span class="o">=</span><span class="s1">&#39;utf-8&#39;</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
207
+ <span class="n">content</span> <span class="o">=</span> <span class="n">f</span><span class="o">.</span><span class="n">read</span><span class="p">()</span>
208
+ <span class="k">return</span> <span class="n">content</span> <span class="c1"># Don&#39;t apply translations to original templates</span>
209
+ <span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
210
+ <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Error loading template </span><span class="si">{</span><span class="n">template_path</span><span class="si">}</span><span class="s2">: </span><span class="si">{</span><span class="n">e</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
211
+ <span class="k">return</span> <span class="s2">&quot;&quot;</span></div>
212
+
213
+
214
+ <div class="viewcode-block" id="setup_template_environment">
215
+ <a class="viewcode-back" href="../../../source/mindroot.lib.html#mindroot.lib.templates.setup_template_environment">[docs]</a>
216
+ <span class="k">def</span><span class="w"> </span><span class="nf">setup_template_environment</span><span class="p">(</span><span class="n">plugins</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
217
+ <span class="w"> </span><span class="sd">&quot;&quot;&quot;Set up Jinja2 environment with multiple template paths.</span>
218
+ <span class="sd"> </span>
219
+ <span class="sd"> Returns:</span>
220
+ <span class="sd"> Environment: Configured Jinja2 environment</span>
221
+ <span class="sd"> &quot;&quot;&quot;</span>
222
+ <span class="k">if</span> <span class="n">plugins</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
223
+ <span class="n">plugins</span> <span class="o">=</span> <span class="n">list_enabled</span><span class="p">(</span><span class="kc">False</span><span class="p">)</span>
224
+ <span class="n">template_paths</span> <span class="o">=</span> <span class="nb">set</span><span class="p">([</span><span class="s1">&#39;templates&#39;</span><span class="p">])</span> <span class="c1"># Start with default templates directory</span>
225
+
226
+ <span class="c1"># Add plugin template paths</span>
227
+ <span class="k">for</span> <span class="n">plugin</span> <span class="ow">in</span> <span class="n">plugins</span><span class="p">:</span>
228
+ <span class="n">plugin_path</span> <span class="o">=</span> <span class="n">get_plugin_path</span><span class="p">(</span><span class="n">plugin</span><span class="p">)</span>
229
+ <span class="k">if</span> <span class="n">plugin_path</span><span class="p">:</span>
230
+ <span class="c1"># Add main template directory</span>
231
+ <span class="n">template_dir</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">plugin_path</span><span class="p">,</span> <span class="s1">&#39;templates&#39;</span><span class="p">)</span>
232
+ <span class="k">if</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="n">template_dir</span><span class="p">):</span>
233
+ <span class="n">template_paths</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">template_dir</span><span class="p">)</span>
234
+ <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Added template path: </span><span class="si">{</span><span class="n">template_dir</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
235
+
236
+ <span class="c1"># Add inject directory</span>
237
+ <span class="n">inject_dir</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">plugin_path</span><span class="p">,</span> <span class="s1">&#39;inject&#39;</span><span class="p">)</span>
238
+ <span class="k">if</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="n">inject_dir</span><span class="p">):</span>
239
+ <span class="n">template_paths</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">inject_dir</span><span class="p">)</span>
240
+ <span class="c1"># change color to green background, white text</span>
241
+ <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;</span><span class="se">\033</span><span class="s2">[92m&quot;</span> <span class="o">+</span> <span class="sa">f</span><span class="s2">&quot;Added inject path: </span><span class="si">{</span><span class="n">inject_dir</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
242
+ <span class="c1"># reset color</span>
243
+ <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;</span><span class="se">\033</span><span class="s2">[0m&quot;</span><span class="p">)</span>
244
+
245
+ <span class="c1"># Add parent directories to handle absolute paths</span>
246
+ <span class="n">template_paths</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">dirname</span><span class="p">(</span><span class="n">plugin_path</span><span class="p">))</span>
247
+ <span class="n">template_paths</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">dirname</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">dirname</span><span class="p">(</span><span class="n">plugin_path</span><span class="p">)))</span>
248
+
249
+ <span class="c1"># Create environment with multiple loaders</span>
250
+ <span class="n">loaders</span> <span class="o">=</span> <span class="p">[</span><span class="n">FileSystemLoader</span><span class="p">(</span><span class="n">path</span><span class="p">)</span> <span class="k">for</span> <span class="n">path</span> <span class="ow">in</span> <span class="n">template_paths</span><span class="p">]</span>
251
+ <span class="n">env</span> <span class="o">=</span> <span class="n">Environment</span><span class="p">(</span><span class="n">loader</span><span class="o">=</span><span class="n">ChoiceLoader</span><span class="p">(</span><span class="n">loaders</span><span class="p">))</span>
252
+ <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Initialized Jinja2 environment with paths: </span><span class="si">{</span><span class="n">template_paths</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
253
+ <span class="k">return</span> <span class="n">env</span></div>
254
+
255
+
256
+ <span class="c1"># Create a Jinja2 environment with multiple template paths</span>
257
+ <span class="n">env</span> <span class="o">=</span> <span class="n">setup_template_environment</span><span class="p">()</span>
258
+ <span class="n">coreplugins</span> <span class="o">=</span><span class="p">[</span><span class="s1">&#39;admin&#39;</span><span class="p">,</span> <span class="s1">&#39;index&#39;</span><span class="p">,</span> <span class="s1">&#39;chat&#39;</span><span class="p">,</span> <span class="s1">&#39;chat_avatar&#39;</span><span class="p">,</span> <span class="s1">&#39;agent&#39;</span><span class="p">,</span> <span class="s1">&#39;jwt_auth&#39;</span><span class="p">,</span> <span class="s1">&#39;home&#39;</span><span class="p">,</span> <span class="s1">&#39;login&#39;</span><span class="p">,</span> <span class="s1">&#39;persona&#39;</span><span class="p">,</span> <span class="s1">&#39;events&#39;</span><span class="p">,</span> <span class="s1">&#39;user_service&#39;</span><span class="p">,</span> <span class="s1">&#39;usage&#39;</span><span class="p">,</span> <span class="s1">&#39;subscriptions&#39;</span><span class="p">,</span> <span class="s1">&#39;credits&#39;</span><span class="p">,</span> <span class="s1">&#39;startup&#39;</span><span class="p">]</span>
259
+ <span class="n">parent_env</span> <span class="o">=</span> <span class="n">get_parent_templates_env</span><span class="p">(</span><span class="n">coreplugins</span><span class="p">)</span>
260
+
261
+
262
+ <div class="viewcode-block" id="find_parent_template">
263
+ <a class="viewcode-back" href="../../../source/mindroot.lib.html#mindroot.lib.templates.find_parent_template">[docs]</a>
264
+ <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">find_parent_template</span><span class="p">(</span><span class="n">page_name</span><span class="p">,</span> <span class="n">plugins</span><span class="p">):</span>
265
+ <span class="w"> </span><span class="sd">&quot;&quot;&quot;Find parent template in enabled plugins.</span>
266
+ <span class="sd"> </span>
267
+ <span class="sd"> Args:</span>
268
+ <span class="sd"> page_name (str): Name of the template page</span>
269
+ <span class="sd"> plugins (list): List of enabled plugins</span>
270
+ <span class="sd"> </span>
271
+ <span class="sd"> Returns:</span>
272
+ <span class="sd"> str: Template path if found, None otherwise</span>
273
+ <span class="sd"> &quot;&quot;&quot;</span>
274
+ <span class="k">for</span> <span class="n">plugin</span> <span class="ow">in</span> <span class="n">plugins</span><span class="p">:</span>
275
+ <span class="n">plugin_path</span> <span class="o">=</span> <span class="n">get_plugin_path</span><span class="p">(</span><span class="n">plugin</span><span class="p">)</span>
276
+ <span class="k">if</span> <span class="ow">not</span> <span class="n">plugin_path</span><span class="p">:</span>
277
+ <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s1">&#39;Warning: Could not find path for plugin: </span><span class="si">{</span><span class="n">plugin</span><span class="si">}</span><span class="s1">&#39;</span><span class="p">)</span>
278
+ <span class="k">continue</span>
279
+
280
+ <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s1">&#39;Checking plugin: </span><span class="si">{</span><span class="n">plugin</span><span class="si">}</span><span class="s1">, path: </span><span class="si">{</span><span class="n">plugin_path</span><span class="si">}</span><span class="s1">&#39;</span><span class="p">)</span>
281
+ <span class="n">template_path</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">plugin_path</span><span class="p">,</span> <span class="s1">&#39;templates&#39;</span><span class="p">,</span> <span class="sa">f</span><span class="s1">&#39;</span><span class="si">{</span><span class="n">page_name</span><span class="si">}</span><span class="s1">.jinja2&#39;</span><span class="p">)</span>
282
+
283
+ <span class="k">if</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="n">template_path</span><span class="p">):</span>
284
+ <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s1">&#39;Found parent template in plugin: </span><span class="si">{</span><span class="n">template_path</span><span class="si">}</span><span class="s1">&#39;</span><span class="p">)</span>
285
+ <span class="c1"># Convert to relative path from one of our template roots</span>
286
+ <span class="k">for</span> <span class="n">loader</span> <span class="ow">in</span> <span class="n">env</span><span class="o">.</span><span class="n">loader</span><span class="o">.</span><span class="n">loaders</span><span class="p">:</span>
287
+ <span class="k">for</span> <span class="n">template_dir</span> <span class="ow">in</span> <span class="n">loader</span><span class="o">.</span><span class="n">searchpath</span><span class="p">:</span>
288
+ <span class="n">rel_path</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">relpath</span><span class="p">(</span><span class="n">template_path</span><span class="p">,</span> <span class="n">template_dir</span><span class="p">)</span>
289
+ <span class="k">if</span> <span class="ow">not</span> <span class="n">rel_path</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s1">&#39;..&#39;</span><span class="p">):</span>
290
+ <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s1">&#39;Using template path: </span><span class="si">{</span><span class="n">rel_path</span><span class="si">}</span><span class="s1">&#39;</span><span class="p">)</span>
291
+ <span class="k">return</span> <span class="n">rel_path</span>
292
+ <span class="c1"># Fallback to absolute path if no relative path works</span>
293
+ <span class="k">return</span> <span class="n">template_path</span>
294
+ <span class="k">else</span><span class="p">:</span>
295
+ <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s1">&#39;No parent template found in plugin: </span><span class="si">{</span><span class="n">plugin</span><span class="si">}</span><span class="s1">, template path was </span><span class="si">{</span><span class="n">template_path</span><span class="si">}</span><span class="s1">&#39;</span><span class="p">)</span>
296
+
297
+ <span class="c1"># Try alternate locations</span>
298
+ <span class="n">alt_paths</span> <span class="o">=</span> <span class="p">[</span>
299
+ <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">plugin_path</span><span class="p">,</span> <span class="s1">&#39;src&#39;</span><span class="p">,</span> <span class="n">plugin</span><span class="p">,</span> <span class="s1">&#39;templates&#39;</span><span class="p">,</span> <span class="sa">f</span><span class="s1">&#39;</span><span class="si">{</span><span class="n">page_name</span><span class="si">}</span><span class="s1">.jinja2&#39;</span><span class="p">),</span>
300
+ <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">plugin_path</span><span class="p">,</span> <span class="s1">&#39;src&#39;</span><span class="p">,</span> <span class="s1">&#39;templates&#39;</span><span class="p">,</span> <span class="sa">f</span><span class="s1">&#39;</span><span class="si">{</span><span class="n">page_name</span><span class="si">}</span><span class="s1">.jinja2&#39;</span><span class="p">),</span>
301
+ <span class="p">]</span>
302
+
303
+ <span class="k">for</span> <span class="n">alt_path</span> <span class="ow">in</span> <span class="n">alt_paths</span><span class="p">:</span>
304
+ <span class="k">if</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="n">alt_path</span><span class="p">):</span>
305
+ <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s1">&#39;Found parent template in alternate location: </span><span class="si">{</span><span class="n">alt_path</span><span class="si">}</span><span class="s1">&#39;</span><span class="p">)</span>
306
+ <span class="c1"># Convert to relative path</span>
307
+ <span class="k">for</span> <span class="n">loader</span> <span class="ow">in</span> <span class="n">env</span><span class="o">.</span><span class="n">loader</span><span class="o">.</span><span class="n">loaders</span><span class="p">:</span>
308
+ <span class="k">for</span> <span class="n">template_dir</span> <span class="ow">in</span> <span class="n">loader</span><span class="o">.</span><span class="n">searchpath</span><span class="p">:</span>
309
+ <span class="n">rel_path</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">relpath</span><span class="p">(</span><span class="n">alt_path</span><span class="p">,</span> <span class="n">template_dir</span><span class="p">)</span>
310
+ <span class="k">if</span> <span class="ow">not</span> <span class="n">rel_path</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s1">&#39;..&#39;</span><span class="p">):</span>
311
+ <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s1">&#39;Using template path: </span><span class="si">{</span><span class="n">rel_path</span><span class="si">}</span><span class="s1">&#39;</span><span class="p">)</span>
312
+ <span class="k">return</span> <span class="n">rel_path</span>
313
+ <span class="k">return</span> <span class="n">alt_path</span>
314
+ <span class="k">return</span> <span class="kc">None</span></div>
315
+
316
+ <div class="viewcode-block" id="find_plugin_template">
317
+ <a class="viewcode-back" href="../../../source/mindroot.lib.html#mindroot.lib.templates.find_plugin_template">[docs]</a>
318
+ <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">find_plugin_template</span><span class="p">(</span><span class="n">page_name</span><span class="p">,</span> <span class="n">plugins</span><span class="p">):</span>
319
+ <span class="w"> </span><span class="sd">&quot;&quot;&quot;Find a template in a plugin&#39;s templates directory.</span>
320
+ <span class="sd"> </span>
321
+ <span class="sd"> Args:</span>
322
+ <span class="sd"> page_name (str): Name of the template page</span>
323
+ <span class="sd"> plugins (list): List of enabled plugins</span>
324
+ <span class="sd"> </span>
325
+ <span class="sd"> Returns:</span>
326
+ <span class="sd"> tuple: (template_path, template_obj) if found, (None, None) otherwise</span>
327
+ <span class="sd"> &quot;&quot;&quot;</span>
328
+ <span class="k">for</span> <span class="n">plugin</span> <span class="ow">in</span> <span class="n">plugins</span><span class="p">:</span>
329
+ <span class="n">plugin_path</span> <span class="o">=</span> <span class="n">get_plugin_path</span><span class="p">(</span><span class="n">plugin</span><span class="p">)</span>
330
+ <span class="k">if</span> <span class="ow">not</span> <span class="n">plugin_path</span><span class="p">:</span>
331
+ <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s1">&#39;Warning: Could not find path for plugin: </span><span class="si">{</span><span class="n">plugin</span><span class="si">}</span><span class="s1">&#39;</span><span class="p">)</span>
332
+ <span class="k">continue</span>
333
+
334
+ <span class="c1"># Try to find the template in the plugin&#39;s templates directory</span>
335
+ <span class="n">template_paths</span> <span class="o">=</span> <span class="p">[</span>
336
+ <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">plugin_path</span><span class="p">,</span> <span class="s1">&#39;templates&#39;</span><span class="p">,</span> <span class="sa">f</span><span class="s1">&#39;</span><span class="si">{</span><span class="n">page_name</span><span class="si">}</span><span class="s1">.jinja2&#39;</span><span class="p">),</span>
337
+ <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">plugin_path</span><span class="p">,</span> <span class="s1">&#39;src&#39;</span><span class="p">,</span> <span class="n">plugin</span><span class="p">,</span> <span class="s1">&#39;templates&#39;</span><span class="p">,</span> <span class="sa">f</span><span class="s1">&#39;</span><span class="si">{</span><span class="n">page_name</span><span class="si">}</span><span class="s1">.jinja2&#39;</span><span class="p">),</span>
338
+ <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">plugin_path</span><span class="p">,</span> <span class="s1">&#39;src&#39;</span><span class="p">,</span> <span class="s1">&#39;templates&#39;</span><span class="p">,</span> <span class="sa">f</span><span class="s1">&#39;</span><span class="si">{</span><span class="n">page_name</span><span class="si">}</span><span class="s1">.jinja2&#39;</span><span class="p">),</span>
339
+ <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">plugin_path</span><span class="p">,</span> <span class="s1">&#39;src&#39;</span><span class="p">,</span> <span class="n">plugin_path</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">&#39;/&#39;</span><span class="p">)[</span><span class="o">-</span><span class="mi">1</span><span class="p">],</span> <span class="s1">&#39;templates&#39;</span><span class="p">,</span> <span class="sa">f</span><span class="s1">&#39;</span><span class="si">{</span><span class="n">page_name</span><span class="si">}</span><span class="s1">.jinja2&#39;</span><span class="p">),</span>
340
+ <span class="p">]</span>
341
+
342
+ <span class="k">for</span> <span class="n">path</span> <span class="ow">in</span> <span class="n">template_paths</span><span class="p">:</span>
343
+ <span class="k">if</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="n">path</span><span class="p">):</span>
344
+ <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s1">&#39;Found template in plugin: </span><span class="si">{</span><span class="n">path</span><span class="si">}</span><span class="s1">&#39;</span><span class="p">)</span>
345
+ <span class="c1"># Try to get the template from the environment</span>
346
+ <span class="k">try</span><span class="p">:</span>
347
+ <span class="c1"># Convert to relative path from one of our template roots</span>
348
+ <span class="k">for</span> <span class="n">loader</span> <span class="ow">in</span> <span class="n">env</span><span class="o">.</span><span class="n">loader</span><span class="o">.</span><span class="n">loaders</span><span class="p">:</span>
349
+ <span class="k">for</span> <span class="n">template_dir</span> <span class="ow">in</span> <span class="n">loader</span><span class="o">.</span><span class="n">searchpath</span><span class="p">:</span>
350
+ <span class="n">rel_path</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">relpath</span><span class="p">(</span><span class="n">path</span><span class="p">,</span> <span class="n">template_dir</span><span class="p">)</span>
351
+ <span class="k">if</span> <span class="ow">not</span> <span class="n">rel_path</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s1">&#39;..&#39;</span><span class="p">):</span>
352
+ <span class="n">template</span> <span class="o">=</span> <span class="n">env</span><span class="o">.</span><span class="n">get_template</span><span class="p">(</span><span class="n">rel_path</span><span class="p">)</span>
353
+ <span class="k">return</span> <span class="n">rel_path</span><span class="p">,</span> <span class="n">template</span>
354
+ <span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
355
+ <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s1">&#39;Error loading template: </span><span class="si">{</span><span class="n">e</span><span class="si">}</span><span class="s1">&#39;</span><span class="p">)</span>
356
+ <span class="k">return</span> <span class="kc">None</span><span class="p">,</span> <span class="kc">None</span></div>
357
+
358
+
359
+ <div class="viewcode-block" id="load_plugin_templates">
360
+ <a class="viewcode-back" href="../../../source/mindroot.lib.html#mindroot.lib.templates.load_plugin_templates">[docs]</a>
361
+ <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">load_plugin_templates</span><span class="p">(</span><span class="n">page_name</span><span class="p">,</span> <span class="n">plugins</span><span class="p">):</span>
362
+ <span class="w"> </span><span class="sd">&quot;&quot;&quot;Load templates from plugins with translation support.</span>
363
+ <span class="sd"> </span>
364
+ <span class="sd"> Args:</span>
365
+ <span class="sd"> page_name (str): Name of the template page</span>
366
+ <span class="sd"> plugins (list): List of enabled plugins</span>
367
+ <span class="sd"> </span>
368
+ <span class="sd"> Returns:</span>
369
+ <span class="sd"> list: List of template info dictionaries</span>
370
+ <span class="sd"> &quot;&quot;&quot;</span>
371
+ <span class="n">templates</span> <span class="o">=</span> <span class="p">[]</span>
372
+ <span class="k">for</span> <span class="n">plugin</span> <span class="ow">in</span> <span class="n">plugins</span><span class="p">:</span>
373
+ <span class="k">try</span><span class="p">:</span>
374
+ <span class="n">plugin_path</span> <span class="o">=</span> <span class="n">get_plugin_path</span><span class="p">(</span><span class="n">plugin</span><span class="p">)</span>
375
+ <span class="k">if</span> <span class="ow">not</span> <span class="n">plugin_path</span><span class="p">:</span>
376
+ <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s1">&#39;Warning: Could not find path for plugin: </span><span class="si">{</span><span class="n">plugin</span><span class="si">}</span><span class="s1">&#39;</span><span class="p">)</span>
377
+ <span class="k">continue</span>
378
+
379
+ <span class="c1">#print(f&quot;Loading templates from plugin: {plugin}, path: {plugin_path}&quot;)</span>
380
+ <span class="c1"># plugin might be name rather than directory</span>
381
+ <span class="c1"># get the last part of the path to check also</span>
382
+ <span class="c1">#</span>
383
+ <span class="n">last_part</span> <span class="o">=</span> <span class="n">plugin_path</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">&#39;/&#39;</span><span class="p">)[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span>
384
+ <span class="c1"># Check inject templates</span>
385
+ <span class="n">inject_paths</span> <span class="o">=</span> <span class="p">[</span>
386
+ <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">plugin_path</span><span class="p">,</span> <span class="s1">&#39;inject&#39;</span><span class="p">,</span> <span class="sa">f</span><span class="s1">&#39;</span><span class="si">{</span><span class="n">page_name</span><span class="si">}</span><span class="s1">.jinja2&#39;</span><span class="p">),</span>
387
+ <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">plugin_path</span><span class="p">,</span> <span class="s1">&#39;src&#39;</span><span class="p">,</span> <span class="n">plugin</span><span class="p">,</span> <span class="s1">&#39;inject&#39;</span><span class="p">,</span> <span class="sa">f</span><span class="s1">&#39;</span><span class="si">{</span><span class="n">page_name</span><span class="si">}</span><span class="s1">.jinja2&#39;</span><span class="p">),</span>
388
+ <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">plugin_path</span><span class="p">,</span> <span class="s1">&#39;src&#39;</span><span class="p">,</span> <span class="s1">&#39;inject&#39;</span><span class="p">,</span> <span class="sa">f</span><span class="s1">&#39;</span><span class="si">{</span><span class="n">page_name</span><span class="si">}</span><span class="s1">.jinja2&#39;</span><span class="p">),</span>
389
+ <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">plugin_path</span><span class="p">,</span> <span class="s1">&#39;src&#39;</span><span class="p">,</span> <span class="n">last_part</span><span class="p">,</span> <span class="s1">&#39;inject&#39;</span><span class="p">,</span> <span class="sa">f</span><span class="s1">&#39;</span><span class="si">{</span><span class="n">page_name</span><span class="si">}</span><span class="s1">.jinja2&#39;</span><span class="p">),</span>
390
+ <span class="p">]</span>
391
+
392
+ <span class="k">for</span> <span class="n">path</span> <span class="ow">in</span> <span class="n">inject_paths</span><span class="p">:</span>
393
+ <span class="k">if</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="n">path</span><span class="p">):</span>
394
+ <span class="c1"># Load template content with translation support</span>
395
+ <span class="n">content</span> <span class="o">=</span> <span class="n">load_template_with_translation</span><span class="p">(</span><span class="n">path</span><span class="p">)</span>
396
+ <span class="k">if</span> <span class="n">content</span><span class="p">:</span>
397
+ <span class="c1">#print(f&quot;Found inject template at: {path}&quot;)</span>
398
+ <span class="n">templates</span><span class="o">.</span><span class="n">append</span><span class="p">({</span><span class="s1">&#39;type&#39;</span><span class="p">:</span> <span class="s1">&#39;inject&#39;</span><span class="p">,</span> <span class="s1">&#39;template&#39;</span><span class="p">:</span> <span class="n">env</span><span class="o">.</span><span class="n">from_string</span><span class="p">(</span><span class="n">content</span><span class="p">)})</span>
399
+ <span class="k">break</span>
400
+ <span class="c1">#else:</span>
401
+ <span class="c1">#</span>
402
+ <span class="c1"># print(f&quot;Inject template not found at: {path}&quot;)</span>
403
+
404
+ <span class="c1"># Check override templates</span>
405
+ <span class="n">override_paths</span> <span class="o">=</span> <span class="p">[</span>
406
+ <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">plugin_path</span><span class="p">,</span> <span class="s1">&#39;override&#39;</span><span class="p">,</span> <span class="sa">f</span><span class="s1">&#39;</span><span class="si">{</span><span class="n">page_name</span><span class="si">}</span><span class="s1">.jinja2&#39;</span><span class="p">),</span>
407
+ <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">plugin_path</span><span class="p">,</span> <span class="s1">&#39;src&#39;</span><span class="p">,</span> <span class="n">plugin</span><span class="p">,</span> <span class="s1">&#39;override&#39;</span><span class="p">,</span> <span class="sa">f</span><span class="s1">&#39;</span><span class="si">{</span><span class="n">page_name</span><span class="si">}</span><span class="s1">.jinja2&#39;</span><span class="p">),</span>
408
+ <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">plugin_path</span><span class="p">,</span> <span class="s1">&#39;src&#39;</span><span class="p">,</span> <span class="s1">&#39;override&#39;</span><span class="p">,</span> <span class="sa">f</span><span class="s1">&#39;</span><span class="si">{</span><span class="n">page_name</span><span class="si">}</span><span class="s1">.jinja2&#39;</span><span class="p">),</span>
409
+ <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">plugin_path</span><span class="p">,</span> <span class="s1">&#39;src&#39;</span><span class="p">,</span> <span class="n">last_part</span><span class="p">,</span> <span class="s1">&#39;override&#39;</span><span class="p">,</span> <span class="sa">f</span><span class="s1">&#39;</span><span class="si">{</span><span class="n">page_name</span><span class="si">}</span><span class="s1">.jinja2&#39;</span><span class="p">)</span>
410
+ <span class="p">]</span>
411
+
412
+ <span class="k">for</span> <span class="n">path</span> <span class="ow">in</span> <span class="n">override_paths</span><span class="p">:</span>
413
+ <span class="k">if</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="n">path</span><span class="p">):</span>
414
+ <span class="c1"># Load template content with translation support</span>
415
+ <span class="n">content</span> <span class="o">=</span> <span class="n">load_template_with_translation</span><span class="p">(</span><span class="n">path</span><span class="p">)</span>
416
+ <span class="k">if</span> <span class="n">content</span><span class="p">:</span>
417
+ <span class="c1">#print(f&quot;Found override template at: {path}&quot;)</span>
418
+ <span class="n">templates</span><span class="o">.</span><span class="n">append</span><span class="p">({</span><span class="s1">&#39;type&#39;</span><span class="p">:</span> <span class="s1">&#39;override&#39;</span><span class="p">,</span> <span class="s1">&#39;template&#39;</span><span class="p">:</span> <span class="n">env</span><span class="o">.</span><span class="n">from_string</span><span class="p">(</span><span class="n">content</span><span class="p">)})</span>
419
+ <span class="k">break</span>
420
+
421
+ <span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
422
+ <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s1">&#39;Error loading plugin template: </span><span class="si">{</span><span class="n">e</span><span class="si">}</span><span class="s1">&#39;</span><span class="p">)</span>
423
+ <span class="k">continue</span>
424
+ <span class="k">return</span> <span class="n">templates</span></div>
425
+
426
+
427
+ <div class="viewcode-block" id="collect_content">
428
+ <a class="viewcode-back" href="../../../source/mindroot.lib.html#mindroot.lib.templates.collect_content">[docs]</a>
429
+ <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">collect_content</span><span class="p">(</span><span class="n">template</span><span class="p">,</span> <span class="n">blocks</span><span class="p">,</span> <span class="n">template_type</span><span class="p">,</span> <span class="n">data</span><span class="p">):</span>
430
+ <span class="w"> </span><span class="sd">&quot;&quot;&quot;Collect content from child templates.</span>
431
+ <span class="sd"> </span>
432
+ <span class="sd"> Args:</span>
433
+ <span class="sd"> template: Jinja2 template object</span>
434
+ <span class="sd"> blocks (list): List of block names</span>
435
+ <span class="sd"> template_type (str): Type of template (&#39;inject&#39; or &#39;override&#39;)</span>
436
+ <span class="sd"> data (dict): Template context data</span>
437
+ <span class="sd"> </span>
438
+ <span class="sd"> Returns:</span>
439
+ <span class="sd"> dict: Collected content by block</span>
440
+ <span class="sd"> &quot;&quot;&quot;</span>
441
+ <span class="n">content</span> <span class="o">=</span> <span class="p">{</span><span class="n">block</span><span class="p">:</span> <span class="p">{</span><span class="s1">&#39;inject&#39;</span><span class="p">:</span> <span class="p">[],</span> <span class="s1">&#39;override&#39;</span><span class="p">:</span> <span class="kc">None</span><span class="p">}</span> <span class="k">for</span> <span class="n">block</span> <span class="ow">in</span> <span class="n">blocks</span><span class="p">}</span>
442
+ <span class="k">for</span> <span class="n">block</span> <span class="ow">in</span> <span class="n">blocks</span><span class="p">:</span>
443
+ <span class="k">if</span> <span class="n">block</span> <span class="ow">in</span> <span class="n">template</span><span class="o">.</span><span class="n">blocks</span><span class="p">:</span>
444
+ <span class="n">block_content</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">template</span><span class="o">.</span><span class="n">blocks</span><span class="p">[</span><span class="n">block</span><span class="p">](</span><span class="n">template</span><span class="o">.</span><span class="n">new_context</span><span class="p">(</span><span class="n">data</span><span class="p">)))</span>
445
+
446
+ <span class="k">if</span> <span class="n">template_type</span> <span class="o">==</span> <span class="s1">&#39;override&#39;</span><span class="p">:</span>
447
+ <span class="n">content</span><span class="p">[</span><span class="n">block</span><span class="p">][</span><span class="s1">&#39;override&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">block_content</span>
448
+ <span class="k">else</span><span class="p">:</span>
449
+ <span class="n">content</span><span class="p">[</span><span class="n">block</span><span class="p">][</span><span class="s1">&#39;inject&#39;</span><span class="p">]</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">block_content</span><span class="p">)</span>
450
+ <span class="k">return</span> <span class="n">content</span></div>
451
+
452
+
453
+ <div class="viewcode-block" id="render_combined_template">
454
+ <a class="viewcode-back" href="../../../source/mindroot.lib.html#mindroot.lib.templates.render_combined_template">[docs]</a>
455
+ <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">render_combined_template</span><span class="p">(</span><span class="n">page_name</span><span class="p">,</span> <span class="n">plugins</span><span class="p">,</span> <span class="n">context</span><span class="p">):</span>
456
+ <span class="w"> </span><span class="sd">&quot;&quot;&quot;Render combined template with injections and overrides, including translation support.</span>
457
+ <span class="sd"> </span>
458
+ <span class="sd"> Args:</span>
459
+ <span class="sd"> page_name (str): Name of the template page</span>
460
+ <span class="sd"> plugins (list): List of enabled plugins</span>
461
+ <span class="sd"> context (dict): Template context data (can be None)</span>
462
+ <span class="sd"> </span>
463
+ <span class="sd"> Returns:</span>
464
+ <span class="sd"> str: Rendered HTML</span>
465
+ <span class="sd"> &quot;&quot;&quot;</span>
466
+ <span class="c1"># Load parent template with translation support</span>
467
+ <span class="n">parent_template</span> <span class="o">=</span> <span class="kc">None</span>
468
+ <span class="n">parent_template_path</span> <span class="o">=</span> <span class="kc">None</span>
469
+
470
+ <span class="c1"># Find the parent template file path</span>
471
+ <span class="c1"># We need to search through the parent_env loaders to find the actual file</span>
472
+ <span class="k">for</span> <span class="n">loader</span> <span class="ow">in</span> <span class="n">parent_env</span><span class="o">.</span><span class="n">loader</span><span class="o">.</span><span class="n">loaders</span><span class="p">:</span>
473
+ <span class="k">for</span> <span class="n">template_dir</span> <span class="ow">in</span> <span class="n">loader</span><span class="o">.</span><span class="n">searchpath</span><span class="p">:</span>
474
+ <span class="n">potential_path</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">template_dir</span><span class="p">,</span> <span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">page_name</span><span class="si">}</span><span class="s2">.jinja2&quot;</span><span class="p">)</span>
475
+ <span class="k">if</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="n">potential_path</span><span class="p">):</span>
476
+ <span class="n">parent_template_path</span> <span class="o">=</span> <span class="n">potential_path</span>
477
+ <span class="k">break</span>
478
+ <span class="k">if</span> <span class="n">parent_template_path</span><span class="p">:</span>
479
+ <span class="k">break</span>
480
+
481
+ <span class="k">if</span> <span class="n">parent_template_path</span><span class="p">:</span>
482
+ <span class="c1"># Load the parent template with translation support</span>
483
+ <span class="n">parent_content</span> <span class="o">=</span> <span class="n">load_template_with_translation</span><span class="p">(</span><span class="n">parent_template_path</span><span class="p">)</span>
484
+ <span class="k">if</span> <span class="n">parent_content</span><span class="p">:</span>
485
+ <span class="c1"># Create a template object from the translated content</span>
486
+ <span class="n">parent_template</span> <span class="o">=</span> <span class="n">env</span><span class="o">.</span><span class="n">from_string</span><span class="p">(</span><span class="n">parent_content</span><span class="p">)</span>
487
+ <span class="c1"># We need to preserve the original template name for Jinja2 inheritance</span>
488
+ <span class="n">parent_template</span><span class="o">.</span><span class="n">name</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">page_name</span><span class="si">}</span><span class="s2">.jinja2&quot;</span>
489
+ <span class="n">parent_template</span><span class="o">.</span><span class="n">filename</span> <span class="o">=</span> <span class="n">parent_template_path</span>
490
+ <span class="k">else</span><span class="p">:</span>
491
+ <span class="c1"># Fallback to loading without translation if something went wrong</span>
492
+ <span class="n">parent_template</span> <span class="o">=</span> <span class="n">parent_env</span><span class="o">.</span><span class="n">get_template</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">page_name</span><span class="si">}</span><span class="s2">.jinja2&quot;</span><span class="p">)</span>
493
+ <span class="k">else</span><span class="p">:</span>
494
+ <span class="c1"># Fallback to original method if we can&#39;t find the file path</span>
495
+ <span class="n">parent_template</span> <span class="o">=</span> <span class="n">parent_env</span><span class="o">.</span><span class="n">get_template</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">page_name</span><span class="si">}</span><span class="s2">.jinja2&quot;</span><span class="p">)</span>
496
+
497
+ <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;parent_template&quot;</span><span class="p">,</span> <span class="n">parent_template</span><span class="p">)</span>
498
+ <span class="n">child_templates</span> <span class="o">=</span> <span class="k">await</span> <span class="n">load_plugin_templates</span><span class="p">(</span><span class="n">page_name</span><span class="p">,</span> <span class="n">plugins</span><span class="p">)</span>
499
+ <span class="n">parent_blocks</span> <span class="o">=</span> <span class="n">parent_template</span><span class="o">.</span><span class="n">blocks</span><span class="o">.</span><span class="n">keys</span><span class="p">()</span>
500
+ <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;parent_blocks&quot;</span><span class="p">,</span> <span class="n">parent_blocks</span><span class="p">)</span>
501
+ <span class="n">all_content</span> <span class="o">=</span> <span class="p">{</span><span class="n">block</span><span class="p">:</span> <span class="p">{</span><span class="s1">&#39;inject&#39;</span><span class="p">:</span> <span class="p">[],</span> <span class="s1">&#39;override&#39;</span><span class="p">:</span> <span class="kc">None</span><span class="p">}</span> <span class="k">for</span> <span class="n">block</span> <span class="ow">in</span> <span class="n">parent_blocks</span><span class="p">}</span>
502
+
503
+ <span class="c1"># Ensure context is a dictionary</span>
504
+ <span class="n">context</span> <span class="o">=</span> <span class="n">context</span> <span class="ow">or</span> <span class="p">{}</span>
505
+
506
+ <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;child_templates&quot;</span><span class="p">,</span> <span class="n">child_templates</span><span class="p">)</span>
507
+
508
+ <span class="k">for</span> <span class="n">child_template_info</span> <span class="ow">in</span> <span class="n">child_templates</span><span class="p">:</span>
509
+ <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;calling collect_content&quot;</span><span class="p">)</span>
510
+ <span class="n">child_content</span> <span class="o">=</span> <span class="k">await</span> <span class="n">collect_content</span><span class="p">(</span>
511
+ <span class="n">child_template_info</span><span class="p">[</span><span class="s1">&#39;template&#39;</span><span class="p">],</span>
512
+ <span class="n">parent_blocks</span><span class="p">,</span>
513
+ <span class="n">child_template_info</span><span class="p">[</span><span class="s1">&#39;type&#39;</span><span class="p">],</span>
514
+ <span class="n">context</span>
515
+ <span class="p">)</span>
516
+ <span class="k">for</span> <span class="n">block</span><span class="p">,</span> <span class="n">content</span> <span class="ow">in</span> <span class="n">child_content</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
517
+ <span class="k">if</span> <span class="n">content</span><span class="p">[</span><span class="s1">&#39;override&#39;</span><span class="p">]:</span>
518
+ <span class="n">all_content</span><span class="p">[</span><span class="n">block</span><span class="p">][</span><span class="s1">&#39;override&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">content</span><span class="p">[</span><span class="s1">&#39;override&#39;</span><span class="p">]</span>
519
+ <span class="k">else</span><span class="p">:</span>
520
+ <span class="n">all_content</span><span class="p">[</span><span class="n">block</span><span class="p">][</span><span class="s1">&#39;inject&#39;</span><span class="p">]</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">content</span><span class="p">[</span><span class="s1">&#39;inject&#39;</span><span class="p">])</span>
521
+
522
+ <span class="n">combined_template_str</span> <span class="o">=</span> <span class="s1">&#39;{</span><span class="si">% e</span><span class="s1">xtends layout_template %}</span><span class="se">\n</span><span class="s1">&#39;</span>
523
+ <span class="k">for</span> <span class="n">block</span> <span class="ow">in</span> <span class="n">all_content</span><span class="p">:</span>
524
+ <span class="k">if</span> <span class="n">all_content</span><span class="p">[</span><span class="n">block</span><span class="p">][</span><span class="s1">&#39;override&#39;</span><span class="p">]:</span>
525
+ <span class="n">combined_template_str</span> <span class="o">+=</span> <span class="sa">f</span><span class="s1">&#39;</span><span class="se">{{</span><span class="s1">% block </span><span class="si">{</span><span class="n">block</span><span class="si">}</span><span class="s1"> %</span><span class="se">}}\n</span><span class="s1"> </span><span class="se">{{{{</span><span class="s1"> combined_</span><span class="si">{</span><span class="n">block</span><span class="si">}</span><span class="s1">_override|safe </span><span class="se">}}}}\n{{</span><span class="s1">% endblock %</span><span class="se">}}\n</span><span class="s1">&#39;</span>
526
+ <span class="k">else</span><span class="p">:</span>
527
+ <span class="n">combined_template_str</span> <span class="o">+=</span> <span class="sa">f</span><span class="s1">&#39;</span><span class="se">{{</span><span class="s1">% block </span><span class="si">{</span><span class="n">block</span><span class="si">}</span><span class="s1"> %</span><span class="se">}}\n</span><span class="s1"> </span><span class="se">{{{{</span><span class="s1"> super() </span><span class="se">}}}}\n</span><span class="s1"> </span><span class="se">{{{{</span><span class="s1"> combined_</span><span class="si">{</span><span class="n">block</span><span class="si">}</span><span class="s1">_inject|safe </span><span class="se">}}}}\n{{</span><span class="s1">% endblock %</span><span class="se">}}\n</span><span class="s1">&#39;</span>
528
+
529
+ <span class="n">combined_child_template</span> <span class="o">=</span> <span class="n">env</span><span class="o">.</span><span class="n">from_string</span><span class="p">(</span><span class="n">combined_template_str</span><span class="p">)</span>
530
+
531
+ <span class="n">combined_inject</span> <span class="o">=</span> <span class="p">{}</span>
532
+ <span class="n">combined_override</span> <span class="o">=</span> <span class="p">{}</span>
533
+
534
+ <span class="k">for</span> <span class="n">block</span><span class="p">,</span> <span class="n">content</span> <span class="ow">in</span> <span class="n">all_content</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
535
+ <span class="k">if</span> <span class="s1">&#39;inject&#39;</span> <span class="ow">in</span> <span class="n">content</span> <span class="ow">and</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">content</span><span class="p">[</span><span class="s1">&#39;inject&#39;</span><span class="p">],</span> <span class="nb">list</span><span class="p">):</span>
536
+ <span class="c1"># print with a yellow background, black text</span>
537
+ <span class="c1"># report details including page name and content injected</span>
538
+ <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;</span><span class="se">\033</span><span class="s2">[103m&quot;</span> <span class="o">+</span> <span class="sa">f</span><span class="s2">&quot;Injecting into block </span><span class="si">{</span><span class="n">block</span><span class="si">}</span><span class="s2"> on page </span><span class="si">{</span><span class="n">page_name</span><span class="si">}</span><span class="s2"> with content:&quot;</span><span class="p">)</span>
539
+ <span class="nb">print</span><span class="p">(</span><span class="n">content</span><span class="p">[</span><span class="s1">&#39;inject&#39;</span><span class="p">])</span>
540
+ <span class="c1"># reset color</span>
541
+ <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;</span><span class="se">\033</span><span class="s2">[0m&quot;</span><span class="p">)</span>
542
+ <span class="n">combined_inject</span><span class="p">[</span><span class="sa">f</span><span class="s1">&#39;combined_</span><span class="si">{</span><span class="n">block</span><span class="si">}</span><span class="s1">_inject&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">content</span><span class="p">[</span><span class="s1">&#39;inject&#39;</span><span class="p">])</span>
543
+ <span class="k">else</span><span class="p">:</span>
544
+ <span class="n">combined_inject</span><span class="p">[</span><span class="sa">f</span><span class="s1">&#39;combined_</span><span class="si">{</span><span class="n">block</span><span class="si">}</span><span class="s1">_inject&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span>
545
+
546
+ <span class="k">if</span> <span class="s1">&#39;override&#39;</span> <span class="ow">in</span> <span class="n">content</span> <span class="ow">and</span> <span class="n">content</span><span class="p">[</span><span class="s1">&#39;override&#39;</span><span class="p">]:</span>
547
+ <span class="n">combined_override</span><span class="p">[</span><span class="sa">f</span><span class="s1">&#39;combined_</span><span class="si">{</span><span class="n">block</span><span class="si">}</span><span class="s1">_override&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">content</span><span class="p">[</span><span class="s1">&#39;override&#39;</span><span class="p">]</span>
548
+
549
+ <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;in render combined, context is&quot;</span><span class="p">,</span> <span class="n">context</span><span class="p">)</span>
550
+
551
+ <span class="n">rendered_html</span> <span class="o">=</span> <span class="n">combined_child_template</span><span class="o">.</span><span class="n">render</span><span class="p">(</span>
552
+ <span class="n">layout_template</span><span class="o">=</span><span class="n">parent_template</span><span class="p">,</span>
553
+ <span class="o">**</span><span class="n">combined_inject</span><span class="p">,</span>
554
+ <span class="o">**</span><span class="n">combined_override</span><span class="p">,</span>
555
+ <span class="o">**</span><span class="n">context</span>
556
+ <span class="p">)</span>
557
+
558
+ <span class="k">return</span> <span class="n">rendered_html</span></div>
559
+
560
+
561
+ <div class="viewcode-block" id="render_direct_template">
562
+ <a class="viewcode-back" href="../../../source/mindroot.lib.html#mindroot.lib.templates.render_direct_template">[docs]</a>
563
+ <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">render_direct_template</span><span class="p">(</span><span class="n">template_path</span><span class="p">,</span> <span class="n">context</span><span class="p">):</span>
564
+ <span class="w"> </span><span class="sd">&quot;&quot;&quot;Render a template directly without combining with a parent template, with translation support.</span>
565
+ <span class="sd"> </span>
566
+ <span class="sd"> Args:</span>
567
+ <span class="sd"> template_path (str): Path to the template</span>
568
+ <span class="sd"> context (dict): Template context data</span>
569
+ <span class="sd"> </span>
570
+ <span class="sd"> Returns:</span>
571
+ <span class="sd"> str: Rendered HTML</span>
572
+ <span class="sd"> &quot;&quot;&quot;</span>
573
+ <span class="c1"># Ensure context is a dictionary</span>
574
+ <span class="n">context</span> <span class="o">=</span> <span class="n">context</span> <span class="ow">or</span> <span class="p">{}</span>
575
+
576
+ <span class="k">try</span><span class="p">:</span>
577
+ <span class="c1"># Check if we need to load with translation support</span>
578
+ <span class="n">template_full_path</span> <span class="o">=</span> <span class="kc">None</span>
579
+ <span class="k">for</span> <span class="n">loader</span> <span class="ow">in</span> <span class="n">env</span><span class="o">.</span><span class="n">loader</span><span class="o">.</span><span class="n">loaders</span><span class="p">:</span>
580
+ <span class="k">for</span> <span class="n">template_dir</span> <span class="ow">in</span> <span class="n">loader</span><span class="o">.</span><span class="n">searchpath</span><span class="p">:</span>
581
+ <span class="n">potential_path</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">template_dir</span><span class="p">,</span> <span class="n">template_path</span><span class="p">)</span>
582
+ <span class="k">if</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="n">potential_path</span><span class="p">):</span>
583
+ <span class="n">template_full_path</span> <span class="o">=</span> <span class="n">potential_path</span>
584
+ <span class="k">break</span>
585
+ <span class="k">if</span> <span class="n">template_full_path</span><span class="p">:</span>
586
+ <span class="k">break</span>
587
+
588
+ <span class="k">if</span> <span class="n">template_full_path</span><span class="p">:</span>
589
+ <span class="c1"># Load with translation support</span>
590
+ <span class="n">content</span> <span class="o">=</span> <span class="n">load_template_with_translation</span><span class="p">(</span><span class="n">template_full_path</span><span class="p">)</span>
591
+ <span class="k">if</span> <span class="n">content</span><span class="p">:</span>
592
+ <span class="n">template</span> <span class="o">=</span> <span class="n">env</span><span class="o">.</span><span class="n">from_string</span><span class="p">(</span><span class="n">content</span><span class="p">)</span>
593
+ <span class="k">return</span> <span class="n">template</span><span class="o">.</span><span class="n">render</span><span class="p">(</span><span class="o">**</span><span class="n">context</span><span class="p">)</span>
594
+
595
+ <span class="c1"># Fallback to normal template loading</span>
596
+ <span class="n">template</span> <span class="o">=</span> <span class="n">env</span><span class="o">.</span><span class="n">get_template</span><span class="p">(</span><span class="n">template_path</span><span class="p">)</span>
597
+ <span class="k">return</span> <span class="n">template</span><span class="o">.</span><span class="n">render</span><span class="p">(</span><span class="o">**</span><span class="n">context</span><span class="p">)</span>
598
+ <span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
599
+ <span class="n">logging</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Error rendering template </span><span class="si">{</span><span class="n">template_path</span><span class="si">}</span><span class="s2">: </span><span class="si">{</span><span class="n">e</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
600
+ <span class="k">return</span> <span class="sa">f</span><span class="s2">&quot;&lt;h1&gt;Error rendering template&lt;/h1&gt;&lt;p&gt;</span><span class="si">{</span><span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">)</span><span class="si">}</span><span class="s2">&lt;/p&gt;&quot;</span></div>
601
+
602
+
603
+ <div class="viewcode-block" id="render">
604
+ <a class="viewcode-back" href="../../../source/mindroot.lib.html#mindroot.lib.templates.render">[docs]</a>
605
+ <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">render</span><span class="p">(</span><span class="n">page_name</span><span class="p">,</span> <span class="n">context</span><span class="p">):</span>
606
+ <span class="w"> </span><span class="sd">&quot;&quot;&quot;Render a template with plugin injections, overrides, and translation support.</span>
607
+ <span class="sd"> If no parent template exists, tries to render a template directly from a plugin.</span>
608
+ <span class="sd"> </span>
609
+ <span class="sd"> Args:</span>
610
+ <span class="sd"> page_name (str): Name of the template page</span>
611
+ <span class="sd"> context (dict): Template context data (can be None)</span>
612
+ <span class="sd"> </span>
613
+ <span class="sd"> Returns:</span>
614
+ <span class="sd"> str: Rendered HTML</span>
615
+ <span class="sd"> &quot;&quot;&quot;</span>
616
+ <span class="n">plugins</span> <span class="o">=</span> <span class="n">list_enabled</span><span class="p">(</span><span class="kc">False</span><span class="p">)</span>
617
+ <span class="c1"># print with white background red text</span>
618
+ <span class="c1"># report details including page name and plugins enabled</span>
619
+ <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;</span><span class="se">\033</span><span class="s2">[101m&quot;</span> <span class="o">+</span> <span class="sa">f</span><span class="s2">&quot;Rendering page </span><span class="si">{</span><span class="n">page_name</span><span class="si">}</span><span class="s2"> with plugins enabled:&quot;</span><span class="p">)</span>
620
+ <span class="nb">print</span><span class="p">(</span><span class="n">plugins</span><span class="p">)</span>
621
+ <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;</span><span class="se">\033</span><span class="s2">[0m&quot;</span><span class="p">)</span>
622
+
623
+ <span class="c1"># Ensure context is a dictionary</span>
624
+ <span class="n">context</span> <span class="o">=</span> <span class="n">context</span> <span class="ow">or</span> <span class="p">{}</span>
625
+
626
+ <span class="c1"># First try to render with the combined template approach</span>
627
+ <span class="k">try</span><span class="p">:</span>
628
+ <span class="n">parent_env</span><span class="o">.</span><span class="n">get_template</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">page_name</span><span class="si">}</span><span class="s2">.jinja2&quot;</span><span class="p">)</span>
629
+ <span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
630
+ <span class="n">trace</span> <span class="o">=</span> <span class="n">traceback</span><span class="o">.</span><span class="n">format_exc</span><span class="p">()</span>
631
+ <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Error finding parent template for </span><span class="si">{</span><span class="n">page_name</span><span class="si">}</span><span class="s2">: </span><span class="si">{</span><span class="n">e</span><span class="si">}</span><span class="se">\n\n</span><span class="si">{</span><span class="n">trace</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
632
+ <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;No parent template found for </span><span class="si">{</span><span class="n">page_name</span><span class="si">}</span><span class="s2">, trying direct rendering: </span><span class="si">{</span><span class="n">e</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
633
+
634
+ <span class="c1"># Try to find and render a template directly from a plugin</span>
635
+ <span class="n">template_path</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="k">await</span> <span class="n">find_plugin_template</span><span class="p">(</span><span class="n">page_name</span><span class="p">,</span> <span class="n">plugins</span><span class="p">)</span>
636
+ <span class="k">if</span> <span class="n">template_path</span><span class="p">:</span>
637
+ <span class="k">return</span> <span class="k">await</span> <span class="n">render_direct_template</span><span class="p">(</span><span class="n">template_path</span><span class="p">,</span> <span class="n">context</span><span class="p">)</span>
638
+
639
+ <span class="k">return</span> <span class="sa">f</span><span class="s2">&quot;&lt;h1&gt;Template Not Found&lt;/h1&gt;&lt;p&gt;No template found for &#39;</span><span class="si">{</span><span class="n">page_name</span><span class="si">}</span><span class="s2">&#39;&lt;/p&gt;&quot;</span>
640
+
641
+ <span class="k">try</span><span class="p">:</span>
642
+ <span class="k">return</span> <span class="k">await</span> <span class="n">render_combined_template</span><span class="p">(</span><span class="n">page_name</span><span class="p">,</span> <span class="n">plugins</span><span class="p">,</span> <span class="n">context</span><span class="p">)</span>
643
+ <span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
644
+ <span class="n">trace</span> <span class="o">=</span> <span class="n">traceback</span><span class="o">.</span><span class="n">format_exc</span><span class="p">()</span>
645
+ <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Error rendering </span><span class="si">{</span><span class="n">page_name</span><span class="si">}</span><span class="s2">: </span><span class="si">{</span><span class="n">e</span><span class="si">}</span><span class="se">\n\n</span><span class="si">{</span><span class="n">trace</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
646
+ <span class="k">return</span> <span class="sa">f</span><span class="s2">&quot;&lt;h1&gt;Error Rendering Page&lt;/h1&gt;&lt;p&gt;</span><span class="si">{</span><span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">)</span><span class="si">}</span><span class="s2">&lt;/p&gt;&lt;pre&gt;</span><span class="si">{</span><span class="n">trace</span><span class="si">}</span><span class="s2">&lt;/pre&gt;&quot;</span></div>
647
+
648
+ </pre></div>
649
+
650
+ </div>
651
+ </div>
652
+ <footer>
653
+
654
+ <hr/>
655
+
656
+ <div role="contentinfo">
657
+ <p>&#169; Copyright 2025, Jason Livesay.</p>
658
+ </div>
659
+
660
+ Built with <a href="https://www.sphinx-doc.org/">Sphinx</a> using a
661
+ <a href="https://github.com/readthedocs/sphinx_rtd_theme">theme</a>
662
+ provided by <a href="https://readthedocs.org">Read the Docs</a>.
663
+
664
+
665
+ </footer>
666
+ </div>
667
+ </div>
668
+ </section>
669
+ </div>
670
+ <script>
671
+ jQuery(function () {
672
+ SphinxRtdTheme.Navigation.enable(true);
673
+ });
674
+ </script>
675
+
676
+ </body>
677
+ </html>