@jahia/agentic 0.2.0 → 0.4.0

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.
Files changed (238) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/README.md +28 -0
  3. package/dist/claude/.claude/agents/cnd-child-nodes.md +74 -0
  4. package/dist/claude/.claude/agents/cnd-jahia-mixins.md +113 -0
  5. package/dist/claude/.claude/agents/cnd-numbers-dates.md +61 -0
  6. package/dist/claude/.claude/agents/cnd-string-selectors.md +94 -0
  7. package/dist/claude/.claude/agents/jahia-cnd-author.md +130 -0
  8. package/dist/claude/.claude/agents/jahia-dev-worker.md +264 -0
  9. package/dist/claude/.claude/agents/jahia-reviewer.md +105 -0
  10. package/dist/claude/.claude/rules/jahia.md +15 -6
  11. package/dist/claude/.claude/skills/jahia/SKILL.md +23 -11
  12. package/dist/claude/.claude/skills/jahia-content/SKILL.md +102 -84
  13. package/dist/claude/.claude/skills/jahia-content-create-content/SKILL.md +255 -280
  14. package/dist/claude/.claude/skills/jahia-content-explore-structure/SKILL.md +187 -96
  15. package/dist/claude/.claude/skills/jahia-content-media-upload/SKILL.md +197 -0
  16. package/dist/claude/.claude/skills/jahia-content-move-content/SKILL.md +160 -165
  17. package/dist/claude/.claude/skills/jahia-content-organize/SKILL.md +209 -0
  18. package/dist/claude/.claude/skills/jahia-content-publish/SKILL.md +181 -0
  19. package/dist/claude/.claude/skills/jahia-content-query-content/SKILL.md +122 -92
  20. package/dist/claude/.claude/skills/jahia-content-translate-content/SKILL.md +154 -225
  21. package/dist/claude/.claude/skills/jahia-dev-accessibility/SKILL.md +3 -3
  22. package/dist/claude/.claude/skills/jahia-dev-build-component/SKILL.md +10 -7
  23. package/dist/claude/.claude/skills/jahia-dev-create-page-template/SKILL.md +59 -21
  24. package/dist/claude/.claude/skills/jahia-dev-create-template-set/SKILL.md +20 -47
  25. package/dist/claude/.claude/skills/jahia-dev-create-view/SKILL.md +3 -3
  26. package/dist/claude/.claude/skills/jahia-dev-cypress/SKILL.md +150 -330
  27. package/dist/claude/.claude/skills/jahia-dev-define-content-type/SKILL.md +43 -486
  28. package/dist/claude/.claude/skills/jahia-dev-define-content-type/references/modeling-decisions.md +52 -0
  29. package/dist/claude/.claude/skills/jahia-dev-query-content/SKILL.md +93 -296
  30. package/dist/claude/.claude/skills/jahia-dev-review-cnd/SKILL.md +79 -0
  31. package/dist/claude/.claude/skills/jahia-dev-review-cnd/scripts/check-cnd.d.mts +13 -0
  32. package/dist/claude/.claude/skills/jahia-dev-review-cnd/scripts/check-cnd.mjs +198 -0
  33. package/dist/claude/.claude/skills/jahia-dev-site-review/SKILL.md +70 -0
  34. package/dist/claude/.claude/skills/jahia-dev-site-review/scripts/review-pages.mjs +85 -0
  35. package/dist/claude/.claude/skills/jahia-dev-start-local/SKILL.md +18 -26
  36. package/dist/claude/.claude/skills/jahia-jcr-sql2/SKILL.md +258 -0
  37. package/dist/claude/.claude/skills/jahia-orchestrate/SKILL.md +148 -0
  38. package/dist/claude/.claude/skills/jahia-orchestrate/scripts/verify-pages.mjs +59 -0
  39. package/dist/claude/CLAUDE.md +16 -13
  40. package/dist/codex/.agents/skills/jahia/SKILL.md +23 -11
  41. package/dist/codex/.agents/skills/jahia-content/SKILL.md +102 -84
  42. package/dist/codex/.agents/skills/jahia-content-create-content/SKILL.md +255 -280
  43. package/dist/codex/.agents/skills/jahia-content-explore-structure/SKILL.md +187 -96
  44. package/dist/codex/.agents/skills/jahia-content-media-upload/SKILL.md +197 -0
  45. package/dist/codex/.agents/skills/jahia-content-move-content/SKILL.md +160 -165
  46. package/dist/codex/.agents/skills/jahia-content-organize/SKILL.md +209 -0
  47. package/dist/codex/.agents/skills/jahia-content-publish/SKILL.md +181 -0
  48. package/dist/codex/.agents/skills/jahia-content-query-content/SKILL.md +122 -92
  49. package/dist/codex/.agents/skills/jahia-content-translate-content/SKILL.md +154 -225
  50. package/dist/codex/.agents/skills/jahia-dev-accessibility/SKILL.md +3 -3
  51. package/dist/codex/.agents/skills/jahia-dev-build-component/SKILL.md +10 -7
  52. package/dist/codex/.agents/skills/jahia-dev-create-page-template/SKILL.md +59 -21
  53. package/dist/codex/.agents/skills/jahia-dev-create-template-set/SKILL.md +20 -47
  54. package/dist/codex/.agents/skills/jahia-dev-create-view/SKILL.md +3 -3
  55. package/dist/codex/.agents/skills/jahia-dev-cypress/SKILL.md +150 -330
  56. package/dist/codex/.agents/skills/jahia-dev-define-content-type/SKILL.md +43 -486
  57. package/dist/codex/.agents/skills/jahia-dev-define-content-type/references/modeling-decisions.md +52 -0
  58. package/dist/codex/.agents/skills/jahia-dev-query-content/SKILL.md +93 -296
  59. package/dist/codex/.agents/skills/jahia-dev-review-cnd/SKILL.md +79 -0
  60. package/dist/codex/.agents/skills/jahia-dev-review-cnd/scripts/check-cnd.d.mts +13 -0
  61. package/dist/codex/.agents/skills/jahia-dev-review-cnd/scripts/check-cnd.mjs +198 -0
  62. package/dist/codex/.agents/skills/jahia-dev-site-review/SKILL.md +70 -0
  63. package/dist/codex/.agents/skills/jahia-dev-site-review/scripts/review-pages.mjs +85 -0
  64. package/dist/codex/.agents/skills/jahia-dev-start-local/SKILL.md +18 -26
  65. package/dist/codex/.agents/skills/jahia-jcr-sql2/SKILL.md +258 -0
  66. package/dist/codex/.agents/skills/jahia-orchestrate/SKILL.md +148 -0
  67. package/dist/codex/.agents/skills/jahia-orchestrate/scripts/verify-pages.mjs +59 -0
  68. package/dist/codex/.codex/agents/cnd-child-nodes.toml +3 -0
  69. package/dist/codex/.codex/agents/cnd-jahia-mixins.toml +3 -0
  70. package/dist/codex/.codex/agents/cnd-numbers-dates.toml +3 -0
  71. package/dist/codex/.codex/agents/cnd-string-selectors.toml +3 -0
  72. package/dist/codex/.codex/agents/jahia-cnd-author.toml +3 -0
  73. package/dist/codex/.codex/agents/jahia-dev-worker.toml +3 -0
  74. package/dist/codex/.codex/agents/jahia-reviewer.toml +3 -0
  75. package/dist/codex/AGENTS.md +17 -10
  76. package/dist/copilot/.agents/skills/jahia/SKILL.md +23 -11
  77. package/dist/copilot/.agents/skills/jahia-content/SKILL.md +102 -84
  78. package/dist/copilot/.agents/skills/jahia-content-create-content/SKILL.md +255 -280
  79. package/dist/copilot/.agents/skills/jahia-content-explore-structure/SKILL.md +187 -96
  80. package/dist/copilot/.agents/skills/jahia-content-media-upload/SKILL.md +197 -0
  81. package/dist/copilot/.agents/skills/jahia-content-move-content/SKILL.md +160 -165
  82. package/dist/copilot/.agents/skills/jahia-content-organize/SKILL.md +209 -0
  83. package/dist/copilot/.agents/skills/jahia-content-publish/SKILL.md +181 -0
  84. package/dist/copilot/.agents/skills/jahia-content-query-content/SKILL.md +122 -92
  85. package/dist/copilot/.agents/skills/jahia-content-translate-content/SKILL.md +154 -225
  86. package/dist/copilot/.agents/skills/jahia-dev-accessibility/SKILL.md +3 -3
  87. package/dist/copilot/.agents/skills/jahia-dev-build-component/SKILL.md +10 -7
  88. package/dist/copilot/.agents/skills/jahia-dev-create-page-template/SKILL.md +59 -21
  89. package/dist/copilot/.agents/skills/jahia-dev-create-template-set/SKILL.md +20 -47
  90. package/dist/copilot/.agents/skills/jahia-dev-create-view/SKILL.md +3 -3
  91. package/dist/copilot/.agents/skills/jahia-dev-cypress/SKILL.md +150 -330
  92. package/dist/copilot/.agents/skills/jahia-dev-define-content-type/SKILL.md +43 -486
  93. package/dist/copilot/.agents/skills/jahia-dev-define-content-type/references/modeling-decisions.md +52 -0
  94. package/dist/copilot/.agents/skills/jahia-dev-query-content/SKILL.md +93 -296
  95. package/dist/copilot/.agents/skills/jahia-dev-review-cnd/SKILL.md +79 -0
  96. package/dist/copilot/.agents/skills/jahia-dev-review-cnd/scripts/check-cnd.d.mts +13 -0
  97. package/dist/copilot/.agents/skills/jahia-dev-review-cnd/scripts/check-cnd.mjs +198 -0
  98. package/dist/copilot/.agents/skills/jahia-dev-site-review/SKILL.md +70 -0
  99. package/dist/copilot/.agents/skills/jahia-dev-site-review/scripts/review-pages.mjs +85 -0
  100. package/dist/copilot/.agents/skills/jahia-dev-start-local/SKILL.md +18 -26
  101. package/dist/copilot/.agents/skills/jahia-jcr-sql2/SKILL.md +258 -0
  102. package/dist/copilot/.agents/skills/jahia-orchestrate/SKILL.md +148 -0
  103. package/dist/copilot/.agents/skills/jahia-orchestrate/scripts/verify-pages.mjs +59 -0
  104. package/dist/copilot/AGENTS.md +17 -10
  105. package/dist/cursor/.agents/skills/jahia/SKILL.md +23 -11
  106. package/dist/cursor/.agents/skills/jahia-content/SKILL.md +102 -84
  107. package/dist/cursor/.agents/skills/jahia-content-create-content/SKILL.md +255 -280
  108. package/dist/cursor/.agents/skills/jahia-content-explore-structure/SKILL.md +187 -96
  109. package/dist/cursor/.agents/skills/jahia-content-media-upload/SKILL.md +197 -0
  110. package/dist/cursor/.agents/skills/jahia-content-move-content/SKILL.md +160 -165
  111. package/dist/cursor/.agents/skills/jahia-content-organize/SKILL.md +209 -0
  112. package/dist/cursor/.agents/skills/jahia-content-publish/SKILL.md +181 -0
  113. package/dist/cursor/.agents/skills/jahia-content-query-content/SKILL.md +122 -92
  114. package/dist/cursor/.agents/skills/jahia-content-translate-content/SKILL.md +154 -225
  115. package/dist/cursor/.agents/skills/jahia-dev-accessibility/SKILL.md +3 -3
  116. package/dist/cursor/.agents/skills/jahia-dev-build-component/SKILL.md +10 -7
  117. package/dist/cursor/.agents/skills/jahia-dev-create-page-template/SKILL.md +59 -21
  118. package/dist/cursor/.agents/skills/jahia-dev-create-template-set/SKILL.md +20 -47
  119. package/dist/cursor/.agents/skills/jahia-dev-create-view/SKILL.md +3 -3
  120. package/dist/cursor/.agents/skills/jahia-dev-cypress/SKILL.md +150 -330
  121. package/dist/cursor/.agents/skills/jahia-dev-define-content-type/SKILL.md +43 -486
  122. package/dist/cursor/.agents/skills/jahia-dev-define-content-type/references/modeling-decisions.md +52 -0
  123. package/dist/cursor/.agents/skills/jahia-dev-query-content/SKILL.md +93 -296
  124. package/dist/cursor/.agents/skills/jahia-dev-review-cnd/SKILL.md +79 -0
  125. package/dist/cursor/.agents/skills/jahia-dev-review-cnd/scripts/check-cnd.d.mts +13 -0
  126. package/dist/cursor/.agents/skills/jahia-dev-review-cnd/scripts/check-cnd.mjs +198 -0
  127. package/dist/cursor/.agents/skills/jahia-dev-site-review/SKILL.md +70 -0
  128. package/dist/cursor/.agents/skills/jahia-dev-site-review/scripts/review-pages.mjs +85 -0
  129. package/dist/cursor/.agents/skills/jahia-dev-start-local/SKILL.md +18 -26
  130. package/dist/cursor/.agents/skills/jahia-jcr-sql2/SKILL.md +258 -0
  131. package/dist/cursor/.agents/skills/jahia-orchestrate/SKILL.md +148 -0
  132. package/dist/cursor/.agents/skills/jahia-orchestrate/scripts/verify-pages.mjs +59 -0
  133. package/dist/cursor/.cursor/agents/cnd-child-nodes.md +74 -0
  134. package/dist/cursor/.cursor/agents/cnd-jahia-mixins.md +113 -0
  135. package/dist/cursor/.cursor/agents/cnd-numbers-dates.md +61 -0
  136. package/dist/cursor/.cursor/agents/cnd-string-selectors.md +94 -0
  137. package/dist/cursor/.cursor/agents/jahia-cnd-author.md +130 -0
  138. package/dist/cursor/.cursor/agents/jahia-dev-worker.md +264 -0
  139. package/dist/cursor/.cursor/agents/jahia-reviewer.md +105 -0
  140. package/dist/cursor/.cursor/rules/jahia.mdc +15 -6
  141. package/dist/gemini/.agents/skills/jahia/SKILL.md +23 -11
  142. package/dist/gemini/.agents/skills/jahia-content/SKILL.md +102 -84
  143. package/dist/gemini/.agents/skills/jahia-content-create-content/SKILL.md +255 -280
  144. package/dist/gemini/.agents/skills/jahia-content-explore-structure/SKILL.md +187 -96
  145. package/dist/gemini/.agents/skills/jahia-content-media-upload/SKILL.md +197 -0
  146. package/dist/gemini/.agents/skills/jahia-content-move-content/SKILL.md +160 -165
  147. package/dist/gemini/.agents/skills/jahia-content-organize/SKILL.md +209 -0
  148. package/dist/gemini/.agents/skills/jahia-content-publish/SKILL.md +181 -0
  149. package/dist/gemini/.agents/skills/jahia-content-query-content/SKILL.md +122 -92
  150. package/dist/gemini/.agents/skills/jahia-content-translate-content/SKILL.md +154 -225
  151. package/dist/gemini/.agents/skills/jahia-dev-accessibility/SKILL.md +3 -3
  152. package/dist/gemini/.agents/skills/jahia-dev-build-component/SKILL.md +10 -7
  153. package/dist/gemini/.agents/skills/jahia-dev-create-page-template/SKILL.md +59 -21
  154. package/dist/gemini/.agents/skills/jahia-dev-create-template-set/SKILL.md +20 -47
  155. package/dist/gemini/.agents/skills/jahia-dev-create-view/SKILL.md +3 -3
  156. package/dist/gemini/.agents/skills/jahia-dev-cypress/SKILL.md +150 -330
  157. package/dist/gemini/.agents/skills/jahia-dev-define-content-type/SKILL.md +43 -486
  158. package/dist/gemini/.agents/skills/jahia-dev-define-content-type/references/modeling-decisions.md +52 -0
  159. package/dist/gemini/.agents/skills/jahia-dev-query-content/SKILL.md +93 -296
  160. package/dist/gemini/.agents/skills/jahia-dev-review-cnd/SKILL.md +79 -0
  161. package/dist/gemini/.agents/skills/jahia-dev-review-cnd/scripts/check-cnd.d.mts +13 -0
  162. package/dist/gemini/.agents/skills/jahia-dev-review-cnd/scripts/check-cnd.mjs +198 -0
  163. package/dist/gemini/.agents/skills/jahia-dev-site-review/SKILL.md +70 -0
  164. package/dist/gemini/.agents/skills/jahia-dev-site-review/scripts/review-pages.mjs +85 -0
  165. package/dist/gemini/.agents/skills/jahia-dev-start-local/SKILL.md +18 -26
  166. package/dist/gemini/.agents/skills/jahia-jcr-sql2/SKILL.md +258 -0
  167. package/dist/gemini/.agents/skills/jahia-orchestrate/SKILL.md +148 -0
  168. package/dist/gemini/.agents/skills/jahia-orchestrate/scripts/verify-pages.mjs +59 -0
  169. package/dist/gemini/AGENTS.md +17 -10
  170. package/dist/gemini/GEMINI.md +2 -2
  171. package/dist/index.js +13 -0
  172. package/dist/opencode/.agents/skills/jahia/SKILL.md +23 -11
  173. package/dist/opencode/.agents/skills/jahia-content/SKILL.md +102 -84
  174. package/dist/opencode/.agents/skills/jahia-content-create-content/SKILL.md +255 -280
  175. package/dist/opencode/.agents/skills/jahia-content-explore-structure/SKILL.md +187 -96
  176. package/dist/opencode/.agents/skills/jahia-content-media-upload/SKILL.md +197 -0
  177. package/dist/opencode/.agents/skills/jahia-content-move-content/SKILL.md +160 -165
  178. package/dist/opencode/.agents/skills/jahia-content-organize/SKILL.md +209 -0
  179. package/dist/opencode/.agents/skills/jahia-content-publish/SKILL.md +181 -0
  180. package/dist/opencode/.agents/skills/jahia-content-query-content/SKILL.md +122 -92
  181. package/dist/opencode/.agents/skills/jahia-content-translate-content/SKILL.md +154 -225
  182. package/dist/opencode/.agents/skills/jahia-dev-accessibility/SKILL.md +3 -3
  183. package/dist/opencode/.agents/skills/jahia-dev-build-component/SKILL.md +10 -7
  184. package/dist/opencode/.agents/skills/jahia-dev-create-page-template/SKILL.md +59 -21
  185. package/dist/opencode/.agents/skills/jahia-dev-create-template-set/SKILL.md +20 -47
  186. package/dist/opencode/.agents/skills/jahia-dev-create-view/SKILL.md +3 -3
  187. package/dist/opencode/.agents/skills/jahia-dev-cypress/SKILL.md +150 -330
  188. package/dist/opencode/.agents/skills/jahia-dev-define-content-type/SKILL.md +43 -486
  189. package/dist/opencode/.agents/skills/jahia-dev-define-content-type/references/modeling-decisions.md +52 -0
  190. package/dist/opencode/.agents/skills/jahia-dev-query-content/SKILL.md +93 -296
  191. package/dist/opencode/.agents/skills/jahia-dev-review-cnd/SKILL.md +79 -0
  192. package/dist/opencode/.agents/skills/jahia-dev-review-cnd/scripts/check-cnd.d.mts +13 -0
  193. package/dist/opencode/.agents/skills/jahia-dev-review-cnd/scripts/check-cnd.mjs +198 -0
  194. package/dist/opencode/.agents/skills/jahia-dev-site-review/SKILL.md +70 -0
  195. package/dist/opencode/.agents/skills/jahia-dev-site-review/scripts/review-pages.mjs +85 -0
  196. package/dist/opencode/.agents/skills/jahia-dev-start-local/SKILL.md +18 -26
  197. package/dist/opencode/.agents/skills/jahia-jcr-sql2/SKILL.md +258 -0
  198. package/dist/opencode/.agents/skills/jahia-orchestrate/SKILL.md +148 -0
  199. package/dist/opencode/.agents/skills/jahia-orchestrate/scripts/verify-pages.mjs +59 -0
  200. package/dist/opencode/.opencode/agents/cnd-child-nodes.md +74 -0
  201. package/dist/opencode/.opencode/agents/cnd-jahia-mixins.md +113 -0
  202. package/dist/opencode/.opencode/agents/cnd-numbers-dates.md +61 -0
  203. package/dist/opencode/.opencode/agents/cnd-string-selectors.md +94 -0
  204. package/dist/opencode/.opencode/agents/jahia-cnd-author.md +130 -0
  205. package/dist/opencode/.opencode/agents/jahia-dev-worker.md +264 -0
  206. package/dist/opencode/.opencode/agents/jahia-reviewer.md +105 -0
  207. package/dist/opencode/AGENTS.md +17 -10
  208. package/dist/windsurf/.windsurf/rules/jahia.md +15 -6
  209. package/dist/windsurf/.windsurf/skills/jahia/SKILL.md +23 -11
  210. package/dist/windsurf/.windsurf/skills/jahia-content/SKILL.md +102 -84
  211. package/dist/windsurf/.windsurf/skills/jahia-content-create-content/SKILL.md +255 -280
  212. package/dist/windsurf/.windsurf/skills/jahia-content-explore-structure/SKILL.md +187 -96
  213. package/dist/windsurf/.windsurf/skills/jahia-content-media-upload/SKILL.md +197 -0
  214. package/dist/windsurf/.windsurf/skills/jahia-content-move-content/SKILL.md +160 -165
  215. package/dist/windsurf/.windsurf/skills/jahia-content-organize/SKILL.md +209 -0
  216. package/dist/windsurf/.windsurf/skills/jahia-content-publish/SKILL.md +181 -0
  217. package/dist/windsurf/.windsurf/skills/jahia-content-query-content/SKILL.md +122 -92
  218. package/dist/windsurf/.windsurf/skills/jahia-content-translate-content/SKILL.md +154 -225
  219. package/dist/windsurf/.windsurf/skills/jahia-dev-accessibility/SKILL.md +3 -3
  220. package/dist/windsurf/.windsurf/skills/jahia-dev-build-component/SKILL.md +10 -7
  221. package/dist/windsurf/.windsurf/skills/jahia-dev-create-page-template/SKILL.md +59 -21
  222. package/dist/windsurf/.windsurf/skills/jahia-dev-create-template-set/SKILL.md +20 -47
  223. package/dist/windsurf/.windsurf/skills/jahia-dev-create-view/SKILL.md +3 -3
  224. package/dist/windsurf/.windsurf/skills/jahia-dev-cypress/SKILL.md +150 -330
  225. package/dist/windsurf/.windsurf/skills/jahia-dev-define-content-type/SKILL.md +43 -486
  226. package/dist/windsurf/.windsurf/skills/jahia-dev-define-content-type/references/modeling-decisions.md +52 -0
  227. package/dist/windsurf/.windsurf/skills/jahia-dev-query-content/SKILL.md +93 -296
  228. package/dist/windsurf/.windsurf/skills/jahia-dev-review-cnd/SKILL.md +79 -0
  229. package/dist/windsurf/.windsurf/skills/jahia-dev-review-cnd/scripts/check-cnd.d.mts +13 -0
  230. package/dist/windsurf/.windsurf/skills/jahia-dev-review-cnd/scripts/check-cnd.mjs +198 -0
  231. package/dist/windsurf/.windsurf/skills/jahia-dev-site-review/SKILL.md +70 -0
  232. package/dist/windsurf/.windsurf/skills/jahia-dev-site-review/scripts/review-pages.mjs +85 -0
  233. package/dist/windsurf/.windsurf/skills/jahia-dev-start-local/SKILL.md +18 -26
  234. package/dist/windsurf/.windsurf/skills/jahia-jcr-sql2/SKILL.md +258 -0
  235. package/dist/windsurf/.windsurf/skills/jahia-orchestrate/SKILL.md +148 -0
  236. package/dist/windsurf/.windsurf/skills/jahia-orchestrate/scripts/verify-pages.mjs +59 -0
  237. package/dist/windsurf/AGENTS.md +17 -10
  238. package/package.json +3 -3
@@ -1,273 +1,208 @@
1
1
  ---
2
2
  name: jahia-content-translate-content
3
- description: Adds language support to a Jahia site and translates existing content nodes. Use when asked to add a new language, fill in missing translations, or audit which content lacks i18n values.
3
+ description: Adds site languages and translates existing Jahia content using MCP tools. Use when asked to enable a locale, fill in missing translations, or publish translated pages and content.
4
4
  ---
5
5
 
6
6
  # Skill: jahia-content-translate-content
7
7
 
8
- Adds languages to a Jahia site and populates i18n properties on existing content nodes via the GraphQL API.
8
+ Translates existing content and manages multi-language support using MCP tools via the `jahia` MCP server.
9
+
10
+ > **Never call Jahia's GraphQL API directly.** Use only MCP tools. If a capability is missing, report it — do not work around with curl/GraphQL.
9
11
 
10
12
  ---
11
13
 
12
14
  ## Prerequisites
13
15
 
14
- - Jahia running at `http://localhost:8080`
15
- - Credentials: `root` / `root1234` (default)
16
- - GraphQL endpoint: `http://localhost:8080/modules/graphql`
17
-
18
- **Always include both auth flags:**
19
- ```bash
20
- curl -s -u root:root1234 \
21
- -H "Content-Type: application/json" \
22
- -H "Origin: http://localhost:8080" \
23
- -X POST http://localhost:8080/modules/graphql \
24
- -d '{"query": "..."}'
25
- ```
26
-
27
- > ⚠️ The `Origin` header is **required** — omitting it returns `Permission denied`.
16
+ - MCP server `jahia` connected with a valid API token
17
+ - Know the target `siteKey` (call `site.list` if unsure)
18
+ - Content already exists in a source locale
28
19
 
29
20
  ---
30
21
 
31
- ## Step 1 — Enable the new language on the site
32
-
33
- Before creating or querying translations, the language must be declared on the site node.
34
-
35
- ```bash
36
- # Check currently enabled languages
37
- curl -s -u root:root1234 \
38
- -H "Content-Type: application/json" \
39
- -H "Origin: http://localhost:8080" \
40
- -X POST http://localhost:8080/modules/graphql \
41
- -d '{
42
- "query": "{ jcr { nodeByPath(path: \"/sites/mySite\") { properties(names: [\"j:languages\",\"j:defaultLanguage\"]) { name values } } } }"
43
- }'
44
-
45
- # Add a language (e.g. "fr") — use setPropertiesBatch with the full new list
46
- curl -s -u root:root1234 \
47
- -H "Content-Type: application/json" \
48
- -H "Origin: http://localhost:8080" \
49
- -X POST http://localhost:8080/modules/graphql \
50
- -d '{
51
- "query": "mutation { jcr { mutateNode(pathOrId: \"/sites/mySite\") { setPropertiesBatch(properties: [{name: \"j:languages\", values: [\"en\", \"fr\"]}]) { path } } } }"
52
- }'
22
+ ## Step 1 — Check site languages
23
+
24
+ ```
25
+ tool: site.get
26
+ args: { "siteKey": "SITE_KEY" }
53
27
  ```
54
28
 
55
- > ⚠️ `j:languages` is a multi-valued property — always pass the **complete** list of languages, not just the new one. Passing only `["fr"]` would remove `"en"`.
29
+ Check `languages` and `defaultLanguage`.
56
30
 
57
- ---
31
+ - If the target locale is already present, continue.
32
+ - If the target locale is missing, add it to the site first before writing translations.
58
33
 
59
- ## Step 2 — Audit content missing translations
34
+ ---
60
35
 
61
- Query all i18n-bearing nodes and inspect which ones have empty values for the target language:
36
+ ## Step 2 Read the source content
62
37
 
63
- ```bash
64
- # Find all content nodes under /sites/mySite/contents
65
- curl -s -u root:root1234 \
66
- -H "Content-Type: application/json" \
67
- -H "Origin: http://localhost:8080" \
68
- -X POST http://localhost:8080/modules/graphql \
69
- -d '{
70
- "query": "{ jcr { nodesByQuery(query: \"SELECT * FROM [jmix:i18n] WHERE ISDESCENDANTNODE(\u0027/sites/mySite/contents\u0027) ORDER BY [jcr:path] ASC\", queryLanguage: SQL2) { nodes { path primaryNodeType { name } properties(language: \"fr\") { name value } } } } }"
71
- }'
38
+ ```
39
+ tool: content.get
40
+ args: {
41
+ "path": "/sites/SITE_KEY/home/about/main/intro-text",
42
+ "locale": "en"
43
+ }
72
44
  ```
73
45
 
74
- Or query a specific content type:
46
+ Note the properties that actually contain human-readable text.
75
47
 
76
- ```bash
77
- curl -s -u root:root1234 \
78
- -H "Content-Type: application/json" \
79
- -H "Origin: http://localhost:8080" \
80
- -X POST http://localhost:8080/modules/graphql \
81
- -d '{
82
- "query": "{ jcr { nodesByQuery(query: \"SELECT * FROM [namespace:article] WHERE ISDESCENDANTNODE(\u0027/sites/mySite/contents\u0027)\", queryLanguage: SQL2) { nodes { path properties(language: \"fr\") { name value } } } } }"
83
- }'
84
- ```
48
+ To find a batch of nodes to translate:
85
49
 
86
- Look for nodes where i18n fields (`jcr:title`, `body`, etc.) have empty or null `value`.
50
+ ```
51
+ tool: content.search
52
+ args: {
53
+ "siteKey": "SITE_KEY",
54
+ "nodeType": "jmix:droppableContent",
55
+ "locale": "en",
56
+ "limit": 50
57
+ }
58
+ ```
87
59
 
88
60
  ---
89
61
 
90
- ## Step 3 — Set i18n properties
91
-
92
- ### Single node
62
+ ## Step 3 — Identify which properties are i18n
93
63
 
94
- ```bash
95
- curl -s -u root:root1234 \
96
- -H "Content-Type: application/json" \
97
- -H "Origin: http://localhost:8080" \
98
- -X POST http://localhost:8080/modules/graphql \
99
- -d '{
100
- "query": "mutation { jcr { mutateNode(pathOrId: \"/sites/mySite/contents/articles/my-article\") { setPropertiesBatch(properties: [{name: \"jcr:title\", value: \"Mon article\", language: \"fr\"}, {name: \"body\", value: \"<p>Contenu ici</p>\", language: \"fr\"}]) { path } } } }"
101
- }'
64
+ ```
65
+ tool: content.type
66
+ args: { "name": "jnt:bigText" }
102
67
  ```
103
68
 
104
- > ⚠️ Use `setPropertiesBatch` (plural), not `setProperty` (singular — does not exist in the Jahia GraphQL API).
69
+ Translate only properties marked as internationalized.
105
70
 
106
- ### Critical ordering rule
71
+ Common i18n properties:
72
+ - `jcr:title`
73
+ - `text`
74
+ - `body`
75
+ - `description`
76
+ - `subtitle`
107
77
 
108
- When a content type has **mandatory** i18n fields (other than `jcr:title`), set those **before** `jcr:title`. Setting `jcr:title` first can trigger a constraint check before all mandatory fields are present.
78
+ Common non-i18n properties:
79
+ - `j:view`
80
+ - `j:templateName`
81
+ - `jcr:primaryType`
82
+ - references such as `j:node`
83
+ - numeric or technical settings
109
84
 
110
- The safe pattern — set all mandatory i18n fields in a single `setPropertiesBatch` call:
85
+ ---
111
86
 
112
- ```bash
113
- curl -s -u root:root1234 \
114
- -H "Content-Type: application/json" \
115
- -H "Origin: http://localhost:8080" \
116
- -X POST http://localhost:8080/modules/graphql \
117
- -d '{
118
- "query": "mutation { jcr { mutateNode(pathOrId: \"/sites/mySite/contents/articles/my-article\") { setPropertiesBatch(properties: [{name: \"body\", value: \"<p>Contenu ici</p>\", language: \"fr\"}, {name: \"jcr:title\", value: \"Mon article\", language: \"fr\"}]) { path } } } }"
119
- }'
120
- ```
87
+ ## Step 4 — Write translated properties
121
88
 
122
- ---
89
+ Use `content.update` with the target locale:
123
90
 
124
- ## Step 4 — Bulk translation with Python
91
+ ```
92
+ tool: content.update
93
+ args: {
94
+ "path": "/sites/SITE_KEY/home/about/main/intro-text",
95
+ "locale": "fr",
96
+ "properties": {
97
+ "jcr:title": "À propos",
98
+ "text": "<p>Bienvenue sur notre site.</p>"
99
+ }
100
+ }
101
+ ```
125
102
 
126
- For translating many nodes at once:
103
+ Key rules:
104
+ - Set all mandatory i18n properties in the same call.
105
+ - Translate only i18n properties.
106
+ - Preserve the HTML structure for rich text.
107
+ - Do not translate technical choicelist values.
127
108
 
128
- ```python
129
- import json
130
- from urllib.request import Request, urlopen
109
+ ---
131
110
 
132
- JAHIA = "http://localhost:8080"
133
- AUTH = ("root", "root1234")
111
+ ## Step 5 — Translate page titles
134
112
 
135
- import base64
136
- token = base64.b64encode(f"{AUTH[0]}:{AUTH[1]}".encode()).decode()
137
- HEADERS = {
138
- "Content-Type": "application/json",
139
- "Origin": JAHIA,
140
- "Authorization": f"Basic {token}",
141
- }
113
+ Page titles are also i18n:
142
114
 
143
- def gql(query):
144
- body = json.dumps({"query": query}).encode()
145
- req = Request(f"{JAHIA}/modules/graphql", data=body, headers=HEADERS, method="POST")
146
- with urlopen(req) as r:
147
- d = json.loads(r.read())
148
- if "errors" in d:
149
- print("ERR:", d["errors"][0]["message"][:120])
150
- return d
151
-
152
- # 1. List all articles missing French title
153
- result = gql(
154
- '{ jcr { nodesByQuery(query: "SELECT * FROM [namespace:article] '
155
- "WHERE ISDESCENDANTNODE('/sites/mySite/contents') "
156
- 'ORDER BY [jcr:path] ASC", queryLanguage: SQL2) '
157
- '{ nodes { path properties(language: "fr") { name value } } } } }'
158
- )
159
-
160
- nodes = result["data"]["jcr"]["nodesByQuery"]["nodes"]
161
- missing_fr = [
162
- n["path"]
163
- for n in nodes
164
- if not any(p["name"] == "jcr:title" and p["value"] for p in n["properties"])
165
- ]
166
-
167
- # 2. Set French translations (replace with actual translated values)
168
- translations = {
169
- "/sites/mySite/contents/articles/article-1": ("Titre FR 1", "<p>Corps FR 1</p>"),
170
- "/sites/mySite/contents/articles/article-2": ("Titre FR 2", "<p>Corps FR 2</p>"),
115
+ ```
116
+ tool: content.update
117
+ args: {
118
+ "path": "/sites/SITE_KEY/home/about",
119
+ "locale": "fr",
120
+ "properties": {
121
+ "jcr:title": "À propos"
122
+ }
171
123
  }
172
-
173
- for path, (title, body) in translations.items():
174
- r = gql(
175
- f'mutation {{ jcr {{ mutateNode(pathOrId: "{path}") {{'
176
- f' setPropertiesBatch(properties: ['
177
- f' {{name: "body", value: {json.dumps(body)}, language: "fr"}},'
178
- f' {{name: "jcr:title", value: {json.dumps(title)}, language: "fr"}}'
179
- f' ]) {{ path }} }} }} }}'
180
- )
181
- ok = "errors" not in r
182
- print(f" {'✓' if ok else '✗'} {path.split('/')[-1]}")
183
124
  ```
184
125
 
185
126
  ---
186
127
 
187
- ## Step 5Choicelist fields and view-level translations
128
+ ## Step 6Verify translations
188
129
 
189
- ### Choicelist fields should NOT be i18n
130
+ Check the translated locale directly:
190
131
 
191
- If a CND property uses a choicelist (e.g. `category`, `status`), its stored values are language-agnostic keys like `"featured"` or `"draft"`. The display label is translated **in the view**, not in the JCR.
132
+ ```
133
+ tool: content.get
134
+ args: {
135
+ "path": "/sites/SITE_KEY/home/about/main/intro-text",
136
+ "locale": "fr"
137
+ }
138
+ ```
192
139
 
193
- ```tsx
194
- // In the view component — translate the stored key to a display label
195
- const STATUS_LABELS: Record<string, Record<string, string>> = {
196
- en: { featured: "Featured", draft: "Draft" },
197
- fr: { featured: "En vedette", draft: "Brouillon" },
198
- };
140
+ Or search in the target locale:
199
141
 
200
- const lang = renderContext.getMainResourceLocale().getLanguage();
201
- const statusKey = properties.status as string;
202
- const statusLabel = STATUS_LABELS[lang]?.[statusKey] ?? statusKey;
142
+ ```
143
+ tool: content.search
144
+ args: {
145
+ "siteKey": "SITE_KEY",
146
+ "nodeType": "jmix:droppableContent",
147
+ "locale": "fr",
148
+ "limit": 20,
149
+ "projectProperties": ["jcr:title"]
150
+ }
203
151
  ```
204
152
 
205
- Do **not** add `i18n` to the CND property for choicelists — the key should be the same in all languages.
206
-
207
- ### Hardcoded UI strings
153
+ ---
208
154
 
209
- View-level strings that are not stored in JCR (button labels, headings, placeholder text) need locale-keyed label maps in the component:
155
+ ## Step 7 Publish the translated locale
210
156
 
211
- ```tsx
212
- const LABELS = {
213
- en: { readMore: "Read more", by: "By" },
214
- fr: { readMore: "Lire la suite", by: "Par" },
215
- };
157
+ Publish the page or subtree in the target language:
216
158
 
217
- const t = LABELS[renderContext.getMainResourceLocale().getLanguage()] ?? LABELS.en;
218
- // Usage: <a>{t.readMore}</a>
219
159
  ```
220
-
221
- ---
222
-
223
- ## Step 6 — Clean up orphaned translation nodes
224
-
225
- When you remove the `i18n` flag from a CND property (or delete a language from the site), orphaned `j:translation_XX` child nodes may remain. Inspect and remove them if needed:
226
-
227
- ```bash
228
- # Find translation sub-nodes for a content node
229
- curl -s -u root:root1234 \
230
- -H "Content-Type: application/json" \
231
- -H "Origin: http://localhost:8080" \
232
- -X POST http://localhost:8080/modules/graphql \
233
- -d '{
234
- "query": "{ jcr { nodeByPath(path: \"/sites/mySite/contents/articles/my-article\") { children { nodes { name primaryNodeType { name } } } } } }"
235
- }'
236
-
237
- # Delete an orphaned translation node
238
- curl -s -u root:root1234 \
239
- -H "Content-Type: application/json" \
240
- -H "Origin: http://localhost:8080" \
241
- -X POST http://localhost:8080/modules/graphql \
242
- -d '{
243
- "query": "mutation { jcr { deleteNode(pathOrId: \"/sites/mySite/contents/articles/my-article/j:translation_fr\") }"
244
- }'
160
+ tool: publication.publish
161
+ args: {
162
+ "path": "/sites/SITE_KEY/home/about",
163
+ "languages": ["fr"]
164
+ }
245
165
  ```
246
166
 
167
+ If the translation touches both a page and child content, publish the page path so the subtree is included.
168
+
247
169
  ---
248
170
 
249
- ## Step 7 — Publish translations
250
-
251
- After setting i18n properties, republish to make them live:
252
-
253
- ```bash
254
- # Publish a single node for a specific language
255
- curl -s -u root:root1234 \
256
- -H "Content-Type: application/json" \
257
- -H "Origin: http://localhost:8080" \
258
- -X POST http://localhost:8080/modules/graphql \
259
- -d '{
260
- "query": "mutation { jcr { mutateNode(pathOrId: \"/sites/mySite/contents/articles/my-article\") { publish(languages: [\"fr\"]) } } }"
261
- }'
262
-
263
- # Publish all articles in both languages
264
- curl -s -u root:root1234 \
265
- -H "Content-Type: application/json" \
266
- -H "Origin: http://localhost:8080" \
267
- -X POST http://localhost:8080/modules/graphql \
268
- -d '{
269
- "query": "mutation { jcr { mutateNodesByQuery(query: \"SELECT * FROM [namespace:article] WHERE ISDESCENDANTNODE(\u0027/sites/mySite/contents\u0027)\", queryLanguage: SQL2) { publish(languages: [\"en\", \"fr\"]) } } }"
270
- }'
171
+ ## Common patterns
172
+
173
+ ### Translate all content under a page
174
+
175
+ 1. Discover the page structure:
176
+ ```
177
+ tool: page.structure
178
+ args: { "path": "/sites/SITE_KEY/home/about" }
179
+ ```
180
+ 2. Read each child node in the source locale:
181
+ ```
182
+ tool: content.get
183
+ args: { "path": "CHILD_PATH", "locale": "en" }
184
+ ```
185
+ 3. Write translated values to the target locale:
186
+ ```
187
+ tool: content.update
188
+ args: {
189
+ "path": "CHILD_PATH",
190
+ "locale": "fr",
191
+ "properties": { "jcr:title": "...", "text": "..." }
192
+ }
193
+ ```
194
+ 4. Publish the page in the new language.
195
+
196
+ ### Audit whether a page is publish-ready in the new locale
197
+
198
+ ```
199
+ tool: publication.status
200
+ args: {
201
+ "path": "/sites/SITE_KEY/home/about",
202
+ "language": "fr",
203
+ "subNodes": true,
204
+ "references": true
205
+ }
271
206
  ```
272
207
 
273
208
  ---
@@ -276,22 +211,16 @@ curl -s -u root:root1234 \
276
211
 
277
212
  | Error | Cause | Fix |
278
213
  |-------|-------|-----|
279
- | `Permission denied` | Missing `Origin` header | Add `-H "Origin: http://localhost:8080"` |
280
- | i18n property returned empty after set | Missing `language:` in `properties()` query | Add `language: "fr"` to read call |
281
- | `ConstraintViolationException` on title set | Mandatory i18n field not set first | Use `setPropertiesBatch` with all mandatory fields in one call |
282
- | Language not appearing in site | `j:languages` mutation only had the new language | Pass the full list: `["en", "fr"]` |
283
- | Choicelist key changed per language | Property incorrectly declared `i18n` in CND | Remove `i18n` from the CND property; translate keys in the view |
214
+ | `MANDATORY_PROPERTY_MISSING` | Not all required i18n properties were set | Set all mandatory translated properties in one `content.update` call |
215
+ | Language not available | Locale not enabled on the site | Add the locale to the site first |
216
+ | Properties appear empty | Wrong locale was used | Verify configured locales with `site.get` |
217
+ | Translation not visible on the public site | It is still only in EDIT | Publish with `publication.publish` |
284
218
 
285
219
  ---
286
220
 
287
- ## Workflow summary
221
+ ## Related skills
222
+
223
+ - `/jahia-content-explore-structure` — find the right pages, nodes, and types first
224
+ - `/jahia-content-publish` — publish translated content and inspect language-scoped status
225
+ - `/jahia-content-create-content` — create new pages or content that will later need translation
288
226
 
289
- ```
290
- 1. Enable language → mutateNode j:languages with full list
291
- 2. Audit → nodesByQuery with properties(language: "XX") to find gaps
292
- 3. Translate → setPropertiesBatch with language: "XX" for each i18n field
293
- 4. View strings → add locale-keyed label maps in .server.tsx
294
- 5. Choicelists → translate keys in the view, not the JCR
295
- 6. Publish → publish(languages: ["XX"]) for all affected nodes
296
- 7. Verify → query back with language: "XX" to confirm values
297
- ```
@@ -110,10 +110,10 @@ color: #595959; /* 7:1 ratio on white */
110
110
  /* Bad */
111
111
  <img src={buildNodeUrl(props.image)} />
112
112
 
113
- /* Fix — use content from CND, fall back to empty string for decorative */
114
- <img src={buildNodeUrl(props.image)} alt={props.imageAlt ?? ""} />
113
+ /* Fix — use the image node's jcr:title, fall back to empty string for decorative */
114
+ <img src={buildNodeUrl(props.image)} alt={props.image?.getPropertyAsString("jcr:title") ?? ""} />
115
115
  ```
116
- Add `- imageAlt (string) i18n` to the CND and `imageAlt?: string` to `types.ts`.
116
+ The image node already has `jcr:title` (from `mix:title`). **Do not add `imageAlt (string) i18n`** to the CND.
117
117
 
118
118
  **`button-name`** — `<button>` or `<a>` is empty (icon-only without label)
119
119
  ```tsx
@@ -43,15 +43,18 @@ Has children: <yes: ChildType / no>
43
43
 
44
44
  ---
45
45
 
46
- ## Step 2 — Invoke `jahia-dev-define-content-type`
46
+ ## Step 2 — REQUIRED: Invoke `/jahia-dev-define-content-type`
47
47
 
48
- Use the instructions from the `jahia-dev-define-content-type` skill to:
48
+ **Do not write CND manually.** Jahia-specific patterns (`choicelist[linkTypeInitializer]`, `mix:title`, child nodes for CTAs) are not in LLM training data — writing CND from memory always produces broken output. This skill delegates to `@jahia-cnd-author` which loads the correct reference files.
49
49
 
50
- 1. Identify the namespace (check `settings/definitions.cnd`)
51
- 2. Create `src/components/<Category>/<Name>/definition.cnd`
52
- 3. Create `src/components/<Category>/<Name>/types.ts`
53
- 4. Run `yarn build && yarn jahia-deploy` to push the type to Jahia
54
- 5. Verify the content type appears in the Jahia content editor
50
+ Invoke `/jahia-dev-define-content-type` in a sub-agent job. Pass the component spec. Wait for it to confirm PASS before continuing.
51
+
52
+ The skill will:
53
+ 1. Confirm the namespace (from `settings/definitions.cnd`)
54
+ 2. Invoke `@jahia-cnd-author` to create `src/components/<Category>/<Name>/definition.cnd`
55
+ 3. Invoke `@jahia-cnd-author` to create `src/components/<Category>/<Name>/types.ts`
56
+
57
+ **Do not proceed to Step 3 until the CND review is PASS.**
55
58
 
56
59
  ---
57
60
 
@@ -14,35 +14,72 @@ A **page template** defines the full layout of a page. It is registered with `co
14
14
 
15
15
  ## Step 1 — Create the template file
16
16
 
17
- Page templates live in `src/templates/Page/`. Name the file `<templateName>.server.tsx`.
17
+ Page templates live in `src/templates/<ModuleName>Template/`. Name the file `default.server.tsx`.
18
18
 
19
19
  ```tsx
20
- import { Area, AbsoluteArea, jahiaComponent } from "@jahia/javascript-modules-library";
21
- import { Layout } from "../Layout.jsx";
20
+ import React from "react";
21
+ import { Area, AbsoluteArea, getChildNodes, buildNodeUrl, jahiaComponent } from "@jahia/javascript-modules-library";
22
+ import styles from "./template.module.css";
22
23
 
23
24
  jahiaComponent(
24
25
  {
25
26
  componentType: "template", // "template" for full pages, not "view"
26
27
  nodeType: "jnt:page", // always jnt:page for page templates
27
- displayName: "Single Column",
28
- name: "singleColumn", // used in Jahia UI when selecting a template
28
+ displayName: "Default Template",
29
+ name: "default",
30
+ },
31
+ ({ "jcr:title": title }, { renderContext, mainNode }) => {
32
+ // Pages live under /sites/<key>/home — not directly under the site node
33
+ const siteHome = renderContext.getSite().getNode("home");
34
+ const navPages = getChildNodes(siteHome, -1, 0, n => n.isNodeType("jnt:page"));
35
+ const siteName = renderContext.getSite().getPropertyAsString("j:siteTitle") ?? renderContext.getSite().getName();
36
+ return (
37
+ <html lang="en">
38
+ <head>
39
+ <meta charSet="UTF-8" />
40
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
41
+ {/* jcr:title is the short page name — template appends site name for SEO */}
42
+ <title>{title}{siteName ? ` | ${siteName}` : ""}</title>
43
+ </head>
44
+ <body>
45
+ <a href="#main-content" className={styles.skipLink}>Skip to main content</a>
46
+ <header className={styles.header}>
47
+ <nav aria-label="Main navigation">
48
+ <ul className={styles.navList}>
49
+ <li key={siteHome.getPath()}>
50
+ <a href={buildNodeUrl(siteHome)} aria-current={siteHome.getPath() === mainNode.getPath() ? "page" : undefined}>
51
+ {siteHome.getPropertyAsString("jcr:title") ?? siteHome.getName()}
52
+ </a>
53
+ </li>
54
+ {navPages.map(page => (
55
+ <li key={page.getPath()}>
56
+ <a
57
+ href={buildNodeUrl(page)}
58
+ aria-current={page.getPath() === mainNode.getPath() ? "page" : undefined}
59
+ >
60
+ {page.getPropertyAsString("jcr:title") ?? page.getName()}
61
+ </a>
62
+ </li>
63
+ ))}
64
+ </ul>
65
+ </nav>
66
+ </header>
67
+ <main id="main-content">
68
+ <h1 className={styles.pageTitle}>{title}</h1>
69
+ <Area name="pagecontent" />
70
+ </main>
71
+ <footer className={styles.footer}>
72
+ <AbsoluteArea name="footer" parent={renderContext.getSite()} />
73
+ <p className={styles.copyright}>{"© "}{renderContext.getSite().getName()}</p>
74
+ </footer>
75
+ </body>
76
+ </html>
77
+ );
29
78
  },
30
- ({ "jcr:title": title }, { renderContext }) => (
31
- <Layout title={title}>
32
- <Area name="header" nodeType="namespace:header" />
33
- <main style={{ maxWidth: "40rem", margin: "0 auto" }}>
34
- <Area name="main" />
35
- </main>
36
- <AbsoluteArea
37
- name="footer"
38
- parent={renderContext.getSite()}
39
- nodeType="namespace:footer"
40
- />
41
- </Layout>
42
- ),
43
79
  );
44
80
  ```
45
81
 
82
+
46
83
  ---
47
84
 
48
85
  ## Step 2 — Choose: Area vs AbsoluteArea
@@ -266,13 +303,14 @@ After deploying, the new template will appear in the **template selection** step
266
303
  ---
267
304
 
268
305
  ## Validation checklist
269
- - [ ] File is in `src/templates/Page/`
270
306
  - [ ] `componentType: "template"` and `nodeType: "jnt:page"`
271
307
  - [ ] `name` is set (used in Jahia UI template picker)
308
+ - [ ] Skip link present: `<a href="#main-content">Skip to main content</a>`
309
+ - [ ] Nav built from `getChildNodes(site.getNode('home'), ...)` — pages are children of `home`, not of the site node
310
+ - [ ] `<h1>{title}</h1>` in the template — no `<h1>` in any component
311
+ - [ ] `<footer>` landmark always has visible content (never empty)
272
312
  - [ ] Areas use a custom area node type (not bare `<Area name="..."/>`)
273
313
  - [ ] Custom area type has `jmix:list`, `jmix:hiddenType`, and `orderable`
274
- - [ ] `AbsoluteArea` uses `renderContext.getSite()` as parent
275
- - [ ] Structural container nodes use `jmix:hiddenType` (hidden from picker)
276
314
  - [ ] Decision made: page template vs sectioning component (see Step 4)
277
315
  - [ ] `yarn build && yarn jahia-deploy` run and template appears in Jahia UI
278
316