@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.
- package/CHANGELOG.md +8 -0
- package/README.md +28 -0
- package/dist/claude/.claude/agents/cnd-child-nodes.md +74 -0
- package/dist/claude/.claude/agents/cnd-jahia-mixins.md +113 -0
- package/dist/claude/.claude/agents/cnd-numbers-dates.md +61 -0
- package/dist/claude/.claude/agents/cnd-string-selectors.md +94 -0
- package/dist/claude/.claude/agents/jahia-cnd-author.md +130 -0
- package/dist/claude/.claude/agents/jahia-dev-worker.md +264 -0
- package/dist/claude/.claude/agents/jahia-reviewer.md +105 -0
- package/dist/claude/.claude/rules/jahia.md +15 -6
- package/dist/claude/.claude/skills/jahia/SKILL.md +23 -11
- package/dist/claude/.claude/skills/jahia-content/SKILL.md +102 -84
- package/dist/claude/.claude/skills/jahia-content-create-content/SKILL.md +255 -280
- package/dist/claude/.claude/skills/jahia-content-explore-structure/SKILL.md +187 -96
- package/dist/claude/.claude/skills/jahia-content-media-upload/SKILL.md +197 -0
- package/dist/claude/.claude/skills/jahia-content-move-content/SKILL.md +160 -165
- package/dist/claude/.claude/skills/jahia-content-organize/SKILL.md +209 -0
- package/dist/claude/.claude/skills/jahia-content-publish/SKILL.md +181 -0
- package/dist/claude/.claude/skills/jahia-content-query-content/SKILL.md +122 -92
- package/dist/claude/.claude/skills/jahia-content-translate-content/SKILL.md +154 -225
- package/dist/claude/.claude/skills/jahia-dev-accessibility/SKILL.md +3 -3
- package/dist/claude/.claude/skills/jahia-dev-build-component/SKILL.md +10 -7
- package/dist/claude/.claude/skills/jahia-dev-create-page-template/SKILL.md +59 -21
- package/dist/claude/.claude/skills/jahia-dev-create-template-set/SKILL.md +20 -47
- package/dist/claude/.claude/skills/jahia-dev-create-view/SKILL.md +3 -3
- package/dist/claude/.claude/skills/jahia-dev-cypress/SKILL.md +150 -330
- package/dist/claude/.claude/skills/jahia-dev-define-content-type/SKILL.md +43 -486
- package/dist/claude/.claude/skills/jahia-dev-define-content-type/references/modeling-decisions.md +52 -0
- package/dist/claude/.claude/skills/jahia-dev-query-content/SKILL.md +93 -296
- package/dist/claude/.claude/skills/jahia-dev-review-cnd/SKILL.md +79 -0
- package/dist/claude/.claude/skills/jahia-dev-review-cnd/scripts/check-cnd.d.mts +13 -0
- package/dist/claude/.claude/skills/jahia-dev-review-cnd/scripts/check-cnd.mjs +198 -0
- package/dist/claude/.claude/skills/jahia-dev-site-review/SKILL.md +70 -0
- package/dist/claude/.claude/skills/jahia-dev-site-review/scripts/review-pages.mjs +85 -0
- package/dist/claude/.claude/skills/jahia-dev-start-local/SKILL.md +18 -26
- package/dist/claude/.claude/skills/jahia-jcr-sql2/SKILL.md +258 -0
- package/dist/claude/.claude/skills/jahia-orchestrate/SKILL.md +148 -0
- package/dist/claude/.claude/skills/jahia-orchestrate/scripts/verify-pages.mjs +59 -0
- package/dist/claude/CLAUDE.md +16 -13
- package/dist/codex/.agents/skills/jahia/SKILL.md +23 -11
- package/dist/codex/.agents/skills/jahia-content/SKILL.md +102 -84
- package/dist/codex/.agents/skills/jahia-content-create-content/SKILL.md +255 -280
- package/dist/codex/.agents/skills/jahia-content-explore-structure/SKILL.md +187 -96
- package/dist/codex/.agents/skills/jahia-content-media-upload/SKILL.md +197 -0
- package/dist/codex/.agents/skills/jahia-content-move-content/SKILL.md +160 -165
- package/dist/codex/.agents/skills/jahia-content-organize/SKILL.md +209 -0
- package/dist/codex/.agents/skills/jahia-content-publish/SKILL.md +181 -0
- package/dist/codex/.agents/skills/jahia-content-query-content/SKILL.md +122 -92
- package/dist/codex/.agents/skills/jahia-content-translate-content/SKILL.md +154 -225
- package/dist/codex/.agents/skills/jahia-dev-accessibility/SKILL.md +3 -3
- package/dist/codex/.agents/skills/jahia-dev-build-component/SKILL.md +10 -7
- package/dist/codex/.agents/skills/jahia-dev-create-page-template/SKILL.md +59 -21
- package/dist/codex/.agents/skills/jahia-dev-create-template-set/SKILL.md +20 -47
- package/dist/codex/.agents/skills/jahia-dev-create-view/SKILL.md +3 -3
- package/dist/codex/.agents/skills/jahia-dev-cypress/SKILL.md +150 -330
- package/dist/codex/.agents/skills/jahia-dev-define-content-type/SKILL.md +43 -486
- package/dist/codex/.agents/skills/jahia-dev-define-content-type/references/modeling-decisions.md +52 -0
- package/dist/codex/.agents/skills/jahia-dev-query-content/SKILL.md +93 -296
- package/dist/codex/.agents/skills/jahia-dev-review-cnd/SKILL.md +79 -0
- package/dist/codex/.agents/skills/jahia-dev-review-cnd/scripts/check-cnd.d.mts +13 -0
- package/dist/codex/.agents/skills/jahia-dev-review-cnd/scripts/check-cnd.mjs +198 -0
- package/dist/codex/.agents/skills/jahia-dev-site-review/SKILL.md +70 -0
- package/dist/codex/.agents/skills/jahia-dev-site-review/scripts/review-pages.mjs +85 -0
- package/dist/codex/.agents/skills/jahia-dev-start-local/SKILL.md +18 -26
- package/dist/codex/.agents/skills/jahia-jcr-sql2/SKILL.md +258 -0
- package/dist/codex/.agents/skills/jahia-orchestrate/SKILL.md +148 -0
- package/dist/codex/.agents/skills/jahia-orchestrate/scripts/verify-pages.mjs +59 -0
- package/dist/codex/.codex/agents/cnd-child-nodes.toml +3 -0
- package/dist/codex/.codex/agents/cnd-jahia-mixins.toml +3 -0
- package/dist/codex/.codex/agents/cnd-numbers-dates.toml +3 -0
- package/dist/codex/.codex/agents/cnd-string-selectors.toml +3 -0
- package/dist/codex/.codex/agents/jahia-cnd-author.toml +3 -0
- package/dist/codex/.codex/agents/jahia-dev-worker.toml +3 -0
- package/dist/codex/.codex/agents/jahia-reviewer.toml +3 -0
- package/dist/codex/AGENTS.md +17 -10
- package/dist/copilot/.agents/skills/jahia/SKILL.md +23 -11
- package/dist/copilot/.agents/skills/jahia-content/SKILL.md +102 -84
- package/dist/copilot/.agents/skills/jahia-content-create-content/SKILL.md +255 -280
- package/dist/copilot/.agents/skills/jahia-content-explore-structure/SKILL.md +187 -96
- package/dist/copilot/.agents/skills/jahia-content-media-upload/SKILL.md +197 -0
- package/dist/copilot/.agents/skills/jahia-content-move-content/SKILL.md +160 -165
- package/dist/copilot/.agents/skills/jahia-content-organize/SKILL.md +209 -0
- package/dist/copilot/.agents/skills/jahia-content-publish/SKILL.md +181 -0
- package/dist/copilot/.agents/skills/jahia-content-query-content/SKILL.md +122 -92
- package/dist/copilot/.agents/skills/jahia-content-translate-content/SKILL.md +154 -225
- package/dist/copilot/.agents/skills/jahia-dev-accessibility/SKILL.md +3 -3
- package/dist/copilot/.agents/skills/jahia-dev-build-component/SKILL.md +10 -7
- package/dist/copilot/.agents/skills/jahia-dev-create-page-template/SKILL.md +59 -21
- package/dist/copilot/.agents/skills/jahia-dev-create-template-set/SKILL.md +20 -47
- package/dist/copilot/.agents/skills/jahia-dev-create-view/SKILL.md +3 -3
- package/dist/copilot/.agents/skills/jahia-dev-cypress/SKILL.md +150 -330
- package/dist/copilot/.agents/skills/jahia-dev-define-content-type/SKILL.md +43 -486
- package/dist/copilot/.agents/skills/jahia-dev-define-content-type/references/modeling-decisions.md +52 -0
- package/dist/copilot/.agents/skills/jahia-dev-query-content/SKILL.md +93 -296
- package/dist/copilot/.agents/skills/jahia-dev-review-cnd/SKILL.md +79 -0
- package/dist/copilot/.agents/skills/jahia-dev-review-cnd/scripts/check-cnd.d.mts +13 -0
- package/dist/copilot/.agents/skills/jahia-dev-review-cnd/scripts/check-cnd.mjs +198 -0
- package/dist/copilot/.agents/skills/jahia-dev-site-review/SKILL.md +70 -0
- package/dist/copilot/.agents/skills/jahia-dev-site-review/scripts/review-pages.mjs +85 -0
- package/dist/copilot/.agents/skills/jahia-dev-start-local/SKILL.md +18 -26
- package/dist/copilot/.agents/skills/jahia-jcr-sql2/SKILL.md +258 -0
- package/dist/copilot/.agents/skills/jahia-orchestrate/SKILL.md +148 -0
- package/dist/copilot/.agents/skills/jahia-orchestrate/scripts/verify-pages.mjs +59 -0
- package/dist/copilot/AGENTS.md +17 -10
- package/dist/cursor/.agents/skills/jahia/SKILL.md +23 -11
- package/dist/cursor/.agents/skills/jahia-content/SKILL.md +102 -84
- package/dist/cursor/.agents/skills/jahia-content-create-content/SKILL.md +255 -280
- package/dist/cursor/.agents/skills/jahia-content-explore-structure/SKILL.md +187 -96
- package/dist/cursor/.agents/skills/jahia-content-media-upload/SKILL.md +197 -0
- package/dist/cursor/.agents/skills/jahia-content-move-content/SKILL.md +160 -165
- package/dist/cursor/.agents/skills/jahia-content-organize/SKILL.md +209 -0
- package/dist/cursor/.agents/skills/jahia-content-publish/SKILL.md +181 -0
- package/dist/cursor/.agents/skills/jahia-content-query-content/SKILL.md +122 -92
- package/dist/cursor/.agents/skills/jahia-content-translate-content/SKILL.md +154 -225
- package/dist/cursor/.agents/skills/jahia-dev-accessibility/SKILL.md +3 -3
- package/dist/cursor/.agents/skills/jahia-dev-build-component/SKILL.md +10 -7
- package/dist/cursor/.agents/skills/jahia-dev-create-page-template/SKILL.md +59 -21
- package/dist/cursor/.agents/skills/jahia-dev-create-template-set/SKILL.md +20 -47
- package/dist/cursor/.agents/skills/jahia-dev-create-view/SKILL.md +3 -3
- package/dist/cursor/.agents/skills/jahia-dev-cypress/SKILL.md +150 -330
- package/dist/cursor/.agents/skills/jahia-dev-define-content-type/SKILL.md +43 -486
- package/dist/cursor/.agents/skills/jahia-dev-define-content-type/references/modeling-decisions.md +52 -0
- package/dist/cursor/.agents/skills/jahia-dev-query-content/SKILL.md +93 -296
- package/dist/cursor/.agents/skills/jahia-dev-review-cnd/SKILL.md +79 -0
- package/dist/cursor/.agents/skills/jahia-dev-review-cnd/scripts/check-cnd.d.mts +13 -0
- package/dist/cursor/.agents/skills/jahia-dev-review-cnd/scripts/check-cnd.mjs +198 -0
- package/dist/cursor/.agents/skills/jahia-dev-site-review/SKILL.md +70 -0
- package/dist/cursor/.agents/skills/jahia-dev-site-review/scripts/review-pages.mjs +85 -0
- package/dist/cursor/.agents/skills/jahia-dev-start-local/SKILL.md +18 -26
- package/dist/cursor/.agents/skills/jahia-jcr-sql2/SKILL.md +258 -0
- package/dist/cursor/.agents/skills/jahia-orchestrate/SKILL.md +148 -0
- package/dist/cursor/.agents/skills/jahia-orchestrate/scripts/verify-pages.mjs +59 -0
- package/dist/cursor/.cursor/agents/cnd-child-nodes.md +74 -0
- package/dist/cursor/.cursor/agents/cnd-jahia-mixins.md +113 -0
- package/dist/cursor/.cursor/agents/cnd-numbers-dates.md +61 -0
- package/dist/cursor/.cursor/agents/cnd-string-selectors.md +94 -0
- package/dist/cursor/.cursor/agents/jahia-cnd-author.md +130 -0
- package/dist/cursor/.cursor/agents/jahia-dev-worker.md +264 -0
- package/dist/cursor/.cursor/agents/jahia-reviewer.md +105 -0
- package/dist/cursor/.cursor/rules/jahia.mdc +15 -6
- package/dist/gemini/.agents/skills/jahia/SKILL.md +23 -11
- package/dist/gemini/.agents/skills/jahia-content/SKILL.md +102 -84
- package/dist/gemini/.agents/skills/jahia-content-create-content/SKILL.md +255 -280
- package/dist/gemini/.agents/skills/jahia-content-explore-structure/SKILL.md +187 -96
- package/dist/gemini/.agents/skills/jahia-content-media-upload/SKILL.md +197 -0
- package/dist/gemini/.agents/skills/jahia-content-move-content/SKILL.md +160 -165
- package/dist/gemini/.agents/skills/jahia-content-organize/SKILL.md +209 -0
- package/dist/gemini/.agents/skills/jahia-content-publish/SKILL.md +181 -0
- package/dist/gemini/.agents/skills/jahia-content-query-content/SKILL.md +122 -92
- package/dist/gemini/.agents/skills/jahia-content-translate-content/SKILL.md +154 -225
- package/dist/gemini/.agents/skills/jahia-dev-accessibility/SKILL.md +3 -3
- package/dist/gemini/.agents/skills/jahia-dev-build-component/SKILL.md +10 -7
- package/dist/gemini/.agents/skills/jahia-dev-create-page-template/SKILL.md +59 -21
- package/dist/gemini/.agents/skills/jahia-dev-create-template-set/SKILL.md +20 -47
- package/dist/gemini/.agents/skills/jahia-dev-create-view/SKILL.md +3 -3
- package/dist/gemini/.agents/skills/jahia-dev-cypress/SKILL.md +150 -330
- package/dist/gemini/.agents/skills/jahia-dev-define-content-type/SKILL.md +43 -486
- package/dist/gemini/.agents/skills/jahia-dev-define-content-type/references/modeling-decisions.md +52 -0
- package/dist/gemini/.agents/skills/jahia-dev-query-content/SKILL.md +93 -296
- package/dist/gemini/.agents/skills/jahia-dev-review-cnd/SKILL.md +79 -0
- package/dist/gemini/.agents/skills/jahia-dev-review-cnd/scripts/check-cnd.d.mts +13 -0
- package/dist/gemini/.agents/skills/jahia-dev-review-cnd/scripts/check-cnd.mjs +198 -0
- package/dist/gemini/.agents/skills/jahia-dev-site-review/SKILL.md +70 -0
- package/dist/gemini/.agents/skills/jahia-dev-site-review/scripts/review-pages.mjs +85 -0
- package/dist/gemini/.agents/skills/jahia-dev-start-local/SKILL.md +18 -26
- package/dist/gemini/.agents/skills/jahia-jcr-sql2/SKILL.md +258 -0
- package/dist/gemini/.agents/skills/jahia-orchestrate/SKILL.md +148 -0
- package/dist/gemini/.agents/skills/jahia-orchestrate/scripts/verify-pages.mjs +59 -0
- package/dist/gemini/AGENTS.md +17 -10
- package/dist/gemini/GEMINI.md +2 -2
- package/dist/index.js +13 -0
- package/dist/opencode/.agents/skills/jahia/SKILL.md +23 -11
- package/dist/opencode/.agents/skills/jahia-content/SKILL.md +102 -84
- package/dist/opencode/.agents/skills/jahia-content-create-content/SKILL.md +255 -280
- package/dist/opencode/.agents/skills/jahia-content-explore-structure/SKILL.md +187 -96
- package/dist/opencode/.agents/skills/jahia-content-media-upload/SKILL.md +197 -0
- package/dist/opencode/.agents/skills/jahia-content-move-content/SKILL.md +160 -165
- package/dist/opencode/.agents/skills/jahia-content-organize/SKILL.md +209 -0
- package/dist/opencode/.agents/skills/jahia-content-publish/SKILL.md +181 -0
- package/dist/opencode/.agents/skills/jahia-content-query-content/SKILL.md +122 -92
- package/dist/opencode/.agents/skills/jahia-content-translate-content/SKILL.md +154 -225
- package/dist/opencode/.agents/skills/jahia-dev-accessibility/SKILL.md +3 -3
- package/dist/opencode/.agents/skills/jahia-dev-build-component/SKILL.md +10 -7
- package/dist/opencode/.agents/skills/jahia-dev-create-page-template/SKILL.md +59 -21
- package/dist/opencode/.agents/skills/jahia-dev-create-template-set/SKILL.md +20 -47
- package/dist/opencode/.agents/skills/jahia-dev-create-view/SKILL.md +3 -3
- package/dist/opencode/.agents/skills/jahia-dev-cypress/SKILL.md +150 -330
- package/dist/opencode/.agents/skills/jahia-dev-define-content-type/SKILL.md +43 -486
- package/dist/opencode/.agents/skills/jahia-dev-define-content-type/references/modeling-decisions.md +52 -0
- package/dist/opencode/.agents/skills/jahia-dev-query-content/SKILL.md +93 -296
- package/dist/opencode/.agents/skills/jahia-dev-review-cnd/SKILL.md +79 -0
- package/dist/opencode/.agents/skills/jahia-dev-review-cnd/scripts/check-cnd.d.mts +13 -0
- package/dist/opencode/.agents/skills/jahia-dev-review-cnd/scripts/check-cnd.mjs +198 -0
- package/dist/opencode/.agents/skills/jahia-dev-site-review/SKILL.md +70 -0
- package/dist/opencode/.agents/skills/jahia-dev-site-review/scripts/review-pages.mjs +85 -0
- package/dist/opencode/.agents/skills/jahia-dev-start-local/SKILL.md +18 -26
- package/dist/opencode/.agents/skills/jahia-jcr-sql2/SKILL.md +258 -0
- package/dist/opencode/.agents/skills/jahia-orchestrate/SKILL.md +148 -0
- package/dist/opencode/.agents/skills/jahia-orchestrate/scripts/verify-pages.mjs +59 -0
- package/dist/opencode/.opencode/agents/cnd-child-nodes.md +74 -0
- package/dist/opencode/.opencode/agents/cnd-jahia-mixins.md +113 -0
- package/dist/opencode/.opencode/agents/cnd-numbers-dates.md +61 -0
- package/dist/opencode/.opencode/agents/cnd-string-selectors.md +94 -0
- package/dist/opencode/.opencode/agents/jahia-cnd-author.md +130 -0
- package/dist/opencode/.opencode/agents/jahia-dev-worker.md +264 -0
- package/dist/opencode/.opencode/agents/jahia-reviewer.md +105 -0
- package/dist/opencode/AGENTS.md +17 -10
- package/dist/windsurf/.windsurf/rules/jahia.md +15 -6
- package/dist/windsurf/.windsurf/skills/jahia/SKILL.md +23 -11
- package/dist/windsurf/.windsurf/skills/jahia-content/SKILL.md +102 -84
- package/dist/windsurf/.windsurf/skills/jahia-content-create-content/SKILL.md +255 -280
- package/dist/windsurf/.windsurf/skills/jahia-content-explore-structure/SKILL.md +187 -96
- package/dist/windsurf/.windsurf/skills/jahia-content-media-upload/SKILL.md +197 -0
- package/dist/windsurf/.windsurf/skills/jahia-content-move-content/SKILL.md +160 -165
- package/dist/windsurf/.windsurf/skills/jahia-content-organize/SKILL.md +209 -0
- package/dist/windsurf/.windsurf/skills/jahia-content-publish/SKILL.md +181 -0
- package/dist/windsurf/.windsurf/skills/jahia-content-query-content/SKILL.md +122 -92
- package/dist/windsurf/.windsurf/skills/jahia-content-translate-content/SKILL.md +154 -225
- package/dist/windsurf/.windsurf/skills/jahia-dev-accessibility/SKILL.md +3 -3
- package/dist/windsurf/.windsurf/skills/jahia-dev-build-component/SKILL.md +10 -7
- package/dist/windsurf/.windsurf/skills/jahia-dev-create-page-template/SKILL.md +59 -21
- package/dist/windsurf/.windsurf/skills/jahia-dev-create-template-set/SKILL.md +20 -47
- package/dist/windsurf/.windsurf/skills/jahia-dev-create-view/SKILL.md +3 -3
- package/dist/windsurf/.windsurf/skills/jahia-dev-cypress/SKILL.md +150 -330
- package/dist/windsurf/.windsurf/skills/jahia-dev-define-content-type/SKILL.md +43 -486
- package/dist/windsurf/.windsurf/skills/jahia-dev-define-content-type/references/modeling-decisions.md +52 -0
- package/dist/windsurf/.windsurf/skills/jahia-dev-query-content/SKILL.md +93 -296
- package/dist/windsurf/.windsurf/skills/jahia-dev-review-cnd/SKILL.md +79 -0
- package/dist/windsurf/.windsurf/skills/jahia-dev-review-cnd/scripts/check-cnd.d.mts +13 -0
- package/dist/windsurf/.windsurf/skills/jahia-dev-review-cnd/scripts/check-cnd.mjs +198 -0
- package/dist/windsurf/.windsurf/skills/jahia-dev-site-review/SKILL.md +70 -0
- package/dist/windsurf/.windsurf/skills/jahia-dev-site-review/scripts/review-pages.mjs +85 -0
- package/dist/windsurf/.windsurf/skills/jahia-dev-start-local/SKILL.md +18 -26
- package/dist/windsurf/.windsurf/skills/jahia-jcr-sql2/SKILL.md +258 -0
- package/dist/windsurf/.windsurf/skills/jahia-orchestrate/SKILL.md +148 -0
- package/dist/windsurf/.windsurf/skills/jahia-orchestrate/scripts/verify-pages.mjs +59 -0
- package/dist/windsurf/AGENTS.md +17 -10
- package/package.json +3 -3
|
@@ -1,53 +1,41 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: jahia-dev-query-content
|
|
3
|
-
description:
|
|
4
|
-
allowed-tools: Bash, Read, Write, Edit, WebFetch
|
|
3
|
+
description: Designs JCR-SQL2 content queries for Jahia page-builder listings and JS module views. Use when asked to list content from folders, filter items, sort results, or wire `useJCRQuery` into a template-set component.
|
|
5
4
|
---
|
|
6
5
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
Jahia stores all content in a tree-based **Java Content Repository (JCR)**. Content can be queried using **JCR-SQL2**, a SQL-like language. This is used to build listings (blogs, news, team members, etc.) from content stored in **Content Folders**.
|
|
6
|
+
# Skill: jahia-dev-query-content
|
|
10
7
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
2. **Server-side hook**: `useJCRQuery` in a `.server.tsx` view
|
|
14
|
-
3. **Client-side hook**: `useJCRQuery` in a `.client.tsx` island (for dynamic, browser-triggered queries)
|
|
8
|
+
Use this skill when building content listings in Jahia template sets.
|
|
9
|
+
For pure JCR-SQL2 language rules, full-text syntax, joins, pagination, and performance guardrails, also use `/jahia-jcr-sql2`.
|
|
15
10
|
|
|
16
11
|
---
|
|
17
12
|
|
|
18
|
-
##
|
|
13
|
+
## Overview
|
|
19
14
|
|
|
20
|
-
|
|
15
|
+
Jahia stores editorial content in the JCR. In template sets, you usually query it in one of three ways:
|
|
21
16
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
3. Right-click → **New Folder**, name it (e.g. `blog`)
|
|
26
|
-
4. Create content items inside this folder
|
|
17
|
+
1. **Page Builder query component** — no-code listing using a JCR query string
|
|
18
|
+
2. **Server-side view** — `useJCRQuery` inside a `.server.tsx` component
|
|
19
|
+
3. **Client-driven experience** — use a dedicated API strategy only when a server-side query is not enough
|
|
27
20
|
|
|
28
21
|
---
|
|
29
22
|
|
|
30
|
-
## Step
|
|
23
|
+
## Step 1 — Understand where content lives
|
|
31
24
|
|
|
32
|
-
|
|
25
|
+
Reusable content usually lives under `/sites/<siteKey>/contents/...` instead of directly under pages.
|
|
26
|
+
Create and manage those folders in jContent.
|
|
33
27
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
## Step 2b — Make content folders editable in jContent
|
|
37
|
-
|
|
38
|
-
Content folders are browsable via **jContent** by default, but if editors need to manage content directly from the **Content Tree** in Page Builder, add `jmix:visibleInContentTree` to the folder node type:
|
|
28
|
+
If editors need the folder visible in the Page Builder content tree, add `jmix:visibleInContentTree` to the folder type:
|
|
39
29
|
|
|
40
30
|
```cnd
|
|
41
31
|
[namespace:blogFolder] > jnt:contentFolder, jmix:visibleInContentTree
|
|
42
32
|
```
|
|
43
33
|
|
|
44
|
-
This makes the folder appear in the left sidebar of Page Builder, enabling drag-and-drop management.
|
|
45
|
-
|
|
46
34
|
---
|
|
47
35
|
|
|
48
|
-
## Step
|
|
36
|
+
## Step 2 — Start with the right SQL2 shape
|
|
49
37
|
|
|
50
|
-
###
|
|
38
|
+
### List all items of a type under a folder
|
|
51
39
|
|
|
52
40
|
```sql
|
|
53
41
|
SELECT *
|
|
@@ -55,137 +43,93 @@ FROM [namespace:typeName] AS item
|
|
|
55
43
|
WHERE ISDESCENDANTNODE(item, '/sites/<siteKey>/contents/<folderName>')
|
|
56
44
|
```
|
|
57
45
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
### Filter out drafts (items without a date)
|
|
46
|
+
### Only direct children of a folder
|
|
61
47
|
|
|
62
48
|
```sql
|
|
63
49
|
SELECT *
|
|
64
50
|
FROM [namespace:blogPost] AS post
|
|
65
|
-
WHERE
|
|
66
|
-
AND post.[publicationDate] IS NOT NULL
|
|
67
|
-
ORDER BY post.[publicationDate] DESC
|
|
51
|
+
WHERE ISCHILDNODE(post, '/sites/<siteKey>/contents/blog')
|
|
68
52
|
```
|
|
69
53
|
|
|
70
|
-
###
|
|
71
|
-
|
|
72
|
-
Use `ISDESCENDANTNODE` for nested folder structures:
|
|
54
|
+
### Filter drafts and sort newest first
|
|
73
55
|
|
|
74
56
|
```sql
|
|
75
|
-
|
|
76
|
-
|
|
57
|
+
SELECT *
|
|
58
|
+
FROM [namespace:blogPost] AS post
|
|
77
59
|
WHERE ISDESCENDANTNODE(post, '/sites/<siteKey>/contents/blog')
|
|
60
|
+
AND post.[publicationDate] IS NOT NULL
|
|
61
|
+
ORDER BY post.[publicationDate] DESC
|
|
78
62
|
```
|
|
79
63
|
|
|
80
|
-
Use `ISCHILDNODE` when you want only direct children of a folder:
|
|
81
|
-
|
|
82
|
-
```sql
|
|
83
|
-
-- Only direct children of /contents/blog
|
|
84
|
-
SELECT * FROM [namespace:blogPost] AS post
|
|
85
|
-
WHERE ISCHILDNODE(post, '/sites/<siteKey>/contents/blog')
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
### Common query clauses
|
|
89
|
-
|
|
90
|
-
| Clause | Usage |
|
|
91
|
-
|---|---|
|
|
92
|
-
| `ISDESCENDANTNODE(x, '/path')` | Filter by location in the tree |
|
|
93
|
-
| `x.[prop] IS NOT NULL` | Exclude items without a property (draft filter) |
|
|
94
|
-
| `x.[prop] = 'value'` | Filter by property value |
|
|
95
|
-
| `ORDER BY x.[prop] DESC` | Sort descending |
|
|
96
|
-
| `ORDER BY x.[prop] ASC` | Sort ascending |
|
|
97
|
-
|
|
98
64
|
---
|
|
99
65
|
|
|
100
|
-
## Step
|
|
66
|
+
## Step 3 — Use the right SQL2 clauses
|
|
101
67
|
|
|
102
|
-
|
|
68
|
+
| Need | Pattern |
|
|
69
|
+
|------|---------|
|
|
70
|
+
| Recursive subtree | `ISDESCENDANTNODE(alias, '/path')` |
|
|
71
|
+
| Direct children only | `ISCHILDNODE(alias, '/path')` |
|
|
72
|
+
| Property equality | `alias.[prop] = 'value'` |
|
|
73
|
+
| Pattern match | `alias.[prop] LIKE '%keyword%'` |
|
|
74
|
+
| Exclude empty values | `alias.[prop] IS NOT NULL` |
|
|
75
|
+
| Sort | `ORDER BY alias.[prop] DESC` |
|
|
76
|
+
| Full-text | `CONTAINS(alias.*, 'term')` |
|
|
77
|
+
| Relevance sort | `ORDER BY SCORE(alias) DESC` |
|
|
103
78
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
```cnd
|
|
107
|
-
[namespace:blogPost] > jnt:content, mix:title, jmix:mainResource, namespacemix:component
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
Then create a full-page view for it:
|
|
111
|
-
|
|
112
|
-
```tsx
|
|
113
|
-
// src/components/BlogPost/fullPage.server.tsx
|
|
114
|
-
// NOTE: componentType is "view" (NOT "template") — the MainResource template
|
|
115
|
-
// at src/templates/MainResource/default.server.tsx routes to this view automatically
|
|
116
|
-
import { jahiaComponent } from "@jahia/javascript-modules-library";
|
|
117
|
-
import type { Props } from "./types.js";
|
|
118
|
-
import classes from "./component.module.css";
|
|
119
|
-
|
|
120
|
-
jahiaComponent(
|
|
121
|
-
{
|
|
122
|
-
componentType: "view", // ← "view", NOT "template"
|
|
123
|
-
nodeType: "namespace:blogPost",
|
|
124
|
-
displayName: "Blog Post Full Page",
|
|
125
|
-
name: "fullPage", // ← this name is what MainResource routes to
|
|
126
|
-
},
|
|
127
|
-
({ "jcr:title": title, body, subtitle }: Props) => (
|
|
128
|
-
<article className={classes.article}>
|
|
129
|
-
<h1>{title}</h1>
|
|
130
|
-
<p>{subtitle}</p>
|
|
131
|
-
<div dangerouslySetInnerHTML={{ __html: body }} />
|
|
132
|
-
</article>
|
|
133
|
-
),
|
|
134
|
-
);
|
|
135
|
-
```
|
|
136
|
-
|
|
137
|
-
### Link to a full-page content item
|
|
138
|
-
|
|
139
|
-
Use `buildNodeUrl(currentNode)` to generate the URL to the item:
|
|
140
|
-
|
|
141
|
-
```tsx
|
|
142
|
-
<a href={buildNodeUrl(currentNode)}>{title}</a>
|
|
143
|
-
```
|
|
79
|
+
**Performance rule:** always constrain queries by path.
|
|
144
80
|
|
|
145
81
|
---
|
|
146
82
|
|
|
147
|
-
## Step
|
|
83
|
+
## Step 4 — Add full-text and filtering when needed
|
|
148
84
|
|
|
149
|
-
|
|
85
|
+
### Phrase search sorted by relevance
|
|
150
86
|
|
|
151
|
-
```
|
|
152
|
-
|
|
87
|
+
```sql
|
|
88
|
+
SELECT *
|
|
89
|
+
FROM [namespace:blogPost] AS post
|
|
90
|
+
WHERE ISDESCENDANTNODE(post, '/sites/<siteKey>/contents/blog')
|
|
91
|
+
AND CONTAINS(post.*, '"annual report"')
|
|
92
|
+
ORDER BY SCORE(post) DESC
|
|
153
93
|
```
|
|
154
94
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
In the query, filter published posts only:
|
|
95
|
+
### Search one property only
|
|
158
96
|
|
|
159
97
|
```sql
|
|
160
|
-
|
|
98
|
+
SELECT *
|
|
99
|
+
FROM [namespace:blogPost] AS post
|
|
100
|
+
WHERE ISDESCENDANTNODE(post, '/sites/<siteKey>/contents/blog')
|
|
101
|
+
AND CONTAINS(post.[jcr:title], 'welcome')
|
|
161
102
|
ORDER BY post.[publicationDate] DESC
|
|
162
103
|
```
|
|
163
104
|
|
|
164
|
-
|
|
105
|
+
### Filter by date
|
|
165
106
|
|
|
166
|
-
```
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
)}
|
|
173
|
-
</time>
|
|
174
|
-
)}
|
|
107
|
+
```sql
|
|
108
|
+
SELECT *
|
|
109
|
+
FROM [namespace:blogPost] AS post
|
|
110
|
+
WHERE ISDESCENDANTNODE(post, '/sites/<siteKey>/contents/blog')
|
|
111
|
+
AND post.[publicationDate] > CAST('2026-01-01T00:00:00.000Z' AS DATE)
|
|
112
|
+
ORDER BY post.[publicationDate] DESC
|
|
175
113
|
```
|
|
176
114
|
|
|
115
|
+
Use the millisecond form `yyyy-MM-dd'T'HH:mm:ss.SSSX` for SQL2 date casts.
|
|
116
|
+
|
|
177
117
|
---
|
|
178
118
|
|
|
179
|
-
## Step
|
|
119
|
+
## Step 5 — Use queries in Jahia UI or code
|
|
120
|
+
|
|
121
|
+
### Page Builder query component
|
|
180
122
|
|
|
181
|
-
For
|
|
123
|
+
For a simple listing, use **Jahia - Queries > Content items using JCR Query** and paste the SQL2 query there.
|
|
124
|
+
|
|
125
|
+
### `useJCRQuery` in a `.server.tsx` view
|
|
182
126
|
|
|
183
127
|
```tsx
|
|
184
|
-
import { jahiaComponent, useJCRQuery, Render } from
|
|
185
|
-
import type { JCRNodeWrapper } from
|
|
128
|
+
import { jahiaComponent, useJCRQuery, Render } from '@jahia/javascript-modules-library';
|
|
129
|
+
import type { JCRNodeWrapper } from 'org.jahia.services.content';
|
|
186
130
|
|
|
187
131
|
jahiaComponent(
|
|
188
|
-
{ componentType:
|
|
132
|
+
{ componentType: 'view', nodeType: 'namespace:blogListing' },
|
|
189
133
|
(_, { renderContext }) => {
|
|
190
134
|
const siteKey = renderContext.getSite().getName();
|
|
191
135
|
const posts = useJCRQuery({
|
|
@@ -206,202 +150,55 @@ jahiaComponent(
|
|
|
206
150
|
);
|
|
207
151
|
```
|
|
208
152
|
|
|
209
|
-
> `useJCRQuery` is server-side only (`.server.tsx`). For client-side dynamic queries triggered by user interaction, use the GraphQL approach in a `.client.tsx` island.
|
|
210
|
-
|
|
211
153
|
---
|
|
212
154
|
|
|
213
|
-
## Step
|
|
155
|
+
## Step 6 — Patterns commonly needed in template sets
|
|
214
156
|
|
|
215
|
-
|
|
157
|
+
### Make a content type renderable at its own URL
|
|
216
158
|
|
|
217
|
-
|
|
218
|
-
import { getSiteLocales, buildNodeUrl, jahiaComponent } from "@jahia/javascript-modules-library";
|
|
159
|
+
Use `jmix:mainResource` only for content that needs both a listing card and a full detail page.
|
|
219
160
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
(_, { currentNode }) => {
|
|
223
|
-
const locales = getSiteLocales(); // Record<string, java.util.Locale>
|
|
224
|
-
|
|
225
|
-
// Read j:invalidLanguages (languages disabled on this node)
|
|
226
|
-
const invalidCodes = currentNode.hasProperty("j:invalidLanguages")
|
|
227
|
-
? currentNode.getProperty("j:invalidLanguages").getValues().map((v: any) => v.getString())
|
|
228
|
-
: [];
|
|
229
|
-
const invalidSet = new Set(invalidCodes);
|
|
230
|
-
|
|
231
|
-
const links = Object.entries(locales)
|
|
232
|
-
.filter(([code, locale]) =>
|
|
233
|
-
!invalidSet.has(code) && currentNode.hasI18N(locale),
|
|
234
|
-
)
|
|
235
|
-
.map(([code]) => ({
|
|
236
|
-
code,
|
|
237
|
-
url: buildNodeUrl(currentNode, { language: code }),
|
|
238
|
-
}));
|
|
239
|
-
|
|
240
|
-
return (
|
|
241
|
-
<nav aria-label="Language switcher">
|
|
242
|
-
{links.map(({ code, url }) => (
|
|
243
|
-
<a key={code} href={url} lang={code} hrefLang={code}>
|
|
244
|
-
{code.toUpperCase()}
|
|
245
|
-
</a>
|
|
246
|
-
))}
|
|
247
|
-
</nav>
|
|
248
|
-
);
|
|
249
|
-
},
|
|
250
|
-
);
|
|
251
|
-
```
|
|
252
|
-
|
|
253
|
-
> `getSiteLocales()` returns all locales configured for the site — not just the active language. Always filter by `j:invalidLanguages` and `hasI18N()` before displaying.
|
|
254
|
-
|
|
255
|
-
---
|
|
256
|
-
|
|
257
|
-
## Step 7b — Query via GraphQL with `useGQLQuery`
|
|
258
|
-
|
|
259
|
-
For complex queries that span multiple nodes or need field-level projection, `useGQLQuery` is more efficient than `useJCRQuery`. It runs synchronously on the server using the current user's session.
|
|
260
|
-
|
|
261
|
-
```tsx
|
|
262
|
-
import { useGQLQuery, jahiaComponent } from "@jahia/javascript-modules-library";
|
|
263
|
-
import { gql } from "graphql-tag";
|
|
264
|
-
|
|
265
|
-
const BLOG_QUERY = gql`
|
|
266
|
-
query LatestPosts($path: String!) {
|
|
267
|
-
jcr {
|
|
268
|
-
nodeByPath(path: $path) {
|
|
269
|
-
descendants(typesFilter: { types: ["namespace:blogPost"] }, fieldFilter: {
|
|
270
|
-
filters: [{ fieldName: "publicationDate", evaluation: NOT_EMPTY }]
|
|
271
|
-
}) {
|
|
272
|
-
nodes {
|
|
273
|
-
name
|
|
274
|
-
path
|
|
275
|
-
displayName
|
|
276
|
-
property(name: "publicationDate") { value }
|
|
277
|
-
property(name: "jcr:title") { value }
|
|
278
|
-
}
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
`;
|
|
284
|
-
|
|
285
|
-
jahiaComponent(
|
|
286
|
-
{ componentType: "view", nodeType: "namespace:blogListing" },
|
|
287
|
-
(_, { renderContext }) => {
|
|
288
|
-
const siteKey = renderContext.getSite().getName();
|
|
289
|
-
const data = useGQLQuery(BLOG_QUERY, { path: `/sites/${siteKey}/contents/blog` });
|
|
290
|
-
const posts = data?.jcr?.nodeByPath?.descendants?.nodes ?? [];
|
|
291
|
-
|
|
292
|
-
return (
|
|
293
|
-
<ul>
|
|
294
|
-
{posts.map((post: any) => (
|
|
295
|
-
<li key={post.path}>
|
|
296
|
-
<a href={post.path}>{post.property?.value ?? post.displayName}</a>
|
|
297
|
-
</li>
|
|
298
|
-
))}
|
|
299
|
-
</ul>
|
|
300
|
-
);
|
|
301
|
-
},
|
|
302
|
-
);
|
|
161
|
+
```cnd
|
|
162
|
+
[namespace:blogPost] > jnt:content, mix:title, jmix:mainResource, namespacemix:component
|
|
303
163
|
```
|
|
304
164
|
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
## Step 8 — Hierarchical content with nested folders
|
|
308
|
-
|
|
309
|
-
Content folders can be nested to create sections (e.g. `tutorials/front-end/`, `tutorials/editors/`). Use `ISDESCENDANTNODE` in queries to automatically include all levels — no query changes needed as you add sub-folders.
|
|
165
|
+
Then add a `fullPage.server.tsx` view and link to the node with `buildNodeUrl(currentNode)`.
|
|
310
166
|
|
|
311
|
-
|
|
167
|
+
### Draft gate with `publicationDate`
|
|
312
168
|
|
|
313
|
-
|
|
169
|
+
A common pattern is:
|
|
314
170
|
|
|
315
|
-
```
|
|
316
|
-
|
|
317
|
-
import type { JCRNodeWrapper } from "org.jahia.services.content";
|
|
318
|
-
|
|
319
|
-
const { renderContext } = useServerContext();
|
|
320
|
-
const folderNode = renderContext.getMainResource().getNode().getSession().getNode(
|
|
321
|
-
`/sites/${siteKey}/contents/tutorials`
|
|
322
|
-
) as JCRNodeWrapper;
|
|
171
|
+
```cnd
|
|
172
|
+
- publicationDate (date)
|
|
323
173
|
```
|
|
324
174
|
|
|
325
|
-
|
|
175
|
+
and the query:
|
|
326
176
|
|
|
327
|
-
```
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
const contentsPath = parts.slice(0, 4).join("/"); // /sites/siteKey/contents
|
|
331
|
-
let current = node;
|
|
332
|
-
while (current.getParent() && (current.getParent() as JCRNodeWrapper).getPath() !== contentsPath) {
|
|
333
|
-
current = current.getParent() as JCRNodeWrapper;
|
|
334
|
-
}
|
|
335
|
-
return current;
|
|
336
|
-
}
|
|
177
|
+
```sql
|
|
178
|
+
AND post.[publicationDate] IS NOT NULL
|
|
179
|
+
ORDER BY post.[publicationDate] DESC
|
|
337
180
|
```
|
|
338
181
|
|
|
339
|
-
|
|
182
|
+
### Nested content folders
|
|
340
183
|
|
|
341
|
-
|
|
184
|
+
Use `ISDESCENDANTNODE` to cover nested folder trees automatically. Switch to `ISCHILDNODE` only when you intentionally want one level.
|
|
342
185
|
|
|
343
|
-
|
|
186
|
+
---
|
|
344
187
|
|
|
345
|
-
|
|
346
|
-
import type { ReactElement } from "react";
|
|
347
|
-
import { buildNodeUrl } from "@jahia/javascript-modules-library";
|
|
348
|
-
import type { JCRNodeWrapper } from "org.jahia.services.content";
|
|
349
|
-
|
|
350
|
-
function renderTree(
|
|
351
|
-
folder: JCRNodeWrapper,
|
|
352
|
-
contentNodeType: string,
|
|
353
|
-
depth: number = 0,
|
|
354
|
-
): ReactElement | null {
|
|
355
|
-
const items: Array<{ type: "folder" | "item"; node: JCRNodeWrapper }> = [];
|
|
356
|
-
const iter = folder.getNodes();
|
|
357
|
-
while (iter.hasNext()) {
|
|
358
|
-
const node = iter.nextNode() as JCRNodeWrapper;
|
|
359
|
-
if (node.isNodeType("jnt:contentFolder")) items.push({ type: "folder", node });
|
|
360
|
-
else if (node.isNodeType(contentNodeType)) items.push({ type: "item", node });
|
|
361
|
-
}
|
|
362
|
-
if (items.length === 0) return null;
|
|
363
|
-
|
|
364
|
-
return (
|
|
365
|
-
<ul>
|
|
366
|
-
{items.map(({ type, node }) => {
|
|
367
|
-
const key = node.getPath();
|
|
368
|
-
if (type === "folder") {
|
|
369
|
-
return (
|
|
370
|
-
<li key={key}>
|
|
371
|
-
<strong>{node.getPropertyAsString("jcr:title") || node.getName()}</strong>
|
|
372
|
-
{renderTree(node, contentNodeType, depth + 1)}
|
|
373
|
-
</li>
|
|
374
|
-
);
|
|
375
|
-
}
|
|
376
|
-
return (
|
|
377
|
-
<li key={key}>
|
|
378
|
-
<a href={buildNodeUrl(node)}>
|
|
379
|
-
{node.getPropertyAsString("jcr:title") || node.getName()}
|
|
380
|
-
</a>
|
|
381
|
-
</li>
|
|
382
|
-
);
|
|
383
|
-
})}
|
|
384
|
-
</ul>
|
|
385
|
-
);
|
|
386
|
-
}
|
|
387
|
-
```
|
|
188
|
+
## Query checklist
|
|
388
189
|
|
|
389
|
-
|
|
190
|
+
- [ ] Query is constrained to `/sites/<siteKey>/contents/...` or another specific subtree
|
|
191
|
+
- [ ] Node type is specific, not overly broad
|
|
192
|
+
- [ ] Sort order matches the UX need
|
|
193
|
+
- [ ] Draft or publish filtering is explicit
|
|
194
|
+
- [ ] Detail-page types use `jmix:mainResource` only when needed
|
|
195
|
+
- [ ] The query has been validated against `/jahia-jcr-sql2` guardrails
|
|
390
196
|
|
|
391
197
|
---
|
|
392
198
|
|
|
393
|
-
|
|
394
|
-
- **Installed definitions browser**: http://localhost:8080/modules/tools/definitionsBrowser.jsp
|
|
395
|
-
|
|
396
|
-
---
|
|
199
|
+
## Related skills
|
|
397
200
|
|
|
398
|
-
|
|
399
|
-
-
|
|
400
|
-
-
|
|
401
|
-
- [ ] Query returns expected results in the built-in query component
|
|
402
|
-
- [ ] `jmix:mainResource` added if items need a full-page view
|
|
403
|
-
- [ ] Draft/publish filtering works correctly
|
|
404
|
-
- [ ] `buildNodeUrl(currentNode)` used for item links
|
|
201
|
+
- `/jahia-jcr-sql2` — SQL2 syntax, full-text, joins, pagination, and performance
|
|
202
|
+
- `/jahia-dev-build-component` — build the listing component that renders query results
|
|
203
|
+
- `/jahia-dev-define-content-type` — create the queried content type and folder types
|
|
405
204
|
|
|
406
|
-
## Troubleshooting
|
|
407
|
-
> https://academy.jahia.com/tutorials-get-started/front-end-developer/making-a-blog
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: jahia-dev-review-cnd
|
|
3
|
+
description: Use after writing any CND file to validate it against Jahia best practices. Runs the deterministic cnd-checker script and reports PASS / FAIL with file:line citations and fixes. Run /jahia-dev-review-cnd <path> to check a specific file or directory, or without arguments to check all CND files in the current module.
|
|
4
|
+
allowed-tools: Bash
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Step 1 — Run the checker
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
CND_SCRIPT=$(find .claude .agents -name "check-cnd.mjs" 2>/dev/null | head -1)
|
|
11
|
+
node "$CND_SCRIPT" <path-to-file-or-directory>
|
|
12
|
+
# or, to check all CND files in the module:
|
|
13
|
+
node "$CND_SCRIPT" src/
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
The script exits with code 0 for PASS and code 1 for FAIL.
|
|
17
|
+
|
|
18
|
+
## Step 2 — Fix and repeat until clean
|
|
19
|
+
|
|
20
|
+
This is a loop. Run the checker, fix every issue reported, run it again. Repeat until the result is `PASS`.
|
|
21
|
+
|
|
22
|
+
- **FAIL** — fix every issue, re-run. Do not proceed until exit code is 0.
|
|
23
|
+
- **PASS** — clean. Continue.
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## Antipattern reference
|
|
28
|
+
|
|
29
|
+
The checker enforces these patterns. Use this as a guide when interpreting output or fixing issues manually.
|
|
30
|
+
|
|
31
|
+
### `rawStringLink`
|
|
32
|
+
Property whose name contains `link`, `url`, `href`, or `path` declared as `(string)`.
|
|
33
|
+
**Fix**: Use the link picker:
|
|
34
|
+
```cnd
|
|
35
|
+
- j:linkType (string, choicelist[linkTypeInitializer]) mandatory
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### `singleHardcodedCta`
|
|
39
|
+
A type with both a CTA label (`ctaText`, `ctaLabel`, `buttonText`, `buttonLabel`) and a CTA link (`ctaLink`, `ctaUrl`, `ctaHref`, `buttonLink`) as flat properties, with no child node.
|
|
40
|
+
**Fix**: Replace with a child node:
|
|
41
|
+
```cnd
|
|
42
|
+
+ * (ns:cta)
|
|
43
|
+
|
|
44
|
+
[ns:cta] > jnt:content, nsmix:component
|
|
45
|
+
- label (string) i18n mandatory
|
|
46
|
+
- j:linkType (string, choicelist[linkTypeInitializer]) mandatory
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### `directDroppable`
|
|
50
|
+
A concrete type extending `jmix:droppableContent` directly.
|
|
51
|
+
**Fix**: Extend the module mixin: `[ns:hero] > jnt:content, nsmix:component`
|
|
52
|
+
|
|
53
|
+
### `missingRatingConstraint`
|
|
54
|
+
`rating (long)` without a range constraint — unconstrained ratings cause data integrity issues.
|
|
55
|
+
**Fix**: Add `< "[1,5]"`
|
|
56
|
+
|
|
57
|
+
### `redundantImageAlt`
|
|
58
|
+
`imageAlt (string)` alongside an image weakreference. The image node already has `jcr:title`.
|
|
59
|
+
**Fix**: Remove `imageAlt`. In the view: `image.getPropertyAsString("jcr:title") ?? ""`
|
|
60
|
+
|
|
61
|
+
### `rawTitleProp`
|
|
62
|
+
Property named `title`, `heroTitle`, `pageTitle`, or `sectionTitle` typed as `(string)`.
|
|
63
|
+
**Fix**: Remove it, extend `mix:title`. Access as `props["jcr:title"]`.
|
|
64
|
+
|
|
65
|
+
### `weakrefNoConstraint`
|
|
66
|
+
`(weakreference)` with no `< ` type constraint.
|
|
67
|
+
**Fix**: Add constraint — `< jmix:image` for images, `< jnt:file` for files.
|
|
68
|
+
|
|
69
|
+
### `weakrefWrongConstraint`
|
|
70
|
+
`< 'jnt:file'` (quoted form).
|
|
71
|
+
**Fix**: `< jmix:image` (unquoted).
|
|
72
|
+
|
|
73
|
+
### `missingI18n`
|
|
74
|
+
User-visible string (`title`, `text`, `label`, `description`, `subtitle`, `caption`, `alt`, `heading`, `summary`, `excerpt`, `body`) without `i18n`.
|
|
75
|
+
**Fix**: Add `i18n` after the type declaration.
|
|
76
|
+
|
|
77
|
+
### `studioOnly`
|
|
78
|
+
Any use of `jmix:studioOnly`.
|
|
79
|
+
**Fix**: Replace with `jmix:hiddenType`.
|