Nilai Atribut
Atribut adalah cara OneEntry menggambarkan konten: sebuah halaman, produk, blok, pengguna, pesanan, atau kolom formulir membawa peta nilai atribut yang dikunci oleh penanda. SDK menormalkan setiap atribut dari setiap respons ke bentuk yang sama, sehingga kolom yang sama terlihat sama tidak peduli modul mana yang mengembalikannya.
const page = await Pages.getPageByUrl('catalog');
page.attributeValues.title.value; // "Catalog" — string
page.attributeValues.amount.value; // 5 — number
page.attributeValues.cover.value; // { downloadLink } — the file object itself
page.attributeValues.notes.value; // null — no value set
Bentuk yang dinormalisasi
Nilai atribut adalah IAttributeValue: { type, value, position?, additionalFields? }. Apa yang dipegang oleh value tergantung pada type:
| Tipe atribut | value |
|---|---|
string, text | string |
integer, float, real | number — dikonversi dari bentuk string API |
image, file dengan satu file | objek file itu sendiri |
image, file dengan beberapa file | array objek file |
groupOfImages | selalu array — ini adalah koleksi berdasarkan definisi |
list | array |
timeInterval | array kelompok — lihat Time Intervals |
| tidak ada nilai yang ditetapkan | selalu null |
Atribut file tunggal tidak dibongkar
Ketika atribut image atau file memegang tepat satu file, value-nya adalah objek file itu sendiri. Hanya nilai dengan dua atau lebih file yang tetap sebagai array.
const block = await Blocks.getBlockByMarker('promo');
// before: block.attributeValues.img.value[0].downloadLink
// now: block.attributeValues.img.value.downloadLink
Ini berlaku di setiap modul. Sebelumnya, pembongkaran hanya terjadi di produk, menu, formulir, data-formulir, set atribut, koleksi integrasi, dan Pages.searchPage, dan hanya pada kunci attributeValues — di tempat lain (blok, semua metode halaman lainnya, Products.getProductsEmptyPage, Products.getProductBlockById, admins, diskon, template, pesanan, pengguna) atribut yang sama tiba sebagai array satu elemen, sehingga konsumen harus bercabang berdasarkan bentuk. Atribut attributes, kolom data formulir, dan additionalFields bersarang tidak pernah dibongkar sama sekali.
⚠️ Migrasi: kode yang membaca
value[0]dari produk atau menu tidak terpengaruh — modul-modul tersebut sudah mengembalikan objek. Kode yang membacavalue[0]dari blok, halaman, pengguna, atau pesanan harus menghapus indeks.
groupOfImages adalah koleksi berdasarkan definisi dan selalu tetap sebagai array. Di sisi permintaan, IBodyTypeFile.value diketik IFileValue | IFileValue[] sesuai.
Angka adalah angka
Nilai integer, float, dan real dikonversi menjadi angka. real dulunya dibiarkan sebagai string, sehingga kolom numerik yang sama mencapai konsumen sebagai 10 atau sebagai "10" tergantung pada tipe mana dari ketiga tipe yang dinyatakan:
const page = await Pages.getPageByUrl('catalog');
// before: page.attributeValues.amount.value // "5"
// now: page.attributeValues.amount.value // 5
Normalisasi numerik juga berjalan pada atribut formulir dan kolom data formulir, yang sepenuhnya dilewati — kolom rating dari atribut formulir integer adalah number, bukan string.
Saat mengirim data, kirim sebagai string: IBodyTypeStringNumberFloat.value adalah string | number | null, dan respons kembali dinormalisasi.
Nilai kosong selalu null
API mengembalikan peta lokalisasi kosong untuk nilai yang tidak diatur. SDK dulunya meneruskannya untuk tipe seperti teks sementara tipe numerik menjadi null — keadaan "tidak ada nilai" yang sama memiliki tiga representasi. Sekarang selalu null.
if (page.attributeValues.notes.value === null) {
// nothing configured for this attribute
}
⚠️ Migrasi:
integer/floatyang tidak diatur tidak lagi0.Number(null)adalah0, jadinulleksplisit dari API dulunya dilaporkan sebagai nol yang nyata — nilai yang tidak dapat dibedakan dari0yang dikonfigurasi.
Segalanya diurutkan berdasarkan posisi
attributeValues selalu dikembalikan dalam urutan position, dan atribut formulir sekarang juga demikian. API mengembalikan kolom formulir tanpa urutan — kolom dengan position: 10 bisa tiba setelah position: 14 — sehingga merender formulir dalam urutan CMS memerlukan pengurutan di sisi konsumen.
Sebuah formulir tanpa atribut mengembalikan attributes: []. API mengirim objek kosong dalam kasus itu, dan SDK menormalkannya menjadi array kosong, sehingga attributes selalu IFormAttribute[] dan form.attributes.map(...) aman pada setiap formulir.
Kolom bersarang: additionalFields
Nilai atribut bersarang tiba di bawah additionalFields. Secara default, SDK mengonversi array yang dikembalikan API menjadi objek yang dikunci oleh marker; atur rawData: true dalam konfigurasi untuk mempertahankan array asli — lihat Additional Fields Format.
// default (rawData: false)
attribute.additionalFields['my_field'].value;
// rawData: true
attribute.additionalFields.find((f) => f.marker === 'my_field').value;
additionalFields bersarang melalui normalisasi yang sama seperti atribut tingkat atas — file tunggal dibongkar dan angka juga dikonversi di sana.
Mengetik nilai atribut
IAttributeValue.value diketik unknown, karena bentuknya tergantung pada type saat runtime — yang juga berarti kompiler tidak dapat menangkap asumsi yang salah tentangnya. Aturan file tunggal di atas adalah tempat itu bermasalah: sebuah pembantu yang ditulis sebagai
const file = Array.isArray(value) ? value[0] : undefined; // single image → undefined
dikompilasi, dibangun, dan merender halaman tanpa gambar dan tanpa kesalahan di mana pun. Akses nilai melalui penjaga dan pembantu sebagai gantinya.
File
getAttributeFiles mengembalikan setiap file dari atribut image, file, atau groupOfImages, menggabungkan bentuk file tunggal dan array menjadi satu daftar. Apa pun yang lain menghasilkan array kosong, sehingga aman pada atribut sembarang:
import { getAttributeFile, getAttributeFiles } from 'oneentry';
const gallery = getAttributeFiles(product.attributeValues.images); // IAttributeFile[]
const cover = getAttributeFile(page.attributeValues.cover); // IAttributeFile | null
const blurDataURL = cover?.previewLink?.default?.[0]; // base64 placeholder
IAttributeFile diekspor: filename, downloadLink, size, contentType, ditambah previewLink opsional (pratinjau yang dikunci oleh template, masing-masing pasangan [base64 placeholder, url]), dan defaultPreview.
Kolom bersarang
additionalFields adalah Record<string, IAttributeValue> | unknown[] — API mengembalikan array kosong ketika atribut tidak memiliki satu pun, dan union itu membuat setiap kolom membaca kesalahan tipe. getAdditionalFields menggabungkannya menjadi peta (dan mengunci array rawData: true dengan marker):
import { getAdditionalFields } from 'oneentry';
const alt = getAdditionalFields(page.attributeValues.cover).alt?.value;
Penjaga
isFileAttribute, isStringAttribute, isNumberAttribute, isListAttribute, dan isTimeIntervalAttribute mempersempit IAttributeValue sehingga value-nya dapat diakses tanpa konversi:
import { isStringAttribute } from 'oneentry';
import type { IAttributeValues } from 'oneentry';
function readText(values: IAttributeValues, marker: string): string {
const attr = values[marker];
return isStringAttribute(attr) ? (attr.value ?? '') : '';
}
Union yang dibedakan
ITypedAttributeValue adalah IAttributeValue sebagai union berdasarkan type — IFileAttributeValue, IStringAttributeValue, INumberAttributeValue, IListAttributeValue, ITimeIntervalAttributeValue. Ini ditutup dengan sengaja: anggota longgar (type: string) akan cocok dengan setiap case dan mengembalikan penyempitan kembali ke unknown. Tipe yang tidak dimodelkan SDK (entity, date, yang kustom) tetap pada IAttributeValue.
Ini bersifat opt-in — IAttributeValues mempertahankan IAttributeValue yang longgar, jadi sempit ke dalam union dengan penjaga, atau anotasi nilai yang Anda kendalikan:
import type { ITypedAttributeValue } from 'oneentry';
function render(attr: ITypedAttributeValue) {
switch (attr.type) {
case 'image':
case 'file':
return attr.value; // IAttributeFile | IAttributeFile[] | null
case 'integer':
return attr.value; // number | null
}
}
Ketika API berubah
Tipe menggambarkan API seperti saat SDK dibangun; mereka tidak dapat menyadari perubahan setelahnya. Untuk nilai atribut, mode kegagalan tenang — jika kolom file diubah namanya, getAttributeFiles akan mengembalikan daftar kosong dan halaman akan dirender tanpa gambar.
Mengaktifkan validasi respons membuatnya terdengar keras:
const api = defineOneEntry('your-url', {
token: 'your-app-token',
validation: { enabled: true, strictMode: false, logErrors: true },
});
attributeValues dulunya dikecualikan dari validasi sepenuhnya. Sekarang diperiksa di mana kontrak API tetap tetap — bentuk file dari atribut image, file, dan groupOfImages, termasuk kolom bersarang — sementara segala sesuatu yang didefinisikan oleh set atribut Anda sendiri tetap terbuka. Sebuah file yang kehilangan atau mengubah nama kolom dilaporkan sebagai masalah validasi yang menyebutkan penanda dan indeks; kolom yang ditambahkan API diterima.
Dengan strictMode: false (pengaturan produksi yang direkomendasikan) data masih diteruskan dan masalah dicatat; dengan strictMode: true panggilan mengembalikan IError yang membawa validationErrors.
🔗 Dokumentasi Terkait
- Time Intervals - memperluas atribut
timeIntervalmenjadi slot - Importing Types -
IAttributeValue,IAttributeValues, dan yang lainnya - AttributesSets Module - bagaimana atribut dikonfigurasi