@paroicms/site-generator-plugin 0.31.6 → 0.32.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.
|
@@ -167,7 +167,10 @@ function fixSiteSchema(siteSchema) {
|
|
|
167
167
|
continue;
|
|
168
168
|
// Add Tiptap plugin to fields with renderAs "html"
|
|
169
169
|
for (const field of nodeType.fields) {
|
|
170
|
-
if (typeof field !== "string" &&
|
|
170
|
+
if (typeof field !== "string" &&
|
|
171
|
+
field.renderAs === "html" &&
|
|
172
|
+
field.storedAs !== "labeling" &&
|
|
173
|
+
field.storedAs !== "partField") {
|
|
171
174
|
field.dataType = "json";
|
|
172
175
|
field.plugin = "@paroicms/tiptap-editor-plugin";
|
|
173
176
|
}
|
|
@@ -181,9 +184,29 @@ function fixSiteSchema(siteSchema) {
|
|
|
181
184
|
];
|
|
182
185
|
}
|
|
183
186
|
}
|
|
187
|
+
validatePartFieldReferences(nodeTypes);
|
|
184
188
|
setMenuPlacementOnTaxonomies(nodeTypes);
|
|
185
189
|
return siteSchema;
|
|
186
190
|
}
|
|
191
|
+
function validatePartFieldReferences(nodeTypes) {
|
|
192
|
+
if (!nodeTypes)
|
|
193
|
+
return;
|
|
194
|
+
const partTypeNames = new Set(nodeTypes.filter((nt) => nt.kind === "part").map((nt) => nt.typeName));
|
|
195
|
+
for (const nodeType of nodeTypes) {
|
|
196
|
+
if (!nodeType.fields)
|
|
197
|
+
continue;
|
|
198
|
+
nodeType.fields = nodeType.fields.filter((field) => {
|
|
199
|
+
if (typeof field === "string")
|
|
200
|
+
return true;
|
|
201
|
+
if (field.storedAs !== "partField")
|
|
202
|
+
return true;
|
|
203
|
+
if (typeof field.partType !== "string" || !partTypeNames.has(field.partType)) {
|
|
204
|
+
return false;
|
|
205
|
+
}
|
|
206
|
+
return true;
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
}
|
|
187
210
|
function setMenuPlacementOnTaxonomies(nodeTypes) {
|
|
188
211
|
if (!nodeTypes)
|
|
189
212
|
return;
|
|
@@ -163,6 +163,9 @@ function templateOfFields(ctx, fields, { parentKey }) {
|
|
|
163
163
|
return fieldTemplates.join("\n");
|
|
164
164
|
}
|
|
165
165
|
function templateOfField(ctx, fieldOrQualifiedName, parentKey) {
|
|
166
|
+
if (typeof fieldOrQualifiedName !== "string" && fieldOrQualifiedName.storedAs === "partField") {
|
|
167
|
+
return templateOfPartField(ctx, fieldOrQualifiedName, parentKey);
|
|
168
|
+
}
|
|
166
169
|
const { dataType, renderAs, name } = typeof fieldOrQualifiedName === "string"
|
|
167
170
|
? getPredefinedDataType(ctx, fieldOrQualifiedName)
|
|
168
171
|
: fieldOrQualifiedName.storedAs === "labeling"
|
|
@@ -229,6 +232,21 @@ function templateOfField(ctx, fieldOrQualifiedName, parentKey) {
|
|
|
229
232
|
}
|
|
230
233
|
return `<div class="Field">{{ ${parentKey}.${name} }}</div>`;
|
|
231
234
|
}
|
|
235
|
+
function templateOfPartField(ctx, field, parentKey) {
|
|
236
|
+
const partKey = `${parentKey}.${field.name}`;
|
|
237
|
+
const partType = ctx.siteSchema.nodeTypes?.find((nt) => nt.typeName === field.partType && nt.kind === "part");
|
|
238
|
+
if (!partType?.fields || partType.fields.length === 0) {
|
|
239
|
+
return `{%- comment -%} Part field: ${field.name} (no fields) {%- endcomment -%}`;
|
|
240
|
+
}
|
|
241
|
+
const innerFields = templateOfFields(ctx, partType.fields, { parentKey: `${partKey}.field` });
|
|
242
|
+
if (!innerFields)
|
|
243
|
+
return "";
|
|
244
|
+
return `{% if ${partKey} %}
|
|
245
|
+
<div class="${camelToKebabCase(field.partType)}">
|
|
246
|
+
${innerFields}
|
|
247
|
+
</div>
|
|
248
|
+
{% endif %}`;
|
|
249
|
+
}
|
|
232
250
|
function templateOfPicture({ imageKey }) {
|
|
233
251
|
return `{% if ${imageKey} %}
|
|
234
252
|
{% set smallIm = image(${imageKey}, resize: "360x48") %}
|
|
@@ -89,7 +89,23 @@ A labeling field lets the user assign taxonomy terms to a document (or part).
|
|
|
89
89
|
|
|
90
90
|
Most of the time, the field name will be the same as the taxonomy type name.
|
|
91
91
|
|
|
92
|
-
# 4.
|
|
92
|
+
# 4. Part Field (embedding a part inline)
|
|
93
|
+
|
|
94
|
+
A part field embeds a single part directly within a document or part's field list. The referenced part type must exist in the schema's nodeTypes as a `kind: "part"` node type.
|
|
95
|
+
|
|
96
|
+
<field_type_example>
|
|
97
|
+
{
|
|
98
|
+
"name": "seo",
|
|
99
|
+
"storedAs": "partField",
|
|
100
|
+
"partType": "myPartTypeName"
|
|
101
|
+
}
|
|
102
|
+
</field_type_example>
|
|
103
|
+
|
|
104
|
+
When using a partField, the referenced part type (e.g., "myPartTypeName") must be defined as a `kind: "part"` node type in the schema. The part will be embedded inline in the document editor, not in the parts tab.
|
|
105
|
+
|
|
106
|
+
Use partField when a group of fields should logically belong together as a reusable unit (e.g., SEO metadata, social sharing settings, address blocks).
|
|
107
|
+
|
|
108
|
+
# 5. Examine the current JSON data, which conforms to the `JtSiteSchema` type
|
|
93
109
|
|
|
94
110
|
<site_schema_json>
|
|
95
111
|
{{siteSchemaJson}}
|
|
@@ -101,20 +117,20 @@ Also, the attached locales:
|
|
|
101
117
|
{{l10nJson}}
|
|
102
118
|
</l10n_json>
|
|
103
119
|
|
|
104
|
-
#
|
|
120
|
+
# 6. Now, here is what to do
|
|
105
121
|
|
|
106
122
|
<user_request>
|
|
107
123
|
{{taskDetailsMd}}
|
|
108
124
|
</user_request>
|
|
109
125
|
|
|
110
|
-
#
|
|
126
|
+
# 7. Guidelines
|
|
111
127
|
|
|
112
128
|
- Don't assume how the CMS works. If you are not sure how to do something, don't do it.
|
|
113
129
|
- You are allowed to be proactive, but only when the user asks you to do something.
|
|
114
130
|
- Remember to adhere strictly to the TypeScript typing when making changes. If the update message requests changes that would violate the typing, then prioritize maintaining the correct structure over making those specific changes.
|
|
115
131
|
- Field choice for listing pages: For new routing documents that have `regularChildren` (like blog index, products index, etc.), prefer `introduction[@paroicms/tiptap-editor-plugin]` instead of `htmlContent[@paroicms/tiptap-editor-plugin]`. These pages display a list of child items, so they only need a short introduction, not full HTML content.
|
|
116
132
|
|
|
117
|
-
#
|
|
133
|
+
# 8. Output
|
|
118
134
|
|
|
119
135
|
If there is a change in the site schema, then provide the updated site schema in JSON within <updated_site_schema_json> tags. Otherwise, let this tag empty.
|
|
120
136
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@paroicms/site-generator-plugin",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.32.0",
|
|
4
4
|
"description": "ParoiCMS Site Generator Plugin",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"paroicms",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"dependencies": {
|
|
31
31
|
"@anthropic-ai/sdk": "~0.78.0",
|
|
32
32
|
"@mistralai/mistralai": "~1.14.1",
|
|
33
|
-
"@paroicms/script-lib": "0.3.
|
|
33
|
+
"@paroicms/script-lib": "0.3.20",
|
|
34
34
|
"arktype": "~2.2.0",
|
|
35
35
|
"jsonwebtoken": "~9.0.3",
|
|
36
36
|
"knex": "~3.1.0",
|
|
@@ -42,9 +42,9 @@
|
|
|
42
42
|
"@paroicms/public-server-lib": "0"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
|
-
"@paroicms/internal-anywhere-lib": "1.39.
|
|
46
|
-
"@paroicms/internal-server-lib": "1.24.
|
|
47
|
-
"@paroicms/public-server-lib": "0.
|
|
45
|
+
"@paroicms/internal-anywhere-lib": "1.39.1",
|
|
46
|
+
"@paroicms/internal-server-lib": "1.24.5",
|
|
47
|
+
"@paroicms/public-server-lib": "0.56.0",
|
|
48
48
|
"@types/node": "~24.11.0",
|
|
49
49
|
"marked": "~17.0.4",
|
|
50
50
|
"nodemon": "~3.1.14",
|