@wp-typia/project-tools 0.16.14 → 0.17.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/dist/runtime/block-generator-service-spec.d.ts +6 -0
- package/dist/runtime/block-generator-service-spec.js +27 -0
- package/dist/runtime/built-in-block-code-artifacts.js +14 -1
- package/dist/runtime/built-in-block-code-templates/query-loop.d.ts +1 -0
- package/dist/runtime/built-in-block-code-templates/query-loop.js +70 -0
- package/dist/runtime/built-in-block-code-templates.d.ts +1 -0
- package/dist/runtime/built-in-block-code-templates.js +1 -0
- package/dist/runtime/built-in-block-non-ts-artifacts.js +2 -0
- package/dist/runtime/cli-help.js +1 -0
- package/dist/runtime/cli-scaffold.d.ts +2 -1
- package/dist/runtime/cli-scaffold.js +2 -1
- package/dist/runtime/local-dev-presets.js +21 -11
- package/dist/runtime/scaffold-answer-resolution.d.ts +1 -1
- package/dist/runtime/scaffold-answer-resolution.js +26 -1
- package/dist/runtime/scaffold-documents.js +8 -9
- package/dist/runtime/scaffold-onboarding.js +12 -0
- package/dist/runtime/scaffold-template-variables.js +6 -0
- package/dist/runtime/scaffold.d.ts +8 -0
- package/dist/runtime/template-defaults.d.ts +7 -0
- package/dist/runtime/template-defaults.js +4 -0
- package/dist/runtime/template-registry.d.ts +1 -1
- package/dist/runtime/template-registry.js +14 -1
- package/package.json +1 -1
- package/templates/query-loop/inc/query-runtime.php.mustache +85 -0
- package/templates/query-loop/package.json.mustache +32 -0
- package/templates/query-loop/src/patterns/grid.php.mustache +49 -0
- package/templates/query-loop/src/patterns/list.php.mustache +48 -0
- package/templates/query-loop/src/query-extension.ts.mustache +41 -0
- package/templates/query-loop/src/validator-toolkit.ts.mustache +1 -0
- package/templates/query-loop/webpack.config.js.mustache +16 -0
- package/templates/query-loop/{{slugKebabCase}}.php.mustache +84 -0
|
@@ -27,6 +27,11 @@ export interface BlockSpec {
|
|
|
27
27
|
project: {
|
|
28
28
|
author: string;
|
|
29
29
|
};
|
|
30
|
+
queryLoop: {
|
|
31
|
+
allowedControls: readonly string[];
|
|
32
|
+
enabled: boolean;
|
|
33
|
+
postType: string;
|
|
34
|
+
};
|
|
30
35
|
runtime: {
|
|
31
36
|
withMigrationUi: boolean;
|
|
32
37
|
withTestPreset: boolean;
|
|
@@ -66,6 +71,7 @@ export interface PlanBlockInput {
|
|
|
66
71
|
templateId: BuiltInTemplateId;
|
|
67
72
|
variant?: string;
|
|
68
73
|
withMigrationUi?: boolean;
|
|
74
|
+
queryPostType?: string;
|
|
69
75
|
withTestPreset?: boolean;
|
|
70
76
|
withWpEnv?: boolean;
|
|
71
77
|
}
|
|
@@ -24,6 +24,15 @@ function getBuiltInPersistenceSpec({ templateId, dataStorageMode, persistencePol
|
|
|
24
24
|
enabled: false,
|
|
25
25
|
};
|
|
26
26
|
}
|
|
27
|
+
const DEFAULT_QUERY_LOOP_ALLOWED_CONTROLS = [
|
|
28
|
+
"inherit",
|
|
29
|
+
"postType",
|
|
30
|
+
"order",
|
|
31
|
+
"sticky",
|
|
32
|
+
"taxQuery",
|
|
33
|
+
"author",
|
|
34
|
+
"search",
|
|
35
|
+
];
|
|
27
36
|
export function createBuiltInBlockSpec({ answers, dataStorageMode, persistencePolicy, templateId, withMigrationUi = false, withTestPreset = false, withWpEnv = false, }) {
|
|
28
37
|
const template = getTemplateById(templateId);
|
|
29
38
|
const metadataDefaults = getBuiltInTemplateMetadataDefaults(templateId);
|
|
@@ -52,6 +61,17 @@ export function createBuiltInBlockSpec({ answers, dataStorageMode, persistencePo
|
|
|
52
61
|
project: {
|
|
53
62
|
author: answers.author.trim(),
|
|
54
63
|
},
|
|
64
|
+
queryLoop: templateId === "query-loop"
|
|
65
|
+
? {
|
|
66
|
+
allowedControls: DEFAULT_QUERY_LOOP_ALLOWED_CONTROLS,
|
|
67
|
+
enabled: true,
|
|
68
|
+
postType: (answers.queryPostType ?? "post").trim() || "post",
|
|
69
|
+
}
|
|
70
|
+
: {
|
|
71
|
+
allowedControls: [],
|
|
72
|
+
enabled: false,
|
|
73
|
+
postType: "post",
|
|
74
|
+
},
|
|
55
75
|
runtime: {
|
|
56
76
|
withMigrationUi,
|
|
57
77
|
withTestPreset,
|
|
@@ -82,6 +102,7 @@ export function buildTemplateVariablesFromBlockSpec(spec) {
|
|
|
82
102
|
const persistencePolicy = persistenceEnabled
|
|
83
103
|
? spec.persistence.persistencePolicy
|
|
84
104
|
: "authenticated";
|
|
105
|
+
const queryVariationNamespace = `${namespace}/${slug}`;
|
|
85
106
|
return {
|
|
86
107
|
apiClientPackageVersion,
|
|
87
108
|
author: spec.project.author,
|
|
@@ -101,7 +122,13 @@ export function buildTemplateVariablesFromBlockSpec(spec) {
|
|
|
101
122
|
dashCase: slug,
|
|
102
123
|
dataStorageMode,
|
|
103
124
|
description: spec.metadata.description,
|
|
125
|
+
descriptionJson: JSON.stringify(spec.metadata.description),
|
|
104
126
|
frontendCssClassName: buildFrontendCssClassName(cssClassName),
|
|
127
|
+
queryAllowedControlsJson: JSON.stringify(spec.queryLoop.enabled ? spec.queryLoop.allowedControls : [], null, 2),
|
|
128
|
+
queryPostType: spec.queryLoop.enabled ? spec.queryLoop.postType : "post",
|
|
129
|
+
queryPostTypeJson: JSON.stringify(spec.queryLoop.enabled ? spec.queryLoop.postType : "post"),
|
|
130
|
+
queryVariationNamespace,
|
|
131
|
+
queryVariationNamespaceJson: JSON.stringify(queryVariationNamespace),
|
|
105
132
|
isAuthenticatedPersistencePolicy: persistencePolicy === "authenticated" ? "true" : "false",
|
|
106
133
|
isPublicPersistencePolicy: persistencePolicy === "public" ? "true" : "false",
|
|
107
134
|
bootstrapCredentialDeclarations: persistencePolicy === "public"
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { buildBuiltInNonTsArtifacts } from "./built-in-block-non-ts-artifacts.js";
|
|
2
|
-
import { BASIC_EDIT_TEMPLATE, BASIC_INDEX_TEMPLATE, BASIC_SAVE_TEMPLATE, BASIC_VALIDATORS_TEMPLATE, BLOCK_METADATA_WRAPPER_TEMPLATE, COMPOUND_CHILD_EDIT_TEMPLATE, COMPOUND_CHILD_INDEX_TEMPLATE, COMPOUND_CHILD_SAVE_TEMPLATE, COMPOUND_CHILD_VALIDATORS_TEMPLATE, COMPOUND_CHILDREN_TEMPLATE, COMPOUND_LOCAL_HOOKS_TEMPLATE, COMPOUND_PARENT_EDIT_TEMPLATE, COMPOUND_PARENT_INDEX_TEMPLATE, COMPOUND_PARENT_SAVE_TEMPLATE, COMPOUND_PARENT_VALIDATORS_TEMPLATE, COMPOUND_PERSISTENCE_PARENT_EDIT_TEMPLATE, COMPOUND_PERSISTENCE_PARENT_INTERACTIVITY_TEMPLATE, COMPOUND_PERSISTENCE_PARENT_SAVE_TEMPLATE, COMPOUND_PERSISTENCE_PARENT_VALIDATORS_TEMPLATE, INTERACTIVITY_EDIT_TEMPLATE, INTERACTIVITY_INDEX_TEMPLATE, INTERACTIVITY_SAVE_TEMPLATE, INTERACTIVITY_SCRIPT_TEMPLATE, INTERACTIVITY_VALIDATORS_TEMPLATE, MANIFEST_DEFAULTS_DOCUMENT_WRAPPER_TEMPLATE, MANIFEST_DOCUMENT_WRAPPER_TEMPLATE, PERSISTENCE_EDIT_TEMPLATE, PERSISTENCE_INDEX_TEMPLATE, PERSISTENCE_INTERACTIVITY_TEMPLATE, PERSISTENCE_SAVE_TEMPLATE, PERSISTENCE_VALIDATORS_TEMPLATE, SHARED_HOOKS_TEMPLATE, } from "./built-in-block-code-templates.js";
|
|
2
|
+
import { BASIC_EDIT_TEMPLATE, BASIC_INDEX_TEMPLATE, BASIC_SAVE_TEMPLATE, BASIC_VALIDATORS_TEMPLATE, BLOCK_METADATA_WRAPPER_TEMPLATE, COMPOUND_CHILD_EDIT_TEMPLATE, COMPOUND_CHILD_INDEX_TEMPLATE, COMPOUND_CHILD_SAVE_TEMPLATE, COMPOUND_CHILD_VALIDATORS_TEMPLATE, COMPOUND_CHILDREN_TEMPLATE, COMPOUND_LOCAL_HOOKS_TEMPLATE, COMPOUND_PARENT_EDIT_TEMPLATE, COMPOUND_PARENT_INDEX_TEMPLATE, COMPOUND_PARENT_SAVE_TEMPLATE, COMPOUND_PARENT_VALIDATORS_TEMPLATE, COMPOUND_PERSISTENCE_PARENT_EDIT_TEMPLATE, COMPOUND_PERSISTENCE_PARENT_INTERACTIVITY_TEMPLATE, COMPOUND_PERSISTENCE_PARENT_SAVE_TEMPLATE, COMPOUND_PERSISTENCE_PARENT_VALIDATORS_TEMPLATE, INTERACTIVITY_EDIT_TEMPLATE, INTERACTIVITY_INDEX_TEMPLATE, INTERACTIVITY_SAVE_TEMPLATE, INTERACTIVITY_SCRIPT_TEMPLATE, INTERACTIVITY_VALIDATORS_TEMPLATE, MANIFEST_DEFAULTS_DOCUMENT_WRAPPER_TEMPLATE, MANIFEST_DOCUMENT_WRAPPER_TEMPLATE, PERSISTENCE_EDIT_TEMPLATE, PERSISTENCE_INDEX_TEMPLATE, PERSISTENCE_INTERACTIVITY_TEMPLATE, PERSISTENCE_SAVE_TEMPLATE, PERSISTENCE_VALIDATORS_TEMPLATE, QUERY_LOOP_INDEX_TEMPLATE, SHARED_HOOKS_TEMPLATE, } from "./built-in-block-code-templates.js";
|
|
3
3
|
import { renderMustacheTemplateString } from "./template-render.js";
|
|
4
4
|
function renderCodeTemplate(template, variables) {
|
|
5
5
|
const rendered = renderMustacheTemplateString(template, variables);
|
|
@@ -162,6 +162,17 @@ function buildPersistenceCodeArtifacts(variables) {
|
|
|
162
162
|
...buildBuiltInNonTsArtifacts({ templateId: "persistence", variables }),
|
|
163
163
|
]);
|
|
164
164
|
}
|
|
165
|
+
function buildQueryLoopCodeArtifacts(variables) {
|
|
166
|
+
return ensureUniqueArtifactPaths([
|
|
167
|
+
...createCodeArtifacts([
|
|
168
|
+
{
|
|
169
|
+
relativePath: "src/index.ts",
|
|
170
|
+
template: QUERY_LOOP_INDEX_TEMPLATE,
|
|
171
|
+
},
|
|
172
|
+
], variables),
|
|
173
|
+
...buildBuiltInNonTsArtifacts({ templateId: "query-loop", variables }),
|
|
174
|
+
]);
|
|
175
|
+
}
|
|
165
176
|
/**
|
|
166
177
|
* Build the emitter-owned scaffold files for a built-in template family.
|
|
167
178
|
*
|
|
@@ -179,6 +190,8 @@ export function buildBuiltInCodeArtifacts({ templateId, variables, }) {
|
|
|
179
190
|
return buildPersistenceCodeArtifacts(variables);
|
|
180
191
|
case "compound":
|
|
181
192
|
return buildCompoundCodeArtifacts(variables);
|
|
193
|
+
case "query-loop":
|
|
194
|
+
return buildQueryLoopCodeArtifacts(variables);
|
|
182
195
|
default: {
|
|
183
196
|
const unhandledTemplateId = templateId;
|
|
184
197
|
throw new Error(`Unhandled built-in template id: ${unhandledTemplateId}`);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const QUERY_LOOP_INDEX_TEMPLATE = "import { registerBlockVariation } from '@wordpress/blocks';\nimport type { BlockVariation } from '@wp-typia/block-types/blocks/registration';\nimport { __ } from '@wordpress/i18n';\nimport {\n getQueryLoopCustomAllowedControls,\n getQueryLoopCustomQuerySeed,\n registerQueryLoopEditorExtensions,\n} from './query-extension';\n\ntype QueryLoopVariationAttributes = {\n namespace?: string;\n query?: {\n inherit?: boolean;\n order?: 'asc' | 'desc';\n orderBy?: string;\n perPage?: number;\n postType?: string;\n wpTypiaVariation?: string;\n [key: string]: unknown;\n };\n};\n\ntype QueryLoopVariation = BlockVariation<QueryLoopVariationAttributes> & {\n allowedControls: string[];\n};\n\nconst VARIATION_NAME = {{queryVariationNamespaceJson}};\nconst DEFAULT_ALLOWED_CONTROLS = {{queryAllowedControlsJson}};\nconst customQuerySeed = getQueryLoopCustomQuerySeed();\nconst allowedControls = Array.from(\n new Set([...DEFAULT_ALLOWED_CONTROLS, ...getQueryLoopCustomAllowedControls()]),\n);\n\nconst queryLoopVariation = {\n name: VARIATION_NAME,\n title: __({{titleJson}}, '{{textDomain}}'),\n description: __({{descriptionJson}}, '{{textDomain}}'),\n scope: ['inserter'],\n isActive: ['namespace'],\n attributes: {\n namespace: VARIATION_NAME,\n query: {\n inherit: false,\n order: 'desc',\n orderBy: 'date',\n perPage: 6,\n postType: {{queryPostTypeJson}},\n ...customQuerySeed,\n wpTypiaVariation: VARIATION_NAME,\n },\n },\n allowedControls,\n innerBlocks: [\n [\n 'core/post-template',\n {},\n [\n ['core/post-featured-image'],\n ['core/post-title', { isLink: true }],\n ['core/post-excerpt'],\n ],\n ],\n ['core/query-pagination'],\n ['core/query-no-results'],\n ],\n} satisfies QueryLoopVariation;\n\nregisterBlockVariation('core/query', queryLoopVariation);\nregisterQueryLoopEditorExtensions({ variationName: VARIATION_NAME });\n";
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
export const QUERY_LOOP_INDEX_TEMPLATE = `import { registerBlockVariation } from '@wordpress/blocks';
|
|
2
|
+
import type { BlockVariation } from '@wp-typia/block-types/blocks/registration';
|
|
3
|
+
import { __ } from '@wordpress/i18n';
|
|
4
|
+
import {
|
|
5
|
+
getQueryLoopCustomAllowedControls,
|
|
6
|
+
getQueryLoopCustomQuerySeed,
|
|
7
|
+
registerQueryLoopEditorExtensions,
|
|
8
|
+
} from './query-extension';
|
|
9
|
+
|
|
10
|
+
type QueryLoopVariationAttributes = {
|
|
11
|
+
namespace?: string;
|
|
12
|
+
query?: {
|
|
13
|
+
inherit?: boolean;
|
|
14
|
+
order?: 'asc' | 'desc';
|
|
15
|
+
orderBy?: string;
|
|
16
|
+
perPage?: number;
|
|
17
|
+
postType?: string;
|
|
18
|
+
wpTypiaVariation?: string;
|
|
19
|
+
[key: string]: unknown;
|
|
20
|
+
};
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
type QueryLoopVariation = BlockVariation<QueryLoopVariationAttributes> & {
|
|
24
|
+
allowedControls: string[];
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
const VARIATION_NAME = {{queryVariationNamespaceJson}};
|
|
28
|
+
const DEFAULT_ALLOWED_CONTROLS = {{queryAllowedControlsJson}};
|
|
29
|
+
const customQuerySeed = getQueryLoopCustomQuerySeed();
|
|
30
|
+
const allowedControls = Array.from(
|
|
31
|
+
new Set([...DEFAULT_ALLOWED_CONTROLS, ...getQueryLoopCustomAllowedControls()]),
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
const queryLoopVariation = {
|
|
35
|
+
name: VARIATION_NAME,
|
|
36
|
+
title: __({{titleJson}}, '{{textDomain}}'),
|
|
37
|
+
description: __({{descriptionJson}}, '{{textDomain}}'),
|
|
38
|
+
scope: ['inserter'],
|
|
39
|
+
isActive: ['namespace'],
|
|
40
|
+
attributes: {
|
|
41
|
+
namespace: VARIATION_NAME,
|
|
42
|
+
query: {
|
|
43
|
+
inherit: false,
|
|
44
|
+
order: 'desc',
|
|
45
|
+
orderBy: 'date',
|
|
46
|
+
perPage: 6,
|
|
47
|
+
postType: {{queryPostTypeJson}},
|
|
48
|
+
...customQuerySeed,
|
|
49
|
+
wpTypiaVariation: VARIATION_NAME,
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
allowedControls,
|
|
53
|
+
innerBlocks: [
|
|
54
|
+
[
|
|
55
|
+
'core/post-template',
|
|
56
|
+
{},
|
|
57
|
+
[
|
|
58
|
+
['core/post-featured-image'],
|
|
59
|
+
['core/post-title', { isLink: true }],
|
|
60
|
+
['core/post-excerpt'],
|
|
61
|
+
],
|
|
62
|
+
],
|
|
63
|
+
['core/query-pagination'],
|
|
64
|
+
['core/query-no-results'],
|
|
65
|
+
],
|
|
66
|
+
} satisfies QueryLoopVariation;
|
|
67
|
+
|
|
68
|
+
registerBlockVariation('core/query', queryLoopVariation);
|
|
69
|
+
registerQueryLoopEditorExtensions({ variationName: VARIATION_NAME });
|
|
70
|
+
`;
|
|
@@ -6,4 +6,5 @@ export { BLOCK_METADATA_WRAPPER_TEMPLATE, MANIFEST_DEFAULTS_DOCUMENT_WRAPPER_TEM
|
|
|
6
6
|
export { BASIC_EDIT_TEMPLATE, BASIC_INDEX_TEMPLATE, BASIC_SAVE_TEMPLATE, BASIC_VALIDATORS_TEMPLATE, } from "./built-in-block-code-templates/basic.js";
|
|
7
7
|
export { INTERACTIVITY_EDIT_TEMPLATE, INTERACTIVITY_INDEX_TEMPLATE, INTERACTIVITY_SAVE_TEMPLATE, INTERACTIVITY_SCRIPT_TEMPLATE, INTERACTIVITY_VALIDATORS_TEMPLATE, } from "./built-in-block-code-templates/interactivity.js";
|
|
8
8
|
export { PERSISTENCE_EDIT_TEMPLATE, PERSISTENCE_INDEX_TEMPLATE, PERSISTENCE_INTERACTIVITY_TEMPLATE, PERSISTENCE_SAVE_TEMPLATE, PERSISTENCE_VALIDATORS_TEMPLATE, } from "./built-in-block-code-templates/persistence.js";
|
|
9
|
+
export { QUERY_LOOP_INDEX_TEMPLATE, } from "./built-in-block-code-templates/query-loop.js";
|
|
9
10
|
export { COMPOUND_CHILD_EDIT_TEMPLATE, COMPOUND_CHILD_INDEX_TEMPLATE, COMPOUND_CHILDREN_TEMPLATE, COMPOUND_CHILD_SAVE_TEMPLATE, COMPOUND_CHILD_VALIDATORS_TEMPLATE, COMPOUND_LOCAL_HOOKS_TEMPLATE, COMPOUND_PARENT_EDIT_TEMPLATE, COMPOUND_PARENT_INDEX_TEMPLATE, COMPOUND_PARENT_SAVE_TEMPLATE, COMPOUND_PARENT_VALIDATORS_TEMPLATE, COMPOUND_PERSISTENCE_PARENT_EDIT_TEMPLATE, COMPOUND_PERSISTENCE_PARENT_INTERACTIVITY_TEMPLATE, COMPOUND_PERSISTENCE_PARENT_SAVE_TEMPLATE, COMPOUND_PERSISTENCE_PARENT_VALIDATORS_TEMPLATE, } from "./built-in-block-code-templates/compound.js";
|
|
@@ -6,4 +6,5 @@ export { BLOCK_METADATA_WRAPPER_TEMPLATE, MANIFEST_DEFAULTS_DOCUMENT_WRAPPER_TEM
|
|
|
6
6
|
export { BASIC_EDIT_TEMPLATE, BASIC_INDEX_TEMPLATE, BASIC_SAVE_TEMPLATE, BASIC_VALIDATORS_TEMPLATE, } from "./built-in-block-code-templates/basic.js";
|
|
7
7
|
export { INTERACTIVITY_EDIT_TEMPLATE, INTERACTIVITY_INDEX_TEMPLATE, INTERACTIVITY_SAVE_TEMPLATE, INTERACTIVITY_SCRIPT_TEMPLATE, INTERACTIVITY_VALIDATORS_TEMPLATE, } from "./built-in-block-code-templates/interactivity.js";
|
|
8
8
|
export { PERSISTENCE_EDIT_TEMPLATE, PERSISTENCE_INDEX_TEMPLATE, PERSISTENCE_INTERACTIVITY_TEMPLATE, PERSISTENCE_SAVE_TEMPLATE, PERSISTENCE_VALIDATORS_TEMPLATE, } from "./built-in-block-code-templates/persistence.js";
|
|
9
|
+
export { QUERY_LOOP_INDEX_TEMPLATE, } from "./built-in-block-code-templates/query-loop.js";
|
|
9
10
|
export { COMPOUND_CHILD_EDIT_TEMPLATE, COMPOUND_CHILD_INDEX_TEMPLATE, COMPOUND_CHILDREN_TEMPLATE, COMPOUND_CHILD_SAVE_TEMPLATE, COMPOUND_CHILD_VALIDATORS_TEMPLATE, COMPOUND_LOCAL_HOOKS_TEMPLATE, COMPOUND_PARENT_EDIT_TEMPLATE, COMPOUND_PARENT_INDEX_TEMPLATE, COMPOUND_PARENT_SAVE_TEMPLATE, COMPOUND_PARENT_VALIDATORS_TEMPLATE, COMPOUND_PERSISTENCE_PARENT_EDIT_TEMPLATE, COMPOUND_PERSISTENCE_PARENT_INTERACTIVITY_TEMPLATE, COMPOUND_PERSISTENCE_PARENT_SAVE_TEMPLATE, COMPOUND_PERSISTENCE_PARENT_VALIDATORS_TEMPLATE, } from "./built-in-block-code-templates/compound.js";
|
|
@@ -555,6 +555,8 @@ export function buildBuiltInNonTsArtifacts({ templateId, variables, }) {
|
|
|
555
555
|
return buildPersistenceArtifacts(variables);
|
|
556
556
|
case "compound":
|
|
557
557
|
return buildCompoundArtifacts(variables);
|
|
558
|
+
case "query-loop":
|
|
559
|
+
return [];
|
|
558
560
|
default: {
|
|
559
561
|
const unhandledTemplateId = templateId;
|
|
560
562
|
throw new Error(`Unhandled built-in template id: ${unhandledTemplateId}`);
|
package/dist/runtime/cli-help.js
CHANGED
|
@@ -11,6 +11,7 @@ import { TEMPLATE_IDS } from "./template-registry.js";
|
|
|
11
11
|
export function formatHelpText() {
|
|
12
12
|
return `Usage:
|
|
13
13
|
wp-typia create <project-dir> [--template <basic|interactivity>] [--external-layer-source <./path|github:owner/repo/path[#ref]|npm-package>] [--external-layer-id <layer-id>] [--namespace <value>] [--text-domain <value>] [--php-prefix <value>] [--with-migration-ui] [--with-wp-env] [--with-test-preset] [--yes] [--no-install] [--package-manager <id>]
|
|
14
|
+
wp-typia create <project-dir> [--template query-loop] [--external-layer-source <./path|github:owner/repo/path[#ref]|npm-package>] [--external-layer-id <layer-id>] [--query-post-type <post-type>] [--namespace <value>] [--text-domain <value>] [--php-prefix <value>] [--with-migration-ui] [--with-wp-env] [--with-test-preset] [--yes] [--no-install] [--package-manager <id>]
|
|
14
15
|
wp-typia create <project-dir> [--template <./path|github:owner/repo/path[#ref]>] [--variant <name>] [--namespace <value>] [--text-domain <value>] [--php-prefix <value>] [--with-wp-env] [--with-test-preset] [--yes] [--no-install] [--package-manager <id>]
|
|
15
16
|
wp-typia create <project-dir> [--template <npm-package>] [--variant <name>] [--namespace <value>] [--text-domain <value>] [--php-prefix <value>] [--with-wp-env] [--with-test-preset] [--yes] [--no-install] [--package-manager <id>]
|
|
16
17
|
wp-typia create <project-dir> [--template persistence] [--external-layer-source <./path|github:owner/repo/path[#ref]|npm-package>] [--external-layer-id <layer-id>] [--data-storage <post-meta|custom-table>] [--persistence-policy <authenticated|public>] [--namespace <value>] [--text-domain <value>] [--php-prefix <value>] [--with-migration-ui] [--with-wp-env] [--with-test-preset] [--yes] [--no-install] [--package-manager <id>]
|
|
@@ -34,6 +34,7 @@ interface RunScaffoldFlowOptions {
|
|
|
34
34
|
phpPrefix?: string;
|
|
35
35
|
projectInput: string;
|
|
36
36
|
promptText?: Parameters<typeof collectScaffoldAnswers>[0]["promptText"];
|
|
37
|
+
queryPostType?: string;
|
|
37
38
|
selectDataStorage?: () => Promise<DataStorageMode>;
|
|
38
39
|
selectExternalLayerId?: (options: ExternalLayerSelectionOption[]) => Promise<string>;
|
|
39
40
|
selectPackageManager?: () => Promise<PackageManagerId>;
|
|
@@ -73,7 +74,7 @@ export declare function getOptionalOnboarding({ availableScripts, packageManager
|
|
|
73
74
|
* project.
|
|
74
75
|
* @returns The scaffold result together with next-step guidance.
|
|
75
76
|
*/
|
|
76
|
-
export declare function runScaffoldFlow({ projectInput, cwd, templateId, dataStorageMode, externalLayerId, externalLayerSource, persistencePolicy, packageManager, namespace, textDomain, phpPrefix, yes, noInstall, isInteractive, allowExistingDir, selectTemplate, selectDataStorage, selectExternalLayerId, selectPersistencePolicy, selectPackageManager, promptText, installDependencies, variant, selectWithTestPreset, selectWithWpEnv, selectWithMigrationUi, withMigrationUi, withTestPreset, withWpEnv, }: RunScaffoldFlowOptions): Promise<{
|
|
77
|
+
export declare function runScaffoldFlow({ projectInput, cwd, templateId, dataStorageMode, externalLayerId, externalLayerSource, persistencePolicy, packageManager, namespace, textDomain, phpPrefix, queryPostType, yes, noInstall, isInteractive, allowExistingDir, selectTemplate, selectDataStorage, selectExternalLayerId, selectPersistencePolicy, selectPackageManager, promptText, installDependencies, variant, selectWithTestPreset, selectWithWpEnv, selectWithMigrationUi, withMigrationUi, withTestPreset, withWpEnv, }: RunScaffoldFlowOptions): Promise<{
|
|
77
78
|
optionalOnboarding: OptionalOnboardingGuidance;
|
|
78
79
|
projectDir: string;
|
|
79
80
|
projectInput: string;
|
|
@@ -135,7 +135,7 @@ export function getOptionalOnboarding({ availableScripts, packageManager, templa
|
|
|
135
135
|
* project.
|
|
136
136
|
* @returns The scaffold result together with next-step guidance.
|
|
137
137
|
*/
|
|
138
|
-
export async function runScaffoldFlow({ projectInput, cwd = process.cwd(), templateId, dataStorageMode, externalLayerId, externalLayerSource, persistencePolicy, packageManager, namespace, textDomain, phpPrefix, yes = false, noInstall = false, isInteractive = false, allowExistingDir = false, selectTemplate, selectDataStorage, selectExternalLayerId, selectPersistencePolicy, selectPackageManager, promptText, installDependencies = undefined, variant, selectWithTestPreset, selectWithWpEnv, selectWithMigrationUi, withMigrationUi, withTestPreset, withWpEnv, }) {
|
|
138
|
+
export async function runScaffoldFlow({ projectInput, cwd = process.cwd(), templateId, dataStorageMode, externalLayerId, externalLayerSource, persistencePolicy, packageManager, namespace, textDomain, phpPrefix, queryPostType, yes = false, noInstall = false, isInteractive = false, allowExistingDir = false, selectTemplate, selectDataStorage, selectExternalLayerId, selectPersistencePolicy, selectPackageManager, promptText, installDependencies = undefined, variant, selectWithTestPreset, selectWithWpEnv, selectWithMigrationUi, withMigrationUi, withTestPreset, withWpEnv, }) {
|
|
139
139
|
const normalizedExternalLayerId = typeof externalLayerId === "string" && externalLayerId.trim().length > 0
|
|
140
140
|
? externalLayerId.trim()
|
|
141
141
|
: undefined;
|
|
@@ -228,6 +228,7 @@ export async function runScaffoldFlow({ projectInput, cwd = process.cwd(), templ
|
|
|
228
228
|
persistencePolicy: resolvedPersistencePolicy,
|
|
229
229
|
phpPrefix,
|
|
230
230
|
projectName,
|
|
231
|
+
queryPostType,
|
|
231
232
|
templateId: resolvedTemplateId,
|
|
232
233
|
textDomain,
|
|
233
234
|
yes,
|
|
@@ -13,6 +13,12 @@ import { copyInterpolatedDirectory } from "./template-render.js";
|
|
|
13
13
|
function templateHasPersistenceSync(templateId, compoundPersistenceEnabled) {
|
|
14
14
|
return templateId === "persistence" || (templateId === "compound" && compoundPersistenceEnabled);
|
|
15
15
|
}
|
|
16
|
+
function templateSupportsGeneratedSyncWatchers(templateId) {
|
|
17
|
+
return (templateId === "basic" ||
|
|
18
|
+
templateId === "interactivity" ||
|
|
19
|
+
templateId === "persistence" ||
|
|
20
|
+
templateId === "compound");
|
|
21
|
+
}
|
|
16
22
|
function getWatchSyncTypesScript(packageManager, templateId) {
|
|
17
23
|
if (templateId === "compound") {
|
|
18
24
|
return `chokidar "src/blocks/**/types.ts" "scripts/block-config.ts" --debounce 200 -c "${formatRunScript(packageManager, "sync-types")}"`;
|
|
@@ -80,11 +86,16 @@ export async function applyLocalDevPresetFiles({ projectDir, variables, withTest
|
|
|
80
86
|
*/
|
|
81
87
|
export async function applyGeneratedProjectDxPackageJson({ compoundPersistenceEnabled = false, packageManager, projectDir, templateId, withTestPreset = false, withWpEnv = false, }) {
|
|
82
88
|
const hasPersistenceSync = templateHasPersistenceSync(templateId, compoundPersistenceEnabled);
|
|
89
|
+
const supportsGeneratedSyncWatchers = templateSupportsGeneratedSyncWatchers(templateId);
|
|
83
90
|
await mutatePackageJson(projectDir, (packageJson) => {
|
|
84
91
|
packageJson.devDependencies = {
|
|
85
92
|
...(packageJson.devDependencies ?? {}),
|
|
86
|
-
|
|
87
|
-
|
|
93
|
+
...(supportsGeneratedSyncWatchers
|
|
94
|
+
? {
|
|
95
|
+
"chokidar-cli": "^3.0.0",
|
|
96
|
+
concurrently: "^9.0.1",
|
|
97
|
+
}
|
|
98
|
+
: {}),
|
|
88
99
|
};
|
|
89
100
|
if (withWpEnv || withTestPreset) {
|
|
90
101
|
packageJson.devDependencies["@wordpress/env"] = "^11.2.0";
|
|
@@ -95,12 +106,16 @@ export async function applyGeneratedProjectDxPackageJson({ compoundPersistenceEn
|
|
|
95
106
|
const scripts = {
|
|
96
107
|
...(packageJson.scripts ?? {}),
|
|
97
108
|
};
|
|
98
|
-
|
|
99
|
-
|
|
109
|
+
if (supportsGeneratedSyncWatchers) {
|
|
110
|
+
scripts["start:editor"] = "wp-scripts start --experimental-modules";
|
|
111
|
+
scripts["watch:sync-types"] = getWatchSyncTypesScript(packageManager, templateId);
|
|
112
|
+
}
|
|
100
113
|
if (hasPersistenceSync) {
|
|
101
114
|
scripts["watch:sync-rest"] = getWatchSyncRestScript(packageManager, templateId);
|
|
102
115
|
}
|
|
103
|
-
|
|
116
|
+
if (supportsGeneratedSyncWatchers) {
|
|
117
|
+
scripts.dev = getDevScript(packageManager, compoundPersistenceEnabled, templateId);
|
|
118
|
+
}
|
|
104
119
|
if (withWpEnv) {
|
|
105
120
|
scripts["wp-env:start"] = "wp-env start";
|
|
106
121
|
scripts["wp-env:stop"] = "wp-env stop";
|
|
@@ -123,10 +138,5 @@ export async function applyGeneratedProjectDxPackageJson({ compoundPersistenceEn
|
|
|
123
138
|
* scaffolded template.
|
|
124
139
|
*/
|
|
125
140
|
export function getPrimaryDevelopmentScript(templateId) {
|
|
126
|
-
return templateId
|
|
127
|
-
templateId === "interactivity" ||
|
|
128
|
-
templateId === "persistence" ||
|
|
129
|
-
templateId === "compound"
|
|
130
|
-
? "dev"
|
|
131
|
-
: "start";
|
|
141
|
+
return templateSupportsGeneratedSyncWatchers(templateId) ? "dev" : "start";
|
|
132
142
|
}
|
|
@@ -34,4 +34,4 @@ export declare function resolvePackageManagerId({ packageManager, yes, isInterac
|
|
|
34
34
|
* @param options Answer collection inputs including prompt callbacks and explicit overrides.
|
|
35
35
|
* @returns The normalized scaffold answers used for rendering and file generation.
|
|
36
36
|
*/
|
|
37
|
-
export declare function collectScaffoldAnswers({ projectName, templateId, yes, dataStorageMode, namespace, persistencePolicy, phpPrefix, promptText, textDomain, }: CollectScaffoldAnswersOptions): Promise<ScaffoldAnswers>;
|
|
37
|
+
export declare function collectScaffoldAnswers({ projectName, templateId, yes, dataStorageMode, namespace, persistencePolicy, phpPrefix, promptText, queryPostType, textDomain, }: CollectScaffoldAnswersOptions): Promise<ScaffoldAnswers>;
|
|
@@ -37,11 +37,32 @@ export function getDefaultAnswers(projectName, templateId) {
|
|
|
37
37
|
namespace: slugDefault,
|
|
38
38
|
persistencePolicy: templateId === 'persistence' ? 'authenticated' : undefined,
|
|
39
39
|
phpPrefix: toSnakeCase(slugDefault),
|
|
40
|
+
queryPostType: templateId === 'query-loop' ? 'post' : undefined,
|
|
40
41
|
slug: slugDefault,
|
|
41
42
|
textDomain: slugDefault,
|
|
42
43
|
title: toTitleCase(slugDefault),
|
|
43
44
|
};
|
|
44
45
|
}
|
|
46
|
+
function validateQueryPostType(value) {
|
|
47
|
+
const normalizedValue = value.trim().toLowerCase();
|
|
48
|
+
if (normalizedValue.length === 0) {
|
|
49
|
+
return 'Query post type is required.';
|
|
50
|
+
}
|
|
51
|
+
if (!/^[a-z0-9_-]{1,20}$/u.test(normalizedValue)) {
|
|
52
|
+
return 'Query post type must be lowercase, 1-20 chars, and only a-z, 0-9, "_" or "-".';
|
|
53
|
+
}
|
|
54
|
+
return true;
|
|
55
|
+
}
|
|
56
|
+
function normalizeQueryPostType(value) {
|
|
57
|
+
if (typeof value !== 'string') {
|
|
58
|
+
return undefined;
|
|
59
|
+
}
|
|
60
|
+
const normalizedValue = value.trim().toLowerCase();
|
|
61
|
+
if (validateQueryPostType(normalizedValue) !== true) {
|
|
62
|
+
throw new Error('Query post type must be lowercase, 1-20 chars, and only a-z, 0-9, "_" or "-".');
|
|
63
|
+
}
|
|
64
|
+
return normalizedValue;
|
|
65
|
+
}
|
|
45
66
|
function normalizeTemplateSelection(templateId) {
|
|
46
67
|
return templateId === WORKSPACE_TEMPLATE_ALIAS
|
|
47
68
|
? OFFICIAL_WORKSPACE_TEMPLATE_PACKAGE
|
|
@@ -96,7 +117,7 @@ export async function resolvePackageManagerId({ packageManager, yes = false, isI
|
|
|
96
117
|
* @param options Answer collection inputs including prompt callbacks and explicit overrides.
|
|
97
118
|
* @returns The normalized scaffold answers used for rendering and file generation.
|
|
98
119
|
*/
|
|
99
|
-
export async function collectScaffoldAnswers({ projectName, templateId, yes = false, dataStorageMode, namespace, persistencePolicy, phpPrefix, promptText, textDomain, }) {
|
|
120
|
+
export async function collectScaffoldAnswers({ projectName, templateId, yes = false, dataStorageMode, namespace, persistencePolicy, phpPrefix, promptText, queryPostType, textDomain, }) {
|
|
100
121
|
const defaults = getDefaultAnswers(projectName, templateId);
|
|
101
122
|
if (yes) {
|
|
102
123
|
const identifiers = resolveScaffoldIdentifiers({
|
|
@@ -111,6 +132,7 @@ export async function collectScaffoldAnswers({ projectName, templateId, yes = fa
|
|
|
111
132
|
namespace: identifiers.namespace,
|
|
112
133
|
persistencePolicy: persistencePolicy ?? defaults.persistencePolicy,
|
|
113
134
|
phpPrefix: identifiers.phpPrefix,
|
|
135
|
+
queryPostType: normalizeQueryPostType(queryPostType ?? defaults.queryPostType),
|
|
114
136
|
textDomain: identifiers.textDomain,
|
|
115
137
|
};
|
|
116
138
|
}
|
|
@@ -130,6 +152,9 @@ export async function collectScaffoldAnswers({ projectName, templateId, yes = fa
|
|
|
130
152
|
namespace: identifiers.namespace,
|
|
131
153
|
persistencePolicy: persistencePolicy ?? defaults.persistencePolicy,
|
|
132
154
|
phpPrefix: identifiers.phpPrefix,
|
|
155
|
+
queryPostType: templateId === 'query-loop'
|
|
156
|
+
? normalizeQueryPostType(await promptText('Query post type', queryPostType ?? defaults.queryPostType ?? 'post', validateQueryPostType))
|
|
157
|
+
: normalizeQueryPostType(queryPostType ?? defaults.queryPostType),
|
|
133
158
|
slug: identifiers.slug,
|
|
134
159
|
textDomain: identifiers.textDomain,
|
|
135
160
|
title: await promptText('Block title', toTitleCase(identifiers.slug)),
|
|
@@ -37,6 +37,13 @@ export function buildReadme(templateId, variables, packageManager, { withMigrati
|
|
|
37
37
|
const migrationSection = withMigrationUi
|
|
38
38
|
? `## Migration UI\n\nThis scaffold already includes an initialized migration workspace at \`v1\`, generated deprecated/runtime artifacts, and an editor-embedded migration dashboard. Migration versions are schema lineage labels and are separate from your package or plugin release version. Use the existing CLI commands to snapshot, diff, scaffold, verify, and fuzz future schema changes.\n\n\`\`\`bash\n${formatRunScript(packageManager, 'migration:doctor')}\n${formatRunScript(packageManager, 'migration:verify')}\n${formatRunScript(packageManager, 'migration:fuzz')}\n\`\`\`\n\nRun \`migration:init\` only when retrofitting migration support into an older project that was not scaffolded with \`--with-migration-ui\`.`
|
|
39
39
|
: '';
|
|
40
|
+
const advancedSyncSection = optionalOnboardingSteps.length > 0
|
|
41
|
+
? `## Advanced Sync\n\n\`\`\`bash\n${optionalOnboardingSteps.join('\n')}\n\`\`\`\n\n${getOptionalOnboardingNote(packageManager, templateId, {
|
|
42
|
+
compoundPersistenceEnabled,
|
|
43
|
+
})}`
|
|
44
|
+
: `## Artifact Refresh\n\n${getOptionalOnboardingNote(packageManager, templateId, {
|
|
45
|
+
compoundPersistenceEnabled,
|
|
46
|
+
})}`;
|
|
40
47
|
return `# ${variables.title}
|
|
41
48
|
|
|
42
49
|
${variables.description}
|
|
@@ -63,15 +70,7 @@ ${formatRunScript(packageManager, 'build')}
|
|
|
63
70
|
${formatRunScript(packageManager, 'typecheck')}
|
|
64
71
|
\`\`\`
|
|
65
72
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
\`\`\`bash
|
|
69
|
-
${optionalOnboardingSteps.join('\n')}
|
|
70
|
-
\`\`\`
|
|
71
|
-
|
|
72
|
-
${getOptionalOnboardingNote(packageManager, templateId, {
|
|
73
|
-
compoundPersistenceEnabled,
|
|
74
|
-
})}
|
|
73
|
+
${advancedSyncSection}
|
|
75
74
|
|
|
76
75
|
## Before First Commit
|
|
77
76
|
|
|
@@ -13,6 +13,9 @@ function templateHasPersistenceSync(templateId, { compoundPersistenceEnabled = f
|
|
|
13
13
|
* Returns the optional sync script names to suggest for a template.
|
|
14
14
|
*/
|
|
15
15
|
export function getOptionalSyncScriptNames(templateId, options = {}) {
|
|
16
|
+
if (templateId === "query-loop") {
|
|
17
|
+
return [];
|
|
18
|
+
}
|
|
16
19
|
const availableScripts = new Set(options.availableScripts ?? []);
|
|
17
20
|
if (availableScripts.has("sync")) {
|
|
18
21
|
return ["sync"];
|
|
@@ -37,6 +40,9 @@ export function getOptionalOnboardingSteps(packageManager, templateId, options =
|
|
|
37
40
|
* Returns the quick-start note explaining the scaffold's primary local loop.
|
|
38
41
|
*/
|
|
39
42
|
export function getQuickStartWorkflowNote(packageManager, templateId = "basic", options = {}) {
|
|
43
|
+
if (templateId === "query-loop") {
|
|
44
|
+
return `${formatRunScript(packageManager, "start")} runs the editor build/watch loop that registers your Query Loop variation in the block editor. This scaffold is editor-facing by design: update \`src/index.ts\` when you want to change the variation namespace, default query, allowed controls, or the minimal inline starter layout, update \`src/patterns/*.php\` when you want richer connected layout presets in the inserter, use \`src/query-extension.ts\` when the variation needs custom query params or optional editor-side hooks, and mirror frontend/editor preview query mapping in \`inc/query-runtime.php\`.`;
|
|
45
|
+
}
|
|
40
46
|
const developmentScript = getPrimaryDevelopmentScript(templateId);
|
|
41
47
|
const devCommand = formatRunScript(packageManager, developmentScript);
|
|
42
48
|
const startCommand = formatRunScript(packageManager, "start");
|
|
@@ -55,6 +61,9 @@ export function getQuickStartWorkflowNote(packageManager, templateId = "basic",
|
|
|
55
61
|
* Returns the onboarding note explaining when manual sync is optional.
|
|
56
62
|
*/
|
|
57
63
|
export function getOptionalOnboardingNote(packageManager, templateId = "basic", options = {}) {
|
|
64
|
+
if (templateId === "query-loop") {
|
|
65
|
+
return `This scaffold does not generate \`block.json\` or Typia manifests. Edit \`src/index.ts\` to change the variation contract, edit \`src/patterns/*.php\` when you want richer connected layouts beyond the inline fallback, edit \`src/query-extension.ts\` when you need variation-specific query params or custom editor hooks, and edit \`inc/query-runtime.php\` when those params need frontend or editor preview parity. Then rerun ${formatRunScript(packageManager, "build")}, ${formatRunScript(packageManager, "start")}, or ${formatRunScript(packageManager, "typecheck")} as needed.`;
|
|
66
|
+
}
|
|
58
67
|
const optionalSyncScripts = getOptionalSyncScriptNames(templateId, options);
|
|
59
68
|
const hasUnifiedSync = optionalSyncScripts.includes("sync");
|
|
60
69
|
const syncSteps = optionalSyncScripts.map((scriptName) => formatRunScript(packageManager, scriptName));
|
|
@@ -100,6 +109,9 @@ export function getInitialCommitNote() {
|
|
|
100
109
|
* Returns source-of-truth guidance for generated artifacts by template mode.
|
|
101
110
|
*/
|
|
102
111
|
export function getTemplateSourceOfTruthNote(templateId, { compoundPersistenceEnabled = false } = {}) {
|
|
112
|
+
if (templateId === "query-loop") {
|
|
113
|
+
return "`src/index.ts` remains the source of truth for the Query Loop variation name, default query attributes, `allowedControls`, and the minimal inline starter `innerBlocks`. Use `src/patterns/*.php` for richer connected layout presets that stay tied to the same variation namespace, use `src/query-extension.ts` for custom query seed values or optional editor-only hook registration, and use `inc/query-runtime.php` to keep frontend and editor preview query mapping aligned for those custom keys. The generated plugin bootstrap should stay focused on script registration, pattern loading, and explicit runtime glue for the variation.";
|
|
114
|
+
}
|
|
103
115
|
if (templateId === "compound") {
|
|
104
116
|
const compoundBase = "`src/blocks/*/types.ts` files remain the source of truth for each block's `block.json`, `typia.manifest.json`, and `typia-validator.php`. Fresh scaffolds include starter `typia.manifest.json` files so editor imports resolve before the first sync.";
|
|
105
117
|
if (compoundPersistenceEnabled) {
|
|
@@ -73,7 +73,13 @@ export function getTemplateVariables(templateId, answers) {
|
|
|
73
73
|
dataStorageMode,
|
|
74
74
|
dashCase: slug,
|
|
75
75
|
description,
|
|
76
|
+
descriptionJson: JSON.stringify(description),
|
|
76
77
|
frontendCssClassName: buildFrontendCssClassName(cssClassName),
|
|
78
|
+
queryAllowedControlsJson: JSON.stringify([], null, 2),
|
|
79
|
+
queryPostType: answers.queryPostType?.trim() || 'post',
|
|
80
|
+
queryPostTypeJson: JSON.stringify(answers.queryPostType?.trim() || 'post'),
|
|
81
|
+
queryVariationNamespace: `${namespace}/${slug}`,
|
|
82
|
+
queryVariationNamespaceJson: JSON.stringify(`${namespace}/${slug}`),
|
|
77
83
|
isAuthenticatedPersistencePolicy: persistencePolicy === 'authenticated' ? 'true' : 'false',
|
|
78
84
|
isPublicPersistencePolicy: persistencePolicy === 'public' ? 'true' : 'false',
|
|
79
85
|
bootstrapCredentialDeclarations: persistencePolicy === 'public'
|
|
@@ -15,6 +15,7 @@ export interface ScaffoldAnswers {
|
|
|
15
15
|
persistencePolicy?: PersistencePolicy;
|
|
16
16
|
/** Snake_case PHP symbol prefix used for generated functions, constants, and keys. */
|
|
17
17
|
phpPrefix?: string;
|
|
18
|
+
queryPostType?: string;
|
|
18
19
|
slug: string;
|
|
19
20
|
/** Kebab-case WordPress text domain used in block metadata and i18n strings. */
|
|
20
21
|
textDomain?: string;
|
|
@@ -46,6 +47,7 @@ export interface ScaffoldTemplateVariables extends Record<string, string> {
|
|
|
46
47
|
dashCase: string;
|
|
47
48
|
dataStorageMode: DataStorageMode;
|
|
48
49
|
description: string;
|
|
50
|
+
descriptionJson: string;
|
|
49
51
|
frontendCssClassName: string;
|
|
50
52
|
keyword: string;
|
|
51
53
|
namespace: string;
|
|
@@ -53,6 +55,11 @@ export interface ScaffoldTemplateVariables extends Record<string, string> {
|
|
|
53
55
|
pascalCase: string;
|
|
54
56
|
phpPrefix: string;
|
|
55
57
|
phpPrefixUpper: string;
|
|
58
|
+
queryAllowedControlsJson: string;
|
|
59
|
+
queryPostTypeJson: string;
|
|
60
|
+
queryPostType: string;
|
|
61
|
+
queryVariationNamespace: string;
|
|
62
|
+
queryVariationNamespaceJson: string;
|
|
56
63
|
isAuthenticatedPersistencePolicy: "false" | "true";
|
|
57
64
|
isPublicPersistencePolicy: "false" | "true";
|
|
58
65
|
bootstrapCredentialDeclarations: string;
|
|
@@ -106,6 +113,7 @@ export interface CollectScaffoldAnswersOptions {
|
|
|
106
113
|
projectName: string;
|
|
107
114
|
promptText?: (message: string, defaultValue: string, validate?: (value: string) => true | string) => Promise<string>;
|
|
108
115
|
persistencePolicy?: PersistencePolicy;
|
|
116
|
+
queryPostType?: string;
|
|
109
117
|
textDomain?: string;
|
|
110
118
|
templateId: string;
|
|
111
119
|
withTestPreset?: boolean;
|
|
@@ -22,6 +22,10 @@ export declare const BUILTIN_TEMPLATE_METADATA_DEFAULTS: Readonly<{
|
|
|
22
22
|
category: "widgets";
|
|
23
23
|
icon: "screenoptions";
|
|
24
24
|
}>;
|
|
25
|
+
"query-loop": Readonly<{
|
|
26
|
+
category: "widgets";
|
|
27
|
+
icon: "query-pagination";
|
|
28
|
+
}>;
|
|
25
29
|
}>;
|
|
26
30
|
/**
|
|
27
31
|
* Shared hidden child block metadata defaults for compound scaffolds.
|
|
@@ -56,6 +60,9 @@ export declare function getBuiltInTemplateMetadataDefaults(templateId: keyof typ
|
|
|
56
60
|
}> | Readonly<{
|
|
57
61
|
category: "widgets";
|
|
58
62
|
icon: "screenoptions";
|
|
63
|
+
}> | Readonly<{
|
|
64
|
+
category: "widgets";
|
|
65
|
+
icon: "query-pagination";
|
|
59
66
|
}>;
|
|
60
67
|
/**
|
|
61
68
|
* Checks whether a template id points at a removed built-in scaffold.
|
|
@@ -22,6 +22,10 @@ export const BUILTIN_TEMPLATE_METADATA_DEFAULTS = Object.freeze({
|
|
|
22
22
|
category: "widgets",
|
|
23
23
|
icon: "screenoptions",
|
|
24
24
|
}),
|
|
25
|
+
"query-loop": Object.freeze({
|
|
26
|
+
category: "widgets",
|
|
27
|
+
icon: "query-pagination",
|
|
28
|
+
}),
|
|
25
29
|
});
|
|
26
30
|
/**
|
|
27
31
|
* Shared hidden child block metadata defaults for compound scaffolds.
|
|
@@ -14,7 +14,7 @@ export declare const SHARED_MIGRATION_UI_TEMPLATE_ROOT: string;
|
|
|
14
14
|
export declare const SHARED_WORKSPACE_TEMPLATE_ROOT: string;
|
|
15
15
|
export declare const SHARED_TEST_PRESET_TEMPLATE_ROOT: string;
|
|
16
16
|
export declare const SHARED_WP_ENV_PRESET_TEMPLATE_ROOT: string;
|
|
17
|
-
export declare const BUILTIN_TEMPLATE_IDS: readonly ["basic", "interactivity", "persistence", "compound"];
|
|
17
|
+
export declare const BUILTIN_TEMPLATE_IDS: readonly ["basic", "interactivity", "persistence", "compound", "query-loop"];
|
|
18
18
|
export declare const OFFICIAL_WORKSPACE_TEMPLATE_PACKAGE = "@wp-typia/create-workspace-template";
|
|
19
19
|
export type BuiltInTemplateId = (typeof BUILTIN_TEMPLATE_IDS)[number];
|
|
20
20
|
export type PersistencePolicy = "authenticated" | "public";
|
|
@@ -40,7 +40,13 @@ export const SHARED_MIGRATION_UI_TEMPLATE_ROOT = path.join(SHARED_TEMPLATE_ROOT,
|
|
|
40
40
|
export const SHARED_WORKSPACE_TEMPLATE_ROOT = path.join(SHARED_TEMPLATE_ROOT, "workspace");
|
|
41
41
|
export const SHARED_TEST_PRESET_TEMPLATE_ROOT = path.join(SHARED_PRESET_TEMPLATE_ROOT, "test-preset");
|
|
42
42
|
export const SHARED_WP_ENV_PRESET_TEMPLATE_ROOT = path.join(SHARED_PRESET_TEMPLATE_ROOT, "wp-env");
|
|
43
|
-
export const BUILTIN_TEMPLATE_IDS = [
|
|
43
|
+
export const BUILTIN_TEMPLATE_IDS = [
|
|
44
|
+
"basic",
|
|
45
|
+
"interactivity",
|
|
46
|
+
"persistence",
|
|
47
|
+
"compound",
|
|
48
|
+
"query-loop",
|
|
49
|
+
];
|
|
44
50
|
export const OFFICIAL_WORKSPACE_TEMPLATE_PACKAGE = "@wp-typia/create-workspace-template";
|
|
45
51
|
export const TEMPLATE_REGISTRY = Object.freeze([
|
|
46
52
|
{
|
|
@@ -71,6 +77,13 @@ export const TEMPLATE_REGISTRY = Object.freeze([
|
|
|
71
77
|
features: ["InnerBlocks", "Hidden child blocks", "Optional persistence layer"],
|
|
72
78
|
templateDir: path.join(TEMPLATE_ROOT, "compound"),
|
|
73
79
|
},
|
|
80
|
+
{
|
|
81
|
+
id: "query-loop",
|
|
82
|
+
description: "A Query Loop block variation scaffold with stable namespace-based identity, inline starter layout, connected pattern presets, custom query seams, and runtime parity hooks",
|
|
83
|
+
defaultCategory: getBuiltInTemplateMetadataDefaults("query-loop").category,
|
|
84
|
+
features: ["core/query variation", "Default innerBlocks", "Connected patterns", "Custom query hooks", "Runtime parity hooks", "Allowed controls"],
|
|
85
|
+
templateDir: path.join(TEMPLATE_ROOT, "query-loop"),
|
|
86
|
+
},
|
|
74
87
|
{
|
|
75
88
|
id: OFFICIAL_WORKSPACE_TEMPLATE_PACKAGE,
|
|
76
89
|
description: "The official empty workspace template that powers `wp-typia add ...` workflows",
|
package/package.json
CHANGED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
if ( ! defined( 'ABSPATH' ) ) {
|
|
3
|
+
exit;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
function {{phpPrefix}}_get_query_loop_variation_name() {
|
|
7
|
+
return '{{namespace}}/{{slug}}';
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
function {{phpPrefix}}_get_query_loop_variation_marker_key() {
|
|
11
|
+
return 'wpTypiaVariation';
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function {{phpPrefix}}_extract_query_loop_request_query( WP_REST_Request $request ) {
|
|
15
|
+
$params = $request->get_params();
|
|
16
|
+
|
|
17
|
+
if ( isset( $params['query'] ) && is_array( $params['query'] ) ) {
|
|
18
|
+
return $params['query'];
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return is_array( $params ) ? $params : array();
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function {{phpPrefix}}_map_query_loop_custom_query_vars( array $query_vars, array $source_query ) {
|
|
25
|
+
unset( $query_vars[ {{phpPrefix}}_get_query_loop_variation_marker_key() ] );
|
|
26
|
+
|
|
27
|
+
$allowed_custom_query_values = array(
|
|
28
|
+
// 'featuredOnly' => isset( $source_query['featuredOnly'] ) ? (bool) $source_query['featuredOnly'] : null,
|
|
29
|
+
// 'eventStatus' => isset( $source_query['eventStatus'] ) ? sanitize_text_field( $source_query['eventStatus'] ) : null,
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
// Mirror only known custom query keys from `src/query-extension.ts` here when
|
|
33
|
+
// they should affect frontend rendering or editor preview requests. Sanitize
|
|
34
|
+
// and cast values before copying them into WP_Query vars; do not merge the
|
|
35
|
+
// raw source query wholesale.
|
|
36
|
+
foreach ( $allowed_custom_query_values as $key => $value ) {
|
|
37
|
+
if ( null === $value ) {
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
$query_vars[ $key ] = $value;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return $query_vars;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function {{phpPrefix}}_filter_query_loop_block_query_vars( $query_vars, $block, $page ) {
|
|
48
|
+
if ( ! is_array( $query_vars ) ) {
|
|
49
|
+
return $query_vars;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
$attrs = is_array( $block ) && isset( $block['attrs'] ) && is_array( $block['attrs'] )
|
|
53
|
+
? $block['attrs']
|
|
54
|
+
: array();
|
|
55
|
+
$namespace = isset( $attrs['namespace'] ) && is_string( $attrs['namespace'] )
|
|
56
|
+
? $attrs['namespace']
|
|
57
|
+
: null;
|
|
58
|
+
$source_query = isset( $attrs['query'] ) && is_array( $attrs['query'] )
|
|
59
|
+
? $attrs['query']
|
|
60
|
+
: array();
|
|
61
|
+
|
|
62
|
+
if ( {{phpPrefix}}_get_query_loop_variation_name() !== $namespace ) {
|
|
63
|
+
return $query_vars;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return {{phpPrefix}}_map_query_loop_custom_query_vars( $query_vars, $source_query );
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function {{phpPrefix}}_filter_query_loop_editor_preview_query_vars( $query_vars, $request ) {
|
|
70
|
+
if ( ! is_array( $query_vars ) || ! $request instanceof WP_REST_Request ) {
|
|
71
|
+
return $query_vars;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
$source_query = {{phpPrefix}}_extract_query_loop_request_query( $request );
|
|
75
|
+
$marker_key = {{phpPrefix}}_get_query_loop_variation_marker_key();
|
|
76
|
+
$variation_name = isset( $source_query[ $marker_key ] ) && is_string( $source_query[ $marker_key ] )
|
|
77
|
+
? $source_query[ $marker_key ]
|
|
78
|
+
: null;
|
|
79
|
+
|
|
80
|
+
if ( {{phpPrefix}}_get_query_loop_variation_name() !== $variation_name ) {
|
|
81
|
+
return $query_vars;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
return {{phpPrefix}}_map_query_loop_custom_query_vars( $query_vars, $source_query );
|
|
85
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "{{slug}}",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"packageManager": "bun@1.3.11",
|
|
5
|
+
"description": "{{description}}",
|
|
6
|
+
"author": "{{author}}",
|
|
7
|
+
"license": "GPL-2.0-or-later",
|
|
8
|
+
"main": "build/index.js",
|
|
9
|
+
"scripts": {
|
|
10
|
+
"build": "wp-scripts build --experimental-modules",
|
|
11
|
+
"start": "wp-scripts start --experimental-modules",
|
|
12
|
+
"dev": "wp-scripts start --experimental-modules",
|
|
13
|
+
"lint:js": "wp-scripts lint-js",
|
|
14
|
+
"lint": "bun run lint:js",
|
|
15
|
+
"format": "wp-scripts format",
|
|
16
|
+
"typecheck": "tsc --noEmit"
|
|
17
|
+
},
|
|
18
|
+
"devDependencies": {
|
|
19
|
+
"@wp-typia/block-types": "{{blockTypesPackageVersion}}",
|
|
20
|
+
"@types/wordpress__block-editor": "^11.5.17",
|
|
21
|
+
"@types/wordpress__blocks": "^12.5.18",
|
|
22
|
+
"@wordpress/browserslist-config": "^6.42.0",
|
|
23
|
+
"@wordpress/scripts": "^30.22.0",
|
|
24
|
+
"eslint-plugin-jsx-a11y": "^6.10.2",
|
|
25
|
+
"prettier": "3.8.2",
|
|
26
|
+
"typescript": "^5.9.2"
|
|
27
|
+
},
|
|
28
|
+
"dependencies": {
|
|
29
|
+
"@wordpress/blocks": "^15.2.0",
|
|
30
|
+
"@wordpress/i18n": "^6.2.0"
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
if ( ! defined( 'ABSPATH' ) ) {
|
|
3
|
+
exit;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
$content = sprintf(
|
|
7
|
+
<<<'HTML'
|
|
8
|
+
<!-- wp:query {"namespace":"{{namespace}}/{{slug}}","query":{"inherit":false,"postType":"{{queryPostType}}","perPage":6,"order":"desc","orderBy":"date","wpTypiaVariation":"{{namespace}}/{{slug}}"},"displayLayout":{"type":"grid","columns":3}} -->
|
|
9
|
+
<div class="wp-block-query">
|
|
10
|
+
<!-- wp:post-template -->
|
|
11
|
+
<!-- wp:group {"style":{"spacing":{"blockGap":"0.75rem","padding":{"top":"1rem","right":"1rem","bottom":"1rem","left":"1rem"}}},"layout":{"type":"constrained"}} -->
|
|
12
|
+
<div class="wp-block-group" style="padding-top:1rem;padding-right:1rem;padding-bottom:1rem;padding-left:1rem">
|
|
13
|
+
<!-- wp:post-featured-image /-->
|
|
14
|
+
<!-- wp:post-title {"isLink":true} /-->
|
|
15
|
+
<!-- wp:post-excerpt /-->
|
|
16
|
+
</div>
|
|
17
|
+
<!-- /wp:group -->
|
|
18
|
+
<!-- /wp:post-template -->
|
|
19
|
+
|
|
20
|
+
<!-- wp:query-pagination -->
|
|
21
|
+
<!-- wp:query-pagination-previous /-->
|
|
22
|
+
<!-- wp:query-pagination-numbers /-->
|
|
23
|
+
<!-- wp:query-pagination-next /-->
|
|
24
|
+
<!-- /wp:query-pagination -->
|
|
25
|
+
|
|
26
|
+
<!-- wp:query-no-results -->
|
|
27
|
+
<!-- wp:paragraph -->
|
|
28
|
+
<p>%s</p>
|
|
29
|
+
<!-- /wp:paragraph -->
|
|
30
|
+
<!-- /wp:query-no-results -->
|
|
31
|
+
</div>
|
|
32
|
+
<!-- /wp:query -->
|
|
33
|
+
HTML,
|
|
34
|
+
esc_html__( 'No items matched this preset yet.', '{{textDomain}}' )
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
register_block_pattern(
|
|
38
|
+
'{{namespace}}/{{slug}}-grid',
|
|
39
|
+
array(
|
|
40
|
+
'title' => __( '{{title}} Grid', '{{textDomain}}' ),
|
|
41
|
+
'description' => __( 'A connected grid layout preset for the {{title}} Query Loop variation.', '{{textDomain}}' ),
|
|
42
|
+
'categories' => array( '{{slug}}-query-loop' ),
|
|
43
|
+
'blockTypes' => array( 'core/query' ),
|
|
44
|
+
'postTypes' => array( '{{queryPostType}}' ),
|
|
45
|
+
'inserter' => true,
|
|
46
|
+
'viewportWidth' => 1280,
|
|
47
|
+
'content' => $content,
|
|
48
|
+
)
|
|
49
|
+
);
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
if ( ! defined( 'ABSPATH' ) ) {
|
|
3
|
+
exit;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
$content = sprintf(
|
|
7
|
+
<<<'HTML'
|
|
8
|
+
<!-- wp:query {"namespace":"{{namespace}}/{{slug}}","query":{"inherit":false,"postType":"{{queryPostType}}","perPage":4,"order":"desc","orderBy":"date","wpTypiaVariation":"{{namespace}}/{{slug}}"}} -->
|
|
9
|
+
<div class="wp-block-query">
|
|
10
|
+
<!-- wp:post-template -->
|
|
11
|
+
<!-- wp:group {"style":{"spacing":{"blockGap":"1rem","padding":{"top":"1.25rem","bottom":"1.25rem"}}},"layout":{"type":"constrained"}} -->
|
|
12
|
+
<div class="wp-block-group" style="padding-top:1.25rem;padding-bottom:1.25rem">
|
|
13
|
+
<!-- wp:post-title {"isLink":true} /-->
|
|
14
|
+
<!-- wp:post-date /-->
|
|
15
|
+
<!-- wp:post-excerpt {"moreText":"Continue reading"} /-->
|
|
16
|
+
</div>
|
|
17
|
+
<!-- /wp:group -->
|
|
18
|
+
<!-- /wp:post-template -->
|
|
19
|
+
|
|
20
|
+
<!-- wp:query-pagination -->
|
|
21
|
+
<!-- wp:query-pagination-previous /-->
|
|
22
|
+
<!-- wp:query-pagination-next /-->
|
|
23
|
+
<!-- /wp:query-pagination -->
|
|
24
|
+
|
|
25
|
+
<!-- wp:query-no-results -->
|
|
26
|
+
<!-- wp:paragraph -->
|
|
27
|
+
<p>%s</p>
|
|
28
|
+
<!-- /wp:paragraph -->
|
|
29
|
+
<!-- /wp:query-no-results -->
|
|
30
|
+
</div>
|
|
31
|
+
<!-- /wp:query -->
|
|
32
|
+
HTML,
|
|
33
|
+
esc_html__( 'No items matched this preset yet.', '{{textDomain}}' )
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
register_block_pattern(
|
|
37
|
+
'{{namespace}}/{{slug}}-list',
|
|
38
|
+
array(
|
|
39
|
+
'title' => __( '{{title}} List', '{{textDomain}}' ),
|
|
40
|
+
'description' => __( 'A connected list layout preset for the {{title}} Query Loop variation.', '{{textDomain}}' ),
|
|
41
|
+
'categories' => array( '{{slug}}-query-loop' ),
|
|
42
|
+
'blockTypes' => array( 'core/query' ),
|
|
43
|
+
'postTypes' => array( '{{queryPostType}}' ),
|
|
44
|
+
'inserter' => true,
|
|
45
|
+
'viewportWidth' => 1280,
|
|
46
|
+
'content' => $content,
|
|
47
|
+
)
|
|
48
|
+
);
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
export type QueryLoopEditorExtensionContext = {
|
|
2
|
+
variationName: string;
|
|
3
|
+
};
|
|
4
|
+
|
|
5
|
+
export type QueryLoopCustomQuerySeed = Record<string, unknown>;
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Extend the generated Query Loop variation with variation-specific query params.
|
|
9
|
+
*
|
|
10
|
+
* Add custom keys here only when the variation should always seed them. Runtime
|
|
11
|
+
* parity hooks in `inc/query-runtime.php` can read the same keys later from the
|
|
12
|
+
* Query Loop `query` object.
|
|
13
|
+
*/
|
|
14
|
+
export function getQueryLoopCustomQuerySeed(): QueryLoopCustomQuerySeed {
|
|
15
|
+
return {};
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Add extra inspector controls by key when your custom query seed needs them.
|
|
20
|
+
*
|
|
21
|
+
* Keep the generated defaults in `src/index.ts` and return only the additional
|
|
22
|
+
* control ids that your variation-specific query params rely on.
|
|
23
|
+
*/
|
|
24
|
+
export function getQueryLoopCustomAllowedControls(): string[] {
|
|
25
|
+
return [];
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Register optional editor-only extension hooks for custom Query Loop params.
|
|
30
|
+
*
|
|
31
|
+
* This stays a no-op by default. When you need custom inspector UI, add your
|
|
32
|
+
* `editor.BlockEdit` filters or other editor hooks here so `src/index.ts` can
|
|
33
|
+
* keep variation registration focused on identity and default query values. If
|
|
34
|
+
* those hooks introduce frontend-affecting query params, mirror them in
|
|
35
|
+
* `inc/query-runtime.php` so editor preview and frontend rendering stay aligned.
|
|
36
|
+
*/
|
|
37
|
+
export function registerQueryLoopEditorExtensions(
|
|
38
|
+
_context: QueryLoopEditorExtensionContext,
|
|
39
|
+
): void {
|
|
40
|
+
// Add optional editor hooks here when this variation introduces custom query UI.
|
|
41
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
const path = require("node:path");
|
|
2
|
+
const defaultConfig = require("@wordpress/scripts/config/webpack.config");
|
|
3
|
+
|
|
4
|
+
const queryLoopEntry = {
|
|
5
|
+
index: path.resolve(process.cwd(), "src/index.ts"),
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
module.exports = Array.isArray(defaultConfig)
|
|
9
|
+
? defaultConfig.map((config) => ({
|
|
10
|
+
...config,
|
|
11
|
+
entry: config?.output?.module ? config.entry : queryLoopEntry,
|
|
12
|
+
}))
|
|
13
|
+
: {
|
|
14
|
+
...defaultConfig,
|
|
15
|
+
entry: queryLoopEntry,
|
|
16
|
+
};
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
/**
|
|
3
|
+
* Plugin Name: {{title}}
|
|
4
|
+
* Description: {{description}}
|
|
5
|
+
* Version: 0.1.0
|
|
6
|
+
* Requires at least: 6.7
|
|
7
|
+
* Tested up to: 6.9
|
|
8
|
+
* Requires PHP: 8.0
|
|
9
|
+
* Author: {{author}}
|
|
10
|
+
* License: GPL-2.0-or-later
|
|
11
|
+
* License URI: https://www.gnu.org/licenses/gpl-2.0.html
|
|
12
|
+
* Text Domain: {{textDomain}}
|
|
13
|
+
* Domain Path: /languages
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
if ( ! defined( 'ABSPATH' ) ) {
|
|
17
|
+
exit;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
require_once __DIR__ . '/inc/query-runtime.php';
|
|
21
|
+
|
|
22
|
+
function {{phpPrefix}}_load_textdomain() {
|
|
23
|
+
load_plugin_textdomain(
|
|
24
|
+
'{{textDomain}}',
|
|
25
|
+
false,
|
|
26
|
+
dirname( plugin_basename( __FILE__ ) ) . '/languages'
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function {{phpPrefix}}_register_query_loop_pattern_category() {
|
|
31
|
+
if ( ! function_exists( 'register_block_pattern_category' ) ) {
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
register_block_pattern_category(
|
|
36
|
+
'{{slug}}-query-loop',
|
|
37
|
+
array(
|
|
38
|
+
'label' => __( '{{title}} Query Loop', '{{textDomain}}' ),
|
|
39
|
+
)
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function {{phpPrefix}}_register_query_loop_patterns() {
|
|
44
|
+
if ( ! function_exists( 'register_block_pattern' ) ) {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
foreach ( glob( __DIR__ . '/src/patterns/*.php' ) ?: array() as $pattern_module ) {
|
|
49
|
+
require $pattern_module;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function {{phpPrefix}}_register_query_loop_variation_script() {
|
|
54
|
+
$script_path = __DIR__ . '/build/index.js';
|
|
55
|
+
$script_asset_path = __DIR__ . '/build/index.asset.php';
|
|
56
|
+
|
|
57
|
+
if ( ! file_exists( $script_path ) || ! file_exists( $script_asset_path ) ) {
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
$asset = require $script_asset_path;
|
|
62
|
+
$handle = '{{phpPrefix}}_query_loop_variation';
|
|
63
|
+
|
|
64
|
+
wp_register_script(
|
|
65
|
+
$handle,
|
|
66
|
+
plugins_url( 'build/index.js', __FILE__ ),
|
|
67
|
+
is_array( $asset ) && isset( $asset['dependencies'] ) ? $asset['dependencies'] : array(),
|
|
68
|
+
is_array( $asset ) && isset( $asset['version'] ) ? $asset['version'] : filemtime( $script_path ),
|
|
69
|
+
true
|
|
70
|
+
);
|
|
71
|
+
wp_set_script_translations( $handle, '{{textDomain}}', __DIR__ . '/languages' );
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function {{phpPrefix}}_enqueue_query_loop_variation_script() {
|
|
75
|
+
{{phpPrefix}}_register_query_loop_variation_script();
|
|
76
|
+
wp_enqueue_script( '{{phpPrefix}}_query_loop_variation' );
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
add_action( 'init', '{{phpPrefix}}_load_textdomain' );
|
|
80
|
+
add_action( 'init', '{{phpPrefix}}_register_query_loop_pattern_category' );
|
|
81
|
+
add_action( 'init', '{{phpPrefix}}_register_query_loop_patterns', 20 );
|
|
82
|
+
add_action( 'enqueue_block_editor_assets', '{{phpPrefix}}_enqueue_query_loop_variation_script' );
|
|
83
|
+
add_filter( 'query_loop_block_query_vars', '{{phpPrefix}}_filter_query_loop_block_query_vars', 10, 3 );
|
|
84
|
+
add_filter( 'rest_{{queryPostType}}_query', '{{phpPrefix}}_filter_query_loop_editor_preview_query_vars', 10, 2 );
|