@jahia/agentic 0.3.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 +4 -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 +5 -1
- 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-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-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-orchestrate/SKILL.md +148 -0
- package/dist/claude/.claude/skills/jahia-orchestrate/scripts/verify-pages.mjs +59 -0
- package/dist/claude/CLAUDE.md +16 -7
- package/dist/codex/.agents/skills/jahia/SKILL.md +5 -1
- 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-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-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-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 -8
- package/dist/copilot/.agents/skills/jahia/SKILL.md +5 -1
- 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-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-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-orchestrate/SKILL.md +148 -0
- package/dist/copilot/.agents/skills/jahia-orchestrate/scripts/verify-pages.mjs +59 -0
- package/dist/copilot/AGENTS.md +17 -8
- package/dist/cursor/.agents/skills/jahia/SKILL.md +5 -1
- 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-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-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-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 +5 -1
- 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-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-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-orchestrate/SKILL.md +148 -0
- package/dist/gemini/.agents/skills/jahia-orchestrate/scripts/verify-pages.mjs +59 -0
- package/dist/gemini/AGENTS.md +17 -8
- package/dist/gemini/GEMINI.md +2 -2
- package/dist/index.js +13 -0
- package/dist/opencode/.agents/skills/jahia/SKILL.md +5 -1
- 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-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-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-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 -8
- package/dist/windsurf/.windsurf/rules/jahia.md +15 -6
- package/dist/windsurf/.windsurf/skills/jahia/SKILL.md +5 -1
- 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-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-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-orchestrate/SKILL.md +148 -0
- package/dist/windsurf/.windsurf/skills/jahia-orchestrate/scripts/verify-pages.mjs +59 -0
- package/dist/windsurf/AGENTS.md +17 -8
- package/package.json +1 -1
|
@@ -1,536 +1,93 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: jahia-dev-define-content-type
|
|
3
3
|
description: Creates a Jahia CND content type definition from a natural language description. Use when asked to model content, create a new content type, or define node types.
|
|
4
|
-
allowed-tools: Bash, Read
|
|
4
|
+
allowed-tools: Bash, Read
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
## Overview
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
Orchestrates CND authoring by delegating to the `@jahia-cnd-author` sub-agent, which handles all CND syntax in an isolated context window. Your job here is to capture the spec and assemble the delegation call.
|
|
10
10
|
|
|
11
11
|
---
|
|
12
12
|
|
|
13
|
-
## Step 0 —
|
|
13
|
+
## Step 0 — Capture the spec
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
Confirm with the user (or infer from context):
|
|
16
16
|
|
|
17
17
|
| Field | Answer |
|
|
18
18
|
|---|---|
|
|
19
|
-
| **
|
|
19
|
+
| **Component name** | e.g. `HeroSection` |
|
|
20
20
|
| **Description** | What is this type for? |
|
|
21
21
|
| **Fields** | name / type / i18n? / mandatory? |
|
|
22
|
-
| **
|
|
23
|
-
| **
|
|
22
|
+
| **Repeatable children?** | CTA buttons, feature items, testimonials? |
|
|
23
|
+
| **Views** | default only, or also: card / fullPage |
|
|
24
|
+
| **Used where** | In a page area? Child of another component? |
|
|
24
25
|
|
|
25
|
-
|
|
26
|
+
For modeling decisions (semantic vs generic, children vs weakreference, mixin extraction), LOAD references/modeling-decisions.md.
|
|
26
27
|
|
|
27
28
|
---
|
|
28
29
|
|
|
29
|
-
## Step
|
|
30
|
+
## Step 1 — Resolve module context
|
|
30
31
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|---|---|
|
|
35
|
-
| Business entities: articles, team members, events | Visual composition: banners, feature rows |
|
|
36
|
-
| Items that appear in listings | One-off sections, layout containers |
|
|
37
|
-
| Anything reused across pages | Unique per-page UI blocks |
|
|
38
|
-
|
|
39
|
-
### Children vs weakreference
|
|
40
|
-
|
|
41
|
-
| Use **child nodes** when… | Use **weakreference** when… |
|
|
42
|
-
|---|---|
|
|
43
|
-
| Parent is the visual container (e.g. CTA buttons inside a hero) | Linking to content managed elsewhere |
|
|
44
|
-
| Children have no life outside the parent | Many-to-many relationships |
|
|
45
|
-
| You always create the children together | Content editors need to reuse the referenced item |
|
|
46
|
-
|
|
47
|
-
### Mixins are the primary reuse mechanism
|
|
48
|
-
|
|
49
|
-
**Mixins are how you share fields across multiple content types.** Whenever a set of properties appears on more than one type — a CTA block, a link, a badge, a price field — extract them into a mixin. This avoids duplication and keeps CND definitions focused.
|
|
50
|
-
|
|
51
|
-
The module-level `settings/definitions.cnd` defines all mixins and base types. Component-level `definition.cnd` files define the content types that extend them.
|
|
52
|
-
|
|
53
|
-
**Example: reusable CTA mixin**
|
|
54
|
-
|
|
55
|
-
```cnd
|
|
56
|
-
// settings/definitions.cnd
|
|
57
|
-
[nsmix:cta] mixin
|
|
58
|
-
- ctaLabel (string) i18n
|
|
59
|
-
- ctaType (string, choicelist[linkTypeInitializer]) = 'none' autocreated mandatory
|
|
60
|
-
// j:linknode and j:url are injected automatically — do NOT declare them
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
Any content type that needs a call-to-action simply extends `nsmix:cta`:
|
|
64
|
-
|
|
65
|
-
```cnd
|
|
66
|
-
// src/components/Hero/definition.cnd
|
|
67
|
-
[ns:hero] > jnt:content, nsmix:component, nsmix:cta
|
|
68
|
-
- title (string) i18n mandatory primary
|
|
69
|
-
- subtitle (string, textarea) i18n
|
|
70
|
-
- backgroundImage (weakreference, picker[type='image']) < jmix:image
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
The `ctaLabel`, `ctaType`, `j:linknode`, `j:url` fields are inherited and ready to use in the view without duplicating a single line of CND. Build your mixin library from day one — once two types need the same field, it belongs in a mixin.
|
|
74
|
-
|
|
75
|
-
**Common reusable mixin patterns:**
|
|
76
|
-
|
|
77
|
-
| Mixin | Properties it adds | When to use |
|
|
78
|
-
|---|---|---|
|
|
79
|
-
| `nsmix:cta` | `ctaLabel`, `ctaType` (+ injected `j:linknode`/`j:url`) | Any type with a button or link |
|
|
80
|
-
| `nsmix:badge` | `badgeText`, `badgeColor` | Cards, teasers, any labelled content |
|
|
81
|
-
| `nsmix:seo` | `metaTitle`, `metaDescription`, `seoKeywords` | Any `jmix:mainResource` type |
|
|
82
|
-
| `nsmix:media` | `image` (weakreference), `imageAltText`, `imageCaption` | Any type with a visual asset |
|
|
83
|
-
| `nsmix:trackable` | `analyticsId`, `trackingLabel` | Any CTA or interactive element |
|
|
84
|
-
|
|
85
|
-
**Generic container — accept any droppable child:**
|
|
32
|
+
```bash
|
|
33
|
+
# Get namespace prefix
|
|
34
|
+
grep -h "^<" settings/definitions.cnd | head -1
|
|
86
35
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
- columns (long) = '3' autocreated mandatory < '1', '2', '3', '4'
|
|
90
|
-
+ * (jmix:droppableContent) // ← accepts ANY droppable component as a child
|
|
36
|
+
# Check for two-tier mixin (pageComponent)
|
|
37
|
+
grep "pageComponent" settings/definitions.cnd
|
|
91
38
|
```
|
|
92
39
|
|
|
93
|
-
Use `+ * (jmix:droppableContent)` for layout containers that should not restrict which components editors can place inside them.
|
|
94
|
-
|
|
95
40
|
---
|
|
96
41
|
|
|
97
|
-
|
|
42
|
+
## Step 2 — REQUIRED: Delegate to `@jahia-cnd-author`
|
|
98
43
|
|
|
99
|
-
|
|
44
|
+
**Do not write CND directly.** Writing CND from memory always produces incorrect Jahia-specific patterns. The sub-agent reads reference files containing the exact syntax — you cannot reproduce this from training data.
|
|
100
45
|
|
|
101
|
-
|
|
102
|
-
// In settings/definitions.cnd
|
|
103
|
-
[namespacemix:component] > jmix:droppableContent, jmix:accessControllableContent mixin
|
|
104
|
-
```
|
|
105
|
-
|
|
106
|
-
Then all component types extend `namespacemix:component` — **never** `jmix:droppableContent` directly. This is what controls which types appear in the content picker.
|
|
107
|
-
|
|
108
|
-
> Add `jmix:accessControllableContent` to the base mixin — it enables per-component access control in jcontent, allowing editors to restrict who can see or edit individual components.
|
|
109
|
-
|
|
110
|
-
### Two-tier mixin system: `component` vs `pageComponent`
|
|
111
|
-
|
|
112
|
-
If the module uses a custom area type with `pageComponent` (see `jahia-dev-create-page-template`), there are two tiers:
|
|
46
|
+
Invoke the sub-agent with the complete structured spec:
|
|
113
47
|
|
|
114
|
-
```cnd
|
|
115
|
-
[namespacemix:component] > jmix:droppableContent mixin // general droppable
|
|
116
|
-
[namespacemix:pageComponent] > namespacemix:component mixin // for page areas only
|
|
117
48
|
```
|
|
49
|
+
@jahia-cnd-author
|
|
118
50
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
> ⚠️ A component that extends only `namespacemix:component` **cannot be dropped in page areas** that use a `namespacemix:pageComponent` area type. This is the most common cause of editors not being able to contribute content to a new page.
|
|
128
|
-
|
|
129
|
-
---
|
|
130
|
-
|
|
131
|
-
## Step 1 — Identify the component location
|
|
132
|
-
|
|
133
|
-
CND files can live in two places:
|
|
134
|
-
|
|
135
|
-
- **Component-level** (preferred): `src/components/<Category>/<Name>/definition.cnd`
|
|
136
|
-
- **Module-level**: `settings/definitions.cnd` (for mixins and shared base types)
|
|
137
|
-
|
|
138
|
-
For a new standalone component, always create a component-level `definition.cnd`.
|
|
139
|
-
|
|
140
|
-
---
|
|
141
|
-
|
|
142
|
-
## Step 2 — Determine the namespace
|
|
143
|
-
|
|
144
|
-
Check `settings/definitions.cnd` for the module's namespace declaration. It looks like:
|
|
145
|
-
|
|
146
|
-
```
|
|
147
|
-
<ns = 'http://www.mymodule.com/...'>
|
|
51
|
+
Component: <PascalCase name>
|
|
52
|
+
Namespace prefix: <ns>
|
|
53
|
+
Module path: <absolute path to module root>
|
|
54
|
+
Fields:
|
|
55
|
+
- <fieldName>: <type description> [mandatory] [i18n] [multiple]
|
|
56
|
+
- ... (one line per field)
|
|
57
|
+
Children: <describe any repeatable sub-items, e.g. "CTA buttons with label + link">
|
|
58
|
+
Usage: <where this component appears, e.g. "dropped in page areas">
|
|
148
59
|
```
|
|
149
60
|
|
|
150
|
-
|
|
61
|
+
Wait for the agent to report back before proceeding.
|
|
151
62
|
|
|
152
63
|
---
|
|
153
64
|
|
|
154
|
-
## Step
|
|
65
|
+
## Step 2b — Validate the CND
|
|
155
66
|
|
|
156
|
-
|
|
67
|
+
After `@jahia-cnd-author` reports back, invoke `/jahia-dev-review-cnd` on the written file:
|
|
157
68
|
|
|
158
|
-
```cnd
|
|
159
|
-
[namespace:typeName] > jnt:content, namespacemix:component
|
|
160
|
-
- propertyName (type) [hints] [attributes] [< constraint]
|
|
161
|
-
+ childName (namespace:childType)
|
|
162
69
|
```
|
|
163
|
-
|
|
164
|
-
### Property types
|
|
165
|
-
|
|
166
|
-
| Type | Usage |
|
|
167
|
-
|---|---|
|
|
168
|
-
| `string` | Single-line text |
|
|
169
|
-
| `string, textarea` | Multi-line text |
|
|
170
|
-
| `string, richtext` | Rich text editor |
|
|
171
|
-
| `weakreference, picker[type='image']` | Image picker |
|
|
172
|
-
| `weakreference multiple` | List of references (e.g. links to multiple pages) |
|
|
173
|
-
| `string, choicelist[linkTypeInitializer]` | Link type discriminator (internal page / external URL / none) — **special initializer, not a value list** |
|
|
174
|
-
| `string, choicelist` with `< 'val1', 'val2'` constraints | Dropdown with fixed choices (see below) |
|
|
175
|
-
| `date` | Date picker |
|
|
176
|
-
| `boolean` | Checkbox |
|
|
177
|
-
| `double` | Decimal number (e.g. latitude/longitude) |
|
|
178
|
-
| `long` | Integer number |
|
|
179
|
-
| `string multiple` | List of strings |
|
|
180
|
-
|
|
181
|
-
### Fixed-choice dropdowns (constrained string)
|
|
182
|
-
|
|
183
|
-
Use `(string, choicelist)` combined with value constraints (`< 'val1', 'val2'`) to render a dropdown in the editor. **Do NOT use `choicelist[val1,val2]`** — that syntax is invalid:
|
|
184
|
-
|
|
185
|
-
```cnd
|
|
186
|
-
[namespace:article] > jnt:content
|
|
187
|
-
- difficulty (string, choicelist) i18n < 'beginner', 'intermediate', 'advanced'
|
|
188
|
-
- product (string, choicelist) i18n < 'jahia', 'jexperience', 'cloud'
|
|
189
|
-
```
|
|
190
|
-
|
|
191
|
-
### Choicelist initializer variants
|
|
192
|
-
|
|
193
|
-
`choicelist[...]` takes an **initializer keyword**, not a value list. Valid initializers:
|
|
194
|
-
|
|
195
|
-
| Initializer | What editor sees |
|
|
196
|
-
|---|---|
|
|
197
|
-
| `choicelist[linkTypeInitializer]` | Internal page / External URL / None link picker |
|
|
198
|
-
| `choicelist[nodes=/path/to/folder;type=jnt:content]` | Picker populated from JCR nodes under a path |
|
|
199
|
-
| `choicelist[componentTypes=jnt:page]` | Picker showing all registered views of a node type |
|
|
200
|
-
| `choicelist[country]` | Country selector (ISO codes with localized labels) |
|
|
201
|
-
| `choicelist[menus]` | Picker for existing menus defined on the site |
|
|
202
|
-
| `choicelist[resourceBundle]` | Labels come from `.properties` file keys matching `ns_type.field.value` |
|
|
203
|
-
|
|
204
|
-
```cnd
|
|
205
|
-
// Country picker — stores ISO code, shows localized country name in editor
|
|
206
|
-
- country (string, choicelist[country]) i18n
|
|
207
|
-
|
|
208
|
-
// Node picker — editor selects from nodes under a specific folder
|
|
209
|
-
- template (string, choicelist[nodes=/sites/mySite/templates;type=jnt:content])
|
|
210
|
-
|
|
211
|
-
// Component type picker — shows all views of jnt:page registered in the module
|
|
212
|
-
- pageLayout (string, choicelist[componentTypes=jnt:page])
|
|
213
|
-
|
|
214
|
-
// Resource bundle labels — values come from .properties keys
|
|
215
|
-
- status (string, choicelist[resourceBundle]) i18n < 'draft', 'review', 'published'
|
|
216
|
-
// In .properties: namespace_typeName.status.draft=Draft
|
|
217
|
-
// namespace_typeName.status.review=In Review
|
|
218
|
-
// namespace_typeName.status.published=Published
|
|
70
|
+
/jahia-dev-review-cnd <module-path>/src/components/<Category>/<Name>/definition.cnd
|
|
219
71
|
```
|
|
220
72
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
Use `< "[-90,90]"` to restrict a numeric property to a range:
|
|
224
|
-
|
|
225
|
-
```cnd
|
|
226
|
-
- latitude (double) mandatory < "[-90,90]"
|
|
227
|
-
- longitude (double) mandatory < "[-180,180]"
|
|
228
|
-
```
|
|
229
|
-
|
|
230
|
-
### `weakreference multiple` vs child nodes
|
|
231
|
-
|
|
232
|
-
| Use `weakreference multiple` when… | Use child nodes when… |
|
|
233
|
-
|---|---|
|
|
234
|
-
| Each item is just a reference (a page link, an image) | Each item has multiple properties (label + URL) |
|
|
235
|
-
| The list is simpler to author and implement | Items need a rich editing interface |
|
|
236
|
-
|
|
237
|
-
```cnd
|
|
238
|
-
// Simpler: list of page links (weakreference multiple)
|
|
239
|
-
[namespace:footer] > jnt:content, namespacemix:component
|
|
240
|
-
- links (weakreference) multiple < jnt:page
|
|
241
|
-
|
|
242
|
-
// More flexible: each CTA has label + link (child nodes)
|
|
243
|
-
[namespace:heroSection] > jnt:content, namespacemix:component
|
|
244
|
-
+ * (namespace:heroCallToAction)
|
|
245
|
-
```
|
|
246
|
-
|
|
247
|
-
Render a `weakreference multiple` list in the view:
|
|
248
|
-
|
|
249
|
-
```tsx
|
|
250
|
-
// links is JCRNodeWrapper[] | undefined
|
|
251
|
-
{links?.filter(link => link !== null).map(link => (
|
|
252
|
-
<a key={link.getPath()} href={buildNodeUrl(link)}>
|
|
253
|
-
{link.getDisplayableName()}
|
|
254
|
-
</a>
|
|
255
|
-
))}
|
|
256
|
-
```
|
|
257
|
-
|
|
258
|
-
### Common attributes
|
|
259
|
-
|
|
260
|
-
| Attribute | Meaning |
|
|
261
|
-
|---|---|
|
|
262
|
-
| `i18n` | Translatable per language |
|
|
263
|
-
| `mandatory` | Required field |
|
|
264
|
-
| `multiple` | Allows a list of values |
|
|
265
|
-
| `autocreated` | Auto-creates the property on node creation — always combine with a default: `= 'value'` |
|
|
266
|
-
| `primary` | Marks the most important field — Jahia's editor UI highlights it. One per type only. |
|
|
267
|
-
| `orderable` | Allows reordering child nodes |
|
|
268
|
-
|
|
269
|
-
```cnd
|
|
270
|
-
[ns:blogPost] > jnt:content, nsmix:component
|
|
271
|
-
- title (string) i18n mandatory primary // ← highlighted in the editor
|
|
272
|
-
- country (string, choicelist[country]) = 'US' autocreated mandatory // ← pre-populated on create
|
|
273
|
-
```
|
|
274
|
-
|
|
275
|
-
### `linkTypeInitializer` — the full link pattern
|
|
276
|
-
|
|
277
|
-
`choicelist[linkTypeInitializer]` creates a link picker where the editor selects *internal page*, *external URL*, or *none*. Declare **only the `j:linkType` field** in the CND — the companion fields `j:linknode` and `j:url` are **added automatically by Jahia's mixins** at runtime. Do NOT add them to your CND.
|
|
278
|
-
|
|
279
|
-
```cnd
|
|
280
|
-
[namespace:callToAction] > jnt:content, namespacemix:component
|
|
281
|
-
- label (string) i18n mandatory
|
|
282
|
-
- j:linkType (string, choicelist[linkTypeInitializer]) mandatory
|
|
283
|
-
// ✅ Stop here — j:linknode and j:url are injected by Jahia, not declared by you
|
|
284
|
-
```
|
|
285
|
-
|
|
286
|
-
In `types.ts`, use a **discriminated union** — the mixin fields ARE available at runtime as props:
|
|
287
|
-
|
|
288
|
-
```ts
|
|
289
|
-
import type { JCRNodeWrapper } from "org.jahia.services.content";
|
|
290
|
-
|
|
291
|
-
export type Props =
|
|
292
|
-
| { label?: string; "j:linkType": "none" }
|
|
293
|
-
| { label?: string; "j:linkType": "internal"; "j:linknode"?: JCRNodeWrapper }
|
|
294
|
-
| { label?: string; "j:linkType": "external"; "j:url"?: string; "j:linkTitle"?: string };
|
|
295
|
-
```
|
|
296
|
-
|
|
297
|
-
In the view, use a `switch` on `props["j:linkType"]` (see `jahia-dev-create-view` skill).
|
|
298
|
-
|
|
299
|
-
### i18n rule
|
|
300
|
-
|
|
301
|
-
**Default to `i18n` on every user-facing field** — titles, subtitles, body text, button labels, alt text, captions, people names. Even on monolingual sites, adding `i18n` from the start avoids costly CND migrations later.
|
|
302
|
-
|
|
303
|
-
> ⚠️ **Child nodes do not support `i18n`.** The content tree is shared across all languages. If you need locale-specific child content, use per-language **visibility conditions** in the Jahia editor (Advanced Editing → Visibility → Languages) instead.
|
|
304
|
-
|
|
305
|
-
> Under the hood: non-i18n fields are stored directly on the node; i18n fields are stored as properties of auto-created `jnt:translation_<language>` child nodes. You don't manage these directly, but knowing this helps when debugging missing translated values.
|
|
306
|
-
|
|
307
|
-
### Common mixins to extend
|
|
308
|
-
|
|
309
|
-
| Mixin | Adds |
|
|
310
|
-
|---|---|
|
|
311
|
-
| `jnt:content` | Base type for all user content (always include) |
|
|
312
|
-
| `namespacemix:component` | Makes this type available as a droppable component in Page Builder |
|
|
313
|
-
| `mix:title` | Adds a `jcr:title` field |
|
|
314
|
-
| `jmix:mainResource` | Makes the node accessible at its own URL — use only for content that needs **both a listing card AND a full detail page** (e.g. blog posts). Do not add to navigation-only or visual composition types. |
|
|
315
|
-
| `jmix:hiddenType` | Hides a type from the Page Builder component picker (use for structural/container nodes editors should not add manually). Prefer over `jmix:studioOnly` which can cause silent rendering issues. |
|
|
316
|
-
| `jmix:accessControllableContent` | Enables per-component access control in jcontent — add to the base module mixin |
|
|
317
|
-
| `jmix:image` | Constraint: only image nodes |
|
|
318
|
-
| `jmix:link` | Built-in link type |
|
|
319
|
-
|
|
320
|
-
### Constraints
|
|
321
|
-
|
|
322
|
-
- `< jmix:image` — restricts a weakreference to image nodes only
|
|
323
|
-
- `< namespace:typeName` — restricts child nodes to a specific type
|
|
324
|
-
|
|
325
|
-
**Regex constraints** — validate a `string` field against a pattern:
|
|
326
|
-
|
|
327
|
-
```cnd
|
|
328
|
-
// Email address (or empty — regex starts with ^$ to allow clearing the field)
|
|
329
|
-
- contactEmail (string) < '^$|[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}'
|
|
330
|
-
|
|
331
|
-
// URL-safe slug — lowercase letters, digits, hyphens only
|
|
332
|
-
- slug (string) < '^[a-z0-9-]+$'
|
|
333
|
-
|
|
334
|
-
// Must start with http:// or https://
|
|
335
|
-
- externalUrl (string) < '^https?://'
|
|
336
|
-
```
|
|
337
|
-
|
|
338
|
-
**Date-range constraints** — bound a `date` field to a window. Use `(` / `)` for exclusive bounds, `[` / `]` for inclusive. Leave either side empty for open-ended:
|
|
339
|
-
|
|
340
|
-
```cnd
|
|
341
|
-
// Any date after 2020-01-01 (exclusive lower bound, no upper bound)
|
|
342
|
-
- eventDate (date, datepicker) < '(2020-01-01T00:00:00.000,)'
|
|
343
|
-
|
|
344
|
-
// From 2020 onwards inclusive (events can't be backdated before the platform launched)
|
|
345
|
-
- startDate (date, datepicker) < '[2020-01-01T00:00:00.000,]'
|
|
346
|
-
|
|
347
|
-
// Bounded window — exclusive on both sides
|
|
348
|
-
- campaignDate (date, datepicker) < '(2020-01-01T00:00:00.000,2030-12-31T00:00:00.000)'
|
|
349
|
-
```
|
|
350
|
-
|
|
351
|
-
### Example — Hero Section with CTA (link pattern)
|
|
352
|
-
|
|
353
|
-
```cnd
|
|
354
|
-
[ns:heroSection] > jnt:content, nsmix:component
|
|
355
|
-
- title (string) i18n mandatory
|
|
356
|
-
- subtitle (string, textarea) i18n mandatory
|
|
357
|
-
- background (weakreference, picker[type='image']) mandatory < jmix:image
|
|
358
|
-
+ * (ns:heroCallToAction)
|
|
359
|
-
|
|
360
|
-
[ns:heroCallToAction] > jnt:content, nsmix:component
|
|
361
|
-
- title (string) i18n mandatory
|
|
362
|
-
- j:linkType (string, choicelist[linkTypeInitializer]) mandatory
|
|
363
|
-
// j:linknode and j:url are injected by Jahia — do not declare them
|
|
364
|
-
```
|
|
365
|
-
|
|
366
|
-
### Example — Blog Post
|
|
367
|
-
|
|
368
|
-
```cnd
|
|
369
|
-
[ns:blogPost] > jnt:content, mix:title, jmix:mainResource, nsmix:component
|
|
370
|
-
- subtitle (string) i18n mandatory
|
|
371
|
-
- authors (string) multiple
|
|
372
|
-
- cover (weakreference, picker[type='image']) mandatory < jmix:image
|
|
373
|
-
- body (string, richtext) i18n mandatory
|
|
374
|
-
- publicationDate (date)
|
|
375
|
-
```
|
|
376
|
-
|
|
377
|
-
---
|
|
378
|
-
|
|
379
|
-
## Step 4 — Create a `types.ts` file
|
|
380
|
-
|
|
381
|
-
For each new content type, create a `types.ts` alongside the `definition.cnd` to define the TypeScript props interface. This will be imported by views.
|
|
382
|
-
|
|
383
|
-
> ⚠️ **All props must use `?:` (optional)** — even mandatory CND fields. Jahia does not guarantee a value is present at render time (e.g. content created before a field was added, or incomplete saves). If a view uses a prop without guarding it, it will crash at runtime.
|
|
384
|
-
|
|
385
|
-
```ts
|
|
386
|
-
import type { JCRNodeWrapper } from "org.jahia.services.content";
|
|
387
|
-
|
|
388
|
-
export interface Props {
|
|
389
|
-
title?: string;
|
|
390
|
-
subtitle?: string;
|
|
391
|
-
background?: JCRNodeWrapper;
|
|
392
|
-
}
|
|
393
|
-
```
|
|
394
|
-
|
|
395
|
-
Map CND types to TypeScript:
|
|
396
|
-
|
|
397
|
-
| CND type | TypeScript type |
|
|
398
|
-
|---|---|
|
|
399
|
-
| `string` | `string` |
|
|
400
|
-
| `string` multiple | `string[]` |
|
|
401
|
-
| `weakreference` | `JCRNodeWrapper` |
|
|
402
|
-
| `weakreference` multiple | `JCRNodeWrapper[]` |
|
|
403
|
-
| `date` | `string` (ISO 8601) |
|
|
404
|
-
| `boolean` | `boolean` |
|
|
405
|
-
| `double` | `number` |
|
|
406
|
-
| `long` | `number` |
|
|
407
|
-
|
|
408
|
-
All fields use `?:` regardless of whether they are mandatory in the CND.
|
|
73
|
+
If the review reports errors, send them back to `@jahia-cnd-author` to fix. Do not proceed until the review is clean.
|
|
409
74
|
|
|
410
75
|
---
|
|
411
76
|
|
|
412
|
-
## Step
|
|
413
|
-
|
|
414
|
-
Editors see raw technical names without translations. Always add labels for every new content type.
|
|
415
|
-
|
|
416
|
-
### Translations
|
|
417
|
-
|
|
418
|
-
Open `settings/resources/<module-name>.properties` (English) and `<module-name>_fr.properties` (French) and add:
|
|
419
|
-
|
|
420
|
-
```properties
|
|
421
|
-
# Node type label (shown in the content picker and editor)
|
|
422
|
-
namespace_typeName=Human-readable name
|
|
423
|
-
|
|
424
|
-
# Field labels
|
|
425
|
-
namespace_typeName.fieldName=Field label
|
|
426
|
-
namespace_typeName.fieldName.ui.tooltip=Optional tooltip shown next to the field in the editor.
|
|
427
|
-
|
|
428
|
-
# choicelist[resourceBundle] option labels
|
|
429
|
-
namespace_typeName.fieldName.optionKey=Option label
|
|
430
|
-
```
|
|
431
|
-
|
|
432
|
-
All `ui.tooltip` values support basic HTML. Escape `<` and `>` as `<` and `>`.
|
|
433
|
-
|
|
434
|
-
> For `choicelist[resourceBundle]` fields, the constraint values (e.g. `< 'house', 'apartment'`) must match the property keys (e.g. `namespace_type.field.house=House`).
|
|
77
|
+
## Step 3 — Continue with deployment
|
|
435
78
|
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
```
|
|
441
|
-
settings/content-editor-forms/fieldsets/<cnd-namespace>_<typeName>.json
|
|
442
|
-
```
|
|
443
|
-
|
|
444
|
-
Example — override `ctaTarget` to render as a radio group and `ctaVariant` as a select:
|
|
445
|
-
|
|
446
|
-
```json
|
|
447
|
-
{
|
|
448
|
-
"nodeType": "ns:card",
|
|
449
|
-
"priority": 1,
|
|
450
|
-
"sections": [{
|
|
451
|
-
"name": "content",
|
|
452
|
-
"fieldSets": [{
|
|
453
|
-
"name": "ns:card",
|
|
454
|
-
"fields": [
|
|
455
|
-
{
|
|
456
|
-
"name": "ctaTarget",
|
|
457
|
-
"selectorType": "RadioChoiceList"
|
|
458
|
-
},
|
|
459
|
-
{
|
|
460
|
-
"name": "ctaVariant",
|
|
461
|
-
"selectorType": "Choicelist",
|
|
462
|
-
"selectorOptions": [{ "name": "context", "value": "true" }]
|
|
463
|
-
}
|
|
464
|
-
]
|
|
465
|
-
}]
|
|
466
|
-
}]
|
|
467
|
-
}
|
|
468
|
-
```
|
|
469
|
-
|
|
470
|
-
`selectorType` overrides the default editor widget for the field. Common overrides:
|
|
471
|
-
|
|
472
|
-
| `selectorType` | Use for |
|
|
473
|
-
|---|---|
|
|
474
|
-
| `RadioChoiceList` | Short fixed-value lists (2–4 options) |
|
|
475
|
-
| `Choicelist` | Longer dropdowns, dynamic lists |
|
|
476
|
-
| `RichText` | Force rich text editor on a `string, richtext` property |
|
|
477
|
-
| `DateTimePicker` | Date + time (vs date only) |
|
|
478
|
-
| `Tag` | Free-form tag input |
|
|
479
|
-
|
|
480
|
-
Fieldset files are optional — only create them when the default editor rendering is insufficient.
|
|
481
|
-
|
|
482
|
-
### Icon
|
|
483
|
-
|
|
484
|
-
Create a 32×32 PNG icon at:
|
|
485
|
-
|
|
486
|
-
```
|
|
487
|
-
settings/content-types-icons/<cnd-namespace>_<typeName>.png
|
|
488
|
-
```
|
|
489
|
-
|
|
490
|
-
The prefix is the **CND namespace** (e.g. `ns`, `nsmix`), **not** the module name. For example:
|
|
491
|
-
- `ns_heroSection.png` ✅
|
|
492
|
-
- `my-module_heroSection.png` ❌ (module name with hyphen — wrong)
|
|
493
|
-
|
|
494
|
-
You can source free icons from [flaticon.com](https://www.flaticon.com/) (download at 32px). If no icon is available, copy an existing one as a placeholder — editors will see a blank space otherwise.
|
|
495
|
-
|
|
496
|
-
---
|
|
497
|
-
|
|
498
|
-
## Step 6 — Deploy to Jahia
|
|
499
|
-
|
|
500
|
-
After creating or modifying a `definition.cnd`, build and deploy the module:
|
|
501
|
-
|
|
502
|
-
```bash
|
|
503
|
-
# Always use this — never use yarn dev from an agent (it's interactive-only)
|
|
504
|
-
yarn build && yarn jahia-deploy
|
|
505
|
-
```
|
|
506
|
-
|
|
507
|
-
If Jahia rejects the type definition (e.g. breaking change), use the **Installed definitions browser** to remove the old definition first:
|
|
508
|
-
> http://localhost:8080/modules/tools/definitionsBrowser.jsp
|
|
79
|
+
After the CND review is PASS, proceed with:
|
|
80
|
+
- Add UI translations (`/jahia-dev-build-component` handles this if invoked from there)
|
|
81
|
+
- `yarn build && yarn jahia-deploy`
|
|
82
|
+
- Verify the type appears in Jahia's content editor
|
|
509
83
|
|
|
510
84
|
---
|
|
511
85
|
|
|
512
86
|
## Validation checklist
|
|
513
|
-
- [ ] Spec confirmed before writing CND (name, fields, views, usage)
|
|
514
|
-
- [ ] Namespace matches the module (check `settings/definitions.cnd`)
|
|
515
|
-
- [ ] Extends `jnt:content` and appropriate mixins
|
|
516
|
-
- [ ] Uses `namespacemix:component` or `namespacemix:pageComponent` — **never** `jmix:droppableContent` directly
|
|
517
|
-
- [ ] All required properties have the `mandatory` attribute
|
|
518
|
-
- [ ] All user-facing string/text fields have `i18n` (default to always)
|
|
519
|
-
- [ ] Structural/container types have `jmix:hiddenType` (not shown in picker) — do NOT use `jmix:studioOnly`
|
|
520
|
-
- [ ] `jmix:mainResource` only used for listing + detail content (not visual composition)
|
|
521
|
-
- [ ] `types.ts` created with correct TypeScript types
|
|
522
|
-
- [ ] Views handle null/missing values gracefully (mandatory does not guarantee a value)
|
|
523
|
-
- [ ] Translation keys added to `.properties` files (EN + FR minimum)
|
|
524
|
-
- [ ] Icon created at `settings/content-types-icons/<namespace>_<typeName>.png`
|
|
525
|
-
- [ ] `yarn build && yarn jahia-deploy` run and type appears in Jahia content editor with correct label and icon
|
|
526
|
-
|
|
527
|
-
## Troubleshooting
|
|
528
|
-
> https://academy.jahia.com/tutorials-get-started/front-end-developer/making-a-hero-section
|
|
529
|
-
|
|
530
|
-
## References
|
|
531
|
-
|
|
532
|
-
- Native Jahia mixins & node types: https://github.com/Jahia/jahia/tree/master/war/src/main/webapp/WEB-INF/etc/repository/nodetypes
|
|
533
|
-
- Developer training: https://github.com/Jahia/developer-training/blob/main/js-training/slides.md
|
|
534
|
-
- JavaScript modules monorepo: https://github.com/Jahia/javascript-modules
|
|
535
87
|
|
|
536
|
-
|
|
88
|
+
- [ ] Spec confirmed before delegation
|
|
89
|
+
- [ ] `@jahia-cnd-author` reported PASS (no errors)
|
|
90
|
+
- [ ] Translation keys added to `.properties` files
|
|
91
|
+
- [ ] Icon created at `settings/content-types-icons/<ns>_<typeName>.png`
|
|
92
|
+
- [ ] `yarn build && yarn jahia-deploy` succeeded
|
|
93
|
+
- [ ] Type appears in Jahia content editor with correct label and icon
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# CND Modeling Decisions
|
|
2
|
+
|
|
3
|
+
## Semantic vs generic types
|
|
4
|
+
|
|
5
|
+
| Use **semantic types** for… | Use **generic types** for… |
|
|
6
|
+
|---|---|
|
|
7
|
+
| Business entities: articles, team members, events | Visual composition: banners, feature rows |
|
|
8
|
+
| Items that appear in listings | One-off sections, layout containers |
|
|
9
|
+
| Anything reused across pages | Unique per-page UI blocks |
|
|
10
|
+
|
|
11
|
+
## Children vs weakreference
|
|
12
|
+
|
|
13
|
+
| Use **child nodes** when… | Use **weakreference** when… |
|
|
14
|
+
|---|---|
|
|
15
|
+
| Parent is the visual container (e.g. CTA buttons inside a hero) | Linking to content managed elsewhere |
|
|
16
|
+
| Children have no life outside the parent | Many-to-many relationships |
|
|
17
|
+
| You always create the children together | Content editors need to reuse the referenced item |
|
|
18
|
+
| Each item has multiple properties (label + link) | Each item is just a reference (a page, an image) |
|
|
19
|
+
|
|
20
|
+
## Mixins are the primary reuse mechanism
|
|
21
|
+
|
|
22
|
+
Whenever a set of properties appears on more than one type, extract them into a mixin in `settings/definitions.cnd`.
|
|
23
|
+
|
|
24
|
+
Common reusable mixin patterns:
|
|
25
|
+
|
|
26
|
+
| Mixin | Properties it adds | When to use |
|
|
27
|
+
|---|---|---|
|
|
28
|
+
| `nsmix:cta` | `ctaLabel`, `j:linkType` | Any type with a button or link |
|
|
29
|
+
| `nsmix:badge` | `badgeText`, `badgeColor` | Cards, teasers, labelled content |
|
|
30
|
+
| `nsmix:seo` | `metaTitle`, `metaDescription` | Any `jmix:mainResource` type |
|
|
31
|
+
| `nsmix:media` | `image` (weakreference) | Any type with a visual asset — alt text comes from the image node's `jcr:title`, never add a separate imageAlt property |
|
|
32
|
+
|
|
33
|
+
Example reusable CTA mixin:
|
|
34
|
+
|
|
35
|
+
```cnd
|
|
36
|
+
[nsmix:cta] mixin
|
|
37
|
+
- ctaLabel (string) i18n
|
|
38
|
+
- j:linkType (string, choicelist[linkTypeInitializer]) = 'none' autocreated mandatory
|
|
39
|
+
// j:linknode and j:url are injected automatically
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Any component that needs a CTA extends `nsmix:cta` — no property duplication.
|
|
43
|
+
|
|
44
|
+
## `jmix:mainResource` — when NOT to use it
|
|
45
|
+
|
|
46
|
+
Only for content that needs **both** a listing card AND a full detail page (e.g. blog posts, events).
|
|
47
|
+
Do NOT add to: navigation-only types, visual composition components, containers.
|
|
48
|
+
|
|
49
|
+
## Component location
|
|
50
|
+
|
|
51
|
+
- **Component-level** (preferred): `src/components/<Category>/<Name>/definition.cnd`
|
|
52
|
+
- **Module-level**: `settings/definitions.cnd` (for mixins and shared base types only)
|