مولّد النماذج ثلاثية الأبعاد 3D
تدعم نقاط نهاية استيراد المولّد طلبات القراءة فقط بين الخوادم. وتتطلب ترويسات API القياسية والصلاحية embed:session:create وخطة نشطة. لا ينشئ تفويض الاستيراد جلسة محرّر ولا يستهلك حصتها الشهرية. يستخدم فتح المحرّر عدّاد monthlyEmbedTokenLimit نفسه الذي تستخدمه الأدوات المضمّنة الأخرى.
اكتشاف النماذج التي تتضمن مولّدًا واستيرادها
استخدم /model-generator/models لسرد النماذج المتاحة التي تتضمن مولّدات. يثبّت الواصف generator قيم projectId وrevision وconfigurationId وtemplateRevision وproductId وproductModel3dId. اتبع importPath الخاص به لاسترجاع نسخة المصدر المحددة نفسها. تعرض قوائم ملفات موارد المنتجات أيضًا generators والواصف generator لكل نموذج. ويمكن استيراد القوالب بشكل مستقل بحسب التهيئة والنسخة.
مرشحات الكتالوج
| نقطة النهاية | التفاصيل |
|---|---|
/model-generator/models | قائمة النماذج: name أو q، وcategoryId، وscope بقيم all وown وglobal، وlimit ضمن 1-50، وoffset. |
/model-generator/catalog | كتالوج القوالب: generatorType وproductId وaudience وq وtemplateKey وconfigurationId وlimit وoffset. |
/model-generator/projects | قائمة المشاريع: configurationId وq وscope بقيم all وown وglobal، وlimit وoffset. يضبط الوكيل العام scope على all افتراضيًا. |
/model-generator/image-libraries/:kind/assets | مكتبات الخامات والخلفيات: تكون قيمة kind هي texture أو background؛ وتُرشّح q وcategory وmapType الموارد المتاحة. |
تتضمن حزمة استيراد المشروع document وrevision وtemplate وقائمة files. يوفّر كل ملف path ضمن /v1/model-generator/؛ أضف /public-api قبله عند تنزيله من Alter Product. انسخ الملفات المطلوبة إلى مساحة التخزين الخاصة بك واستبدل المراجع المصدرية بمراجع محلية. استورد المانيكانات ومكتبات الخامات عبر نقاط نهاية كتالوجاتها؛ يقتصر public-files على مسارات الموارد المسموح بها، ويجب أن تجتاز القوالب التحقق من الوصول إلى التهيئة والنسخة.
مثال طلب (fetch)
// Server-side: uses alterFetch and authHeaders from the API connection guide.
const catalog = await alterFetch('/model-generator/models?' + new URLSearchParams({
scope: 'all', limit: '24', offset: '0'
}));
const selected = catalog.items[0];
if (!selected?.generator) throw new Error('Select an available generator model');
const importPath = selected.generator.importPath;
if (!importPath.startsWith('/v1/model-generator/projects/')) {
throw new Error('Invalid generator import path');
}
const bundle = await alterFetch(importPath.slice('/v1'.length));
for (const file of bundle.files) {
if (!file.path.startsWith('/v1/model-generator/')) {
throw new Error('Invalid generator file path');
}
const response = await fetch('https://alterproduct.com/public-api' + file.path, {
headers: authHeaders,
redirect: 'error'
});
if (!response.ok) throw new Error(`File download failed: ${response.status}`);
const bytes = new Uint8Array(await response.arrayBuffer());
// Persist bytes in your local storage; record the mapping from
// file.sourceHref / file.href to the resulting local file reference.
}
// Persist bundle.document, bundle.template and revision metadata locally.
// Import the related product asset and its textures/mockups as needed:
const product = await alterFetch('/assets/products/' + selected.generator.productId);
const mannequins = await alterFetch('/model-generator/mannequins');
console.log({ product, mannequins });جلسة المحرّر والتخزين المحلي
أنشئ جلسة المحرّر باستخدام tool: model-generator وtoolId رقمي موجب يعرّف مشروع المولّد المحلي، وليس UUID الخاص به أو معرّف منتج WooCommerce، مع origin المتجر المسموح به. لا تمرّر designId أو orderId أو runtimeBindingId أو حقول السلة لهذه الأداة. يُعد UUID مشروع المولّد معرّفًا منفصلًا. مرّر token المُعاد عبر مصافحة iframe؛ وتعيد تهيئة بيئة التشغيل الأولية سياق المولّد مع storageMode: wordpress_local.
// Server-side, after authorizing the merchant's access to this local project.
const localProjectId = 42; // Local generator project ID, not its UUID or WC product ID.
const session = await alterFetch('/embed/session', {
method: 'POST',
body: JSON.stringify({
tool: 'model-generator',
toolId: localProjectId,
origin: 'https://yourstore.com'
})
});
// The iframe receives session.token through ALTER_CUSTOMIZER_SESSION_READY.
// Do not put API credentials or the token in the iframe URL.
const bootstrapResponse = await fetch('https://alterproduct.com/public-api/v1/runtime/bootstrap', {
headers: { Authorization: `Bearer ${session.token}` }
});
if (!bootstrapResponse.ok) throw new Error('Generator bootstrap failed');
const context = await bootstrapResponse.json();
console.log(context);مثال رد
{
"runtimeBindingId": null,
"designId": null,
"productId": 42,
"toolId": 42,
"runtimeType": "model-generator",
"storageMode": "wordpress_local",
"parentOrigin": "https://yourstore.com"
}// Host page: WordPress returns a numeric toolId and a UUID in id.
const url = new URL('https://alterproduct.com/app/model-generator');
url.search = new URLSearchParams({
embedded: '1',
lng: 'en',
parentOrigin: window.location.origin,
toolId: String(localProject.toolId),
serverProjectId: localProject.id
}).toString();
// Optional: serverProjectRevision pins an existing saved revision.
iframe.src = url.toString();
// Install the authenticated handshake and storage bridge described below.
// Setting iframe.src alone does not authorize the editor or provide storage.رسائل iframe التي يستخدمها جسر WordPress
تستضيف إضافة WordPress جسر التخزين وتتحقق من صلاحيات المسؤول أو مدير WooCommerce. وتتحقق من origin الخاص بـ iframe والنافذة المصدرية وnonce ومعرّف الطلب ومسارات المشروع المسموح بها. يوجّه الجسر عمليات القراءة والكتابة المحلية إلى /wp-json/alter-wc/v1/model-generator. تبقى بيانات اعتماد API على الخادم. ويجب أن تنفّذ أي تكاملات مخصصة معالجة تخزين مكافئة ومصادَقًا عليها؛ فواجهة API العامة للمولّد لا تحفظ المشاريع في Alter Product.
| النوع | الوصف |
|---|---|
ALTER_CHILD_HELLO / ALTER_PARENT_ACK | يبدأ الإطار الفرعي المصافحة باستخدام nonce؛ وتؤكد الصفحة الأم nonce نفسه. |
ALTER_CUSTOMIZER_INIT_SESSION / ALTER_CUSTOMIZER_SESSION_READY | يطلب الإطار الفرعي جلسة تحرير model-generator؛ وتعيد الصفحة الأم الرمز المصرّح به. |
ALTER_MODEL_GENERATOR_REQUEST | يرسل الإطار الفرعي requestId وnonce وrequest الذي يحتوي على method وpath وdata وresponseType. |
ALTER_MODEL_GENERATOR_RESPONSE | تجيب الصفحة الأم بـ requestId وnonce نفسيهما، إضافة إلى status وdata وheaders وأي error. |
// Messages after ALTER_CHILD_HELLO / ALTER_PARENT_ACK agree on the nonce.
// Iframe -> parent:
const sessionRequest = {
type: 'ALTER_CUSTOMIZER_INIT_SESSION',
nonce: handshakeNonce,
payload: {
tool: 'model-generator', alterProductId: localProject.toolId, mode: 'edit'
}
};
// Parent -> iframe, after the server authorizes the merchant and issues a token:
const sessionReady = {
type: 'ALTER_CUSTOMIZER_SESSION_READY',
nonce: handshakeNonce,
token: session.token,
tool: 'model-generator',
cartKey: `model-generator:${localProject.id}`,
mode: 'edit',
localSession: false,
adminSession: true
};
// Send only to the validated iframe's exact origin and source window.
// An authorized token and successful bootstrap are still required.تتضمن عملية الحفظ expectedRevision وtemplateRevision وdocument ومراجع الملفات الناتجة. وتنشئ نسخة غير قابلة للتغيير؛ وإذا كانت expectedRevision قديمة، تُعاد استجابة HTTP 409. يخزّن WordPress البيانات الوصفية في قاعدة بياناته والملفات في مجلد uploads. يُصغّر JSON ويُضغط باستخدام gzip عندما يؤدي الضغط إلى تقليل حجمه.
// Example message from the iframe; savedSnapshot and artifact IDs come
// from the generator. The host checks origin/source/nonce/project permissions.
const message = {
type: 'ALTER_MODEL_GENERATOR_REQUEST',
requestId: crypto.randomUUID(),
nonce: handshakeNonce,
request: {
method: 'POST',
path: `/pattern-generator/projects/${projectUuid}/revisions`,
data: {
expectedRevision: loadedRevision,
name: projectName,
templateRevision,
document: savedSnapshot,
references: { artifactIds: savedArtifactIds }
},
responseType: 'json'
}
};ينشر إجراء «استخدام النموذج المحفوظ في التصميم» نسخة محفوظة كاملة إلى تصميم مرتبط. يراها العملاء بعد ذلك عبر Customizer أو Configurator أو Viewer الحالي، مع روابط المنتجات وفحوص الاشتراك المعتادة. يظل محرّر المولّد أداة للتاجر. تحتفظ روابط الطلبات بالمشروع والنسخة المحفوظين، كي لا تؤدي التعديلات اللاحقة إلى تغيير الطلبات السابقة دون تنبيه.