itmar-block-packages 1.9.0 → 1.10.1
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/README.md +8 -0
- package/build/index.asset.php +1 -1
- package/build/index.js +3 -3
- package/package.json +1 -1
- package/src/BrockInserter.js +247 -0
- package/src/MasonryControl.js +125 -0
- package/src/SwiperControl.js +265 -0
- package/src/customFooks.js +1 -0
- package/src/index.js +9 -0
- package/src/wordpressApi.js +230 -38
package/src/wordpressApi.js
CHANGED
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
ToggleControl,
|
|
7
7
|
} from "@wordpress/components";
|
|
8
8
|
import apiFetch from "@wordpress/api-fetch";
|
|
9
|
+
import { addQueryArgs } from "@wordpress/url";
|
|
9
10
|
|
|
10
11
|
//const _ = require("lodash");
|
|
11
12
|
|
|
@@ -68,8 +69,9 @@ const ChoiceControl = (props) => {
|
|
|
68
69
|
const fetchData = async () => {
|
|
69
70
|
try {
|
|
70
71
|
const fetchChoices = await fetchFunction(selectedSlug);
|
|
71
|
-
|
|
72
72
|
setChoices(fetchChoices);
|
|
73
|
+
//指定の投稿タイプに含まれないフィールドを削除する
|
|
74
|
+
pruneChoiceItemsByObjectKeys(fetchChoices[0], choiceItems);
|
|
73
75
|
} catch (error) {
|
|
74
76
|
console.error("Error fetching data:", error.message);
|
|
75
77
|
}
|
|
@@ -90,22 +92,78 @@ const ChoiceControl = (props) => {
|
|
|
90
92
|
}
|
|
91
93
|
return setItems;
|
|
92
94
|
};
|
|
95
|
+
/**
|
|
96
|
+
* dataObj のキー一覧を「choiceItems と比較する形」に変換して Set で返す
|
|
97
|
+
* - 通常キー: そのまま
|
|
98
|
+
* - acf / meta: 子キーに `${parent}_` を付けたもの(例: acf_relate_url, meta_footnotes)
|
|
99
|
+
*/
|
|
100
|
+
function buildComparableKeySet(dataObj) {
|
|
101
|
+
const keySet = new Set();
|
|
102
|
+
|
|
103
|
+
if (!dataObj || typeof dataObj !== "object") return keySet;
|
|
104
|
+
|
|
105
|
+
for (const [key, val] of Object.entries(dataObj)) {
|
|
106
|
+
if (
|
|
107
|
+
(key === "acf" || key === "meta") &&
|
|
108
|
+
val &&
|
|
109
|
+
typeof val === "object" &&
|
|
110
|
+
!Array.isArray(val)
|
|
111
|
+
) {
|
|
112
|
+
for (const childKey of Object.keys(val)) {
|
|
113
|
+
keySet.add(`${key}_${childKey}`);
|
|
114
|
+
}
|
|
115
|
+
continue;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
keySet.add(key);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
return keySet;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* choiceItems を dataObj のキーに合わせて削除する
|
|
126
|
+
* - choiceItems が string 配列でも、{value: "..."} の配列でも動くようにしてあります
|
|
127
|
+
*/
|
|
128
|
+
function pruneChoiceItemsByObjectKeys(dataObj, choiceItems) {
|
|
129
|
+
const validKeys = buildComparableKeySet(dataObj);
|
|
130
|
+
|
|
131
|
+
const getItemKey = (item) => {
|
|
132
|
+
if (typeof item === "string") return item;
|
|
133
|
+
if (item && typeof item === "object")
|
|
134
|
+
return item.value ?? item.key ?? item.name ?? "";
|
|
135
|
+
return "";
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
const next = (choiceItems ?? []).filter((item) =>
|
|
139
|
+
validKeys.has(getItemKey(item))
|
|
140
|
+
);
|
|
141
|
+
|
|
142
|
+
// ★ 配列の参照はそのまま、中身だけ置き換える
|
|
143
|
+
choiceItems.splice(0, choiceItems.length, ...next);
|
|
144
|
+
|
|
145
|
+
return choiceItems; // 必要なら返す
|
|
146
|
+
}
|
|
93
147
|
|
|
94
148
|
//階層化されたカスタムフィールドのフィールド名を表示する関数
|
|
95
149
|
let groupLabel = "";
|
|
96
|
-
const dispCustumFields = (obj, prefix = "", onChange) => {
|
|
150
|
+
const dispCustumFields = (obj, prefix = "", isImage = false, onChange) => {
|
|
97
151
|
return Object.entries(obj).map(([key, value]) => {
|
|
98
152
|
const fieldName = prefix ? `${prefix}.${key}` : key; //prefixはグループ名
|
|
99
153
|
|
|
100
154
|
const fieldLabel = key.replace(/^(meta_|acf_)/, "");
|
|
101
|
-
|
|
102
|
-
if (
|
|
155
|
+
//オブジェクトであって配列でないものがグループと考える
|
|
156
|
+
if (
|
|
157
|
+
typeof value === "object" &&
|
|
158
|
+
!Array.isArray(value) &&
|
|
159
|
+
value !== null
|
|
160
|
+
) {
|
|
103
161
|
groupLabel = `${fieldLabel}.`;
|
|
104
162
|
return (
|
|
105
163
|
<div className="group_area">
|
|
106
164
|
<div className="group_label">{fieldLabel}</div>
|
|
107
165
|
<div key={fieldName} className="field_group">
|
|
108
|
-
{dispCustumFields(value, fieldName, onChange)}
|
|
166
|
+
{dispCustumFields(value, fieldName, isImage, onChange)}
|
|
109
167
|
</div>
|
|
110
168
|
</div>
|
|
111
169
|
);
|
|
@@ -117,6 +175,7 @@ const ChoiceControl = (props) => {
|
|
|
117
175
|
{ value: "itmar/design-title", label: "itmar/design-title" },
|
|
118
176
|
{ value: "core/paragraph", label: "core/paragraph" },
|
|
119
177
|
{ value: "core/image", label: "core/image" },
|
|
178
|
+
{ value: "itmar/slide-mv", label: "itmar/slide-mv" },
|
|
120
179
|
];
|
|
121
180
|
return (
|
|
122
181
|
<div className="itmar_custom_field_set">
|
|
@@ -136,20 +195,23 @@ const ChoiceControl = (props) => {
|
|
|
136
195
|
props.onChange(newChoiceFields);
|
|
137
196
|
}}
|
|
138
197
|
/>
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
: `${
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
198
|
+
{!isImage && (
|
|
199
|
+
<ComboboxControl
|
|
200
|
+
options={options}
|
|
201
|
+
value={
|
|
202
|
+
//blockMap[`${prefix ? groupLabel : ""}${key}`] || "itmar/design-title"
|
|
203
|
+
blockMap[`${prefix ? prefix + "." : ""}${key}`] ||
|
|
204
|
+
"itmar/design-title"
|
|
205
|
+
}
|
|
206
|
+
onChange={(newValue) => {
|
|
207
|
+
//const fieldKey = prefix ? `${groupLabel}${key}` : `${key}`;
|
|
208
|
+
const fieldKey = prefix ? `${prefix}.${key}` : `${key}`;
|
|
209
|
+
|
|
210
|
+
const newBlockMap = { ...blockMap, [fieldKey]: newValue };
|
|
211
|
+
props.onBlockMapChange(newBlockMap);
|
|
212
|
+
}}
|
|
213
|
+
/>
|
|
214
|
+
)}
|
|
153
215
|
</div>
|
|
154
216
|
);
|
|
155
217
|
}
|
|
@@ -240,6 +302,23 @@ const ChoiceControl = (props) => {
|
|
|
240
302
|
}}
|
|
241
303
|
/>
|
|
242
304
|
)}
|
|
305
|
+
{choice.content && (
|
|
306
|
+
<ToggleControl
|
|
307
|
+
className="field_choice"
|
|
308
|
+
label={__("Content", "block-collections")}
|
|
309
|
+
checked={choiceItems.some(
|
|
310
|
+
(choiceField) => choiceField === "content"
|
|
311
|
+
)}
|
|
312
|
+
onChange={(checked) => {
|
|
313
|
+
const newChoiceFields = handleChoiceChange(
|
|
314
|
+
checked,
|
|
315
|
+
"content",
|
|
316
|
+
choiceItems
|
|
317
|
+
);
|
|
318
|
+
props.onChange(newChoiceFields);
|
|
319
|
+
}}
|
|
320
|
+
/>
|
|
321
|
+
)}
|
|
243
322
|
{choice.date && (
|
|
244
323
|
<ToggleControl
|
|
245
324
|
className="field_choice"
|
|
@@ -343,6 +422,7 @@ const ChoiceControl = (props) => {
|
|
|
343
422
|
</div>
|
|
344
423
|
<div className="custom_field_area">
|
|
345
424
|
{dispCustumFields({
|
|
425
|
+
// meta はそのまま
|
|
346
426
|
...Object.entries(choice.meta).reduce(
|
|
347
427
|
(acc, [key, value]) => ({
|
|
348
428
|
...acc,
|
|
@@ -350,13 +430,16 @@ const ChoiceControl = (props) => {
|
|
|
350
430
|
}),
|
|
351
431
|
{}
|
|
352
432
|
),
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
433
|
+
// acf は「同名で _source があるもののベース側を除く」
|
|
434
|
+
...Object.entries(choice.acf)
|
|
435
|
+
.filter(([key]) => !key.endsWith("_source"))
|
|
436
|
+
.reduce(
|
|
437
|
+
(acc, [key, value]) => ({
|
|
438
|
+
...acc,
|
|
439
|
+
[`acf_${key}`]: value,
|
|
440
|
+
}),
|
|
441
|
+
{}
|
|
442
|
+
),
|
|
360
443
|
})}
|
|
361
444
|
</div>
|
|
362
445
|
</>
|
|
@@ -364,16 +447,124 @@ const ChoiceControl = (props) => {
|
|
|
364
447
|
</div>
|
|
365
448
|
);
|
|
366
449
|
})}
|
|
450
|
+
{type === "imgField" &&
|
|
451
|
+
choices.map((choice, index) => {
|
|
452
|
+
//metaの対象カスタムフィールドが含まれるかのフラグ
|
|
453
|
+
const metaFlg =
|
|
454
|
+
choice.meta &&
|
|
455
|
+
!Object.keys(choice.meta).every(
|
|
456
|
+
(key) => key === "_acf_changed" || key === "footnotes"
|
|
457
|
+
);
|
|
458
|
+
//acfの対象カスタムフィールドが含まれるかのフラグ
|
|
459
|
+
const acfFlg =
|
|
460
|
+
choice.acf &&
|
|
461
|
+
typeof choice.acf === "object" &&
|
|
462
|
+
!Array.isArray(choice.acf);
|
|
463
|
+
|
|
464
|
+
return (
|
|
465
|
+
<div key={index} className="field_section">
|
|
466
|
+
{choice.content && (
|
|
467
|
+
<ToggleControl
|
|
468
|
+
className="field_choice"
|
|
469
|
+
label={__("Content", "block-collections")}
|
|
470
|
+
checked={choiceItems.some(
|
|
471
|
+
(choiceField) => choiceField === "content"
|
|
472
|
+
)}
|
|
473
|
+
onChange={(checked) => {
|
|
474
|
+
const newChoiceFields = handleChoiceChange(
|
|
475
|
+
checked,
|
|
476
|
+
"content",
|
|
477
|
+
choiceItems
|
|
478
|
+
);
|
|
479
|
+
props.onChange(newChoiceFields);
|
|
480
|
+
}}
|
|
481
|
+
/>
|
|
482
|
+
)}
|
|
483
|
+
{(choice.featured_media || choice.featured_media === 0) && (
|
|
484
|
+
<ToggleControl
|
|
485
|
+
className="field_choice"
|
|
486
|
+
label={__("Featured Image", "block-collections")}
|
|
487
|
+
checked={choiceItems.some(
|
|
488
|
+
(choiceField) => choiceField === "featured_media"
|
|
489
|
+
)}
|
|
490
|
+
onChange={(checked) => {
|
|
491
|
+
const newChoiceFields = handleChoiceChange(
|
|
492
|
+
checked,
|
|
493
|
+
"featured_media",
|
|
494
|
+
choiceItems
|
|
495
|
+
);
|
|
496
|
+
props.onChange(newChoiceFields);
|
|
497
|
+
}}
|
|
498
|
+
/>
|
|
499
|
+
)}
|
|
500
|
+
|
|
501
|
+
{(metaFlg || acfFlg) && (
|
|
502
|
+
<>
|
|
503
|
+
<div className="custom_field_label">
|
|
504
|
+
{__("Custom Field", "block-collections")}
|
|
505
|
+
</div>
|
|
506
|
+
<div className="custom_field_area">
|
|
507
|
+
{dispCustumFields(
|
|
508
|
+
{
|
|
509
|
+
// meta はそのまま
|
|
510
|
+
...Object.entries(choice.meta).reduce(
|
|
511
|
+
(acc, [key, value]) => ({
|
|
512
|
+
...acc,
|
|
513
|
+
[`meta_${key}`]: value,
|
|
514
|
+
}),
|
|
515
|
+
{}
|
|
516
|
+
),
|
|
517
|
+
// acf は「同名で _source があるもののベース側を除く」
|
|
518
|
+
...Object.entries(choice.acf)
|
|
519
|
+
.filter(([key]) => !key.endsWith("_source"))
|
|
520
|
+
.reduce(
|
|
521
|
+
(acc, [key, value]) => ({
|
|
522
|
+
...acc,
|
|
523
|
+
[`acf_${key}`]: value,
|
|
524
|
+
}),
|
|
525
|
+
{}
|
|
526
|
+
),
|
|
527
|
+
},
|
|
528
|
+
"",
|
|
529
|
+
true
|
|
530
|
+
)}
|
|
531
|
+
</div>
|
|
532
|
+
</>
|
|
533
|
+
)}
|
|
534
|
+
</div>
|
|
535
|
+
);
|
|
536
|
+
})}
|
|
367
537
|
</div>
|
|
368
538
|
);
|
|
369
539
|
};
|
|
370
540
|
|
|
371
541
|
//固定ページ取得RestAPI関数
|
|
372
542
|
export const fetchPagesOptions = async (home_url) => {
|
|
373
|
-
const
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
543
|
+
const allPages = [];
|
|
544
|
+
let page = 1;
|
|
545
|
+
|
|
546
|
+
while (true) {
|
|
547
|
+
const items = await apiFetch({
|
|
548
|
+
path: addQueryArgs("/wp/v2/pages", {
|
|
549
|
+
status: "publish", // 公開のみ
|
|
550
|
+
per_page: 100, // 最大100
|
|
551
|
+
page,
|
|
552
|
+
// orderby: "title",
|
|
553
|
+
// order: "asc",
|
|
554
|
+
}),
|
|
555
|
+
});
|
|
556
|
+
|
|
557
|
+
allPages.push(...items);
|
|
558
|
+
|
|
559
|
+
// 100件未満ならこれが最後
|
|
560
|
+
if (!items || items.length < 100) break;
|
|
561
|
+
|
|
562
|
+
page++;
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
// ページIDが-1である要素をホーム要素として作成
|
|
566
|
+
if (!allPages.some((p) => p.id === -1)) {
|
|
567
|
+
allPages.unshift({
|
|
377
568
|
id: -1,
|
|
378
569
|
title: { rendered: "ホーム" },
|
|
379
570
|
link: home_url,
|
|
@@ -381,14 +572,13 @@ export const fetchPagesOptions = async (home_url) => {
|
|
|
381
572
|
});
|
|
382
573
|
}
|
|
383
574
|
|
|
384
|
-
const ret_pages =
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
: [];
|
|
575
|
+
const ret_pages = allPages.map((p) => ({
|
|
576
|
+
value: p.id,
|
|
577
|
+
slug: p.slug,
|
|
578
|
+
label: p.title?.rendered ?? "",
|
|
579
|
+
// 階層ページでも正しいURLになるようにRESTのlinkを優先
|
|
580
|
+
link: p.link || (p.slug ? `${home_url}/${p.slug}` : home_url),
|
|
581
|
+
}));
|
|
392
582
|
|
|
393
583
|
return ret_pages;
|
|
394
584
|
};
|
|
@@ -483,6 +673,7 @@ export const restFieldes = async (rest_base) => {
|
|
|
483
673
|
//投稿データに以下のフィールドが含まれているかを調べる
|
|
484
674
|
const selectedFields = [
|
|
485
675
|
"title",
|
|
676
|
+
"content",
|
|
486
677
|
"date",
|
|
487
678
|
"excerpt",
|
|
488
679
|
"featured_media",
|
|
@@ -495,6 +686,7 @@ export const restFieldes = async (rest_base) => {
|
|
|
495
686
|
const response = await apiFetch({
|
|
496
687
|
path: `/wp/v2/${rest_base}?_fields=${fieldsParam}&per_page=1&order=desc`,
|
|
497
688
|
});
|
|
689
|
+
|
|
498
690
|
return response;
|
|
499
691
|
};
|
|
500
692
|
|