Lewati ke konten utama

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 atributvalue
string, textstring
integer, float, realnumber — dikonversi dari bentuk string API
image, file dengan satu fileobjek file itu sendiri
image, file dengan beberapa filearray objek file
groupOfImagesselalu array — ini adalah koleksi berdasarkan definisi
listarray
timeIntervalarray kelompok — lihat Time Intervals
tidak ada nilai yang ditetapkanselalu 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 membaca value[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/float yang tidak diatur tidak lagi 0. Number(null) adalah 0, jadi null eksplisit dari API dulunya dilaporkan sebagai nol yang nyata — nilai yang tidak dapat dibedakan dari 0 yang 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​