mofang-page-builder

Build Magicflu/Mofang web-table custom pages from the jsonv2 records API. Use when users ask for Magicflu/Mofang forms, records, lists, create/edit/detail/admin CRUD pages, H5 extension pages, React/Vue/vanilla JS examples, local jsonv2 mock/proxy debugging, or same-origin publishing to Magicflu websites. Works as a standalone skill for Codex/OpenAI, OpenClaw, Claude Code, Trae, and Trae CN.

Audits

Warn

Install

openclaw skills install mofang-page-builder

魔方网表页面生成

Use this skill to generate and publish Magicflu/Mofang web-table pages. The safe path is:

  1. Confirm spaceId, formId, and page type.
  2. Fetch or import the real fielddef.
  3. Generate page code using only field name values from fielddef.fields[].
  4. Test with local mock-jsonv2 or proxy.
  5. Set CONFIG.apiBase to '' before same-origin publishing.

Install Locations

Copy the whole mofang-page-builder/ folder, not only SKILL.md.

ClientProject installGlobal install
Claude Code.claude/skills/mofang-page-builder/~/.claude/skills/mofang-page-builder/
Trae.trae/skills/mofang-page-builder/~/.trae/skills/mofang-page-builder/
Trae CN.trae/skills/mofang-page-builder/~/.trae-cn/skills/mofang-page-builder/

Keep these directories with the skill: examples/, assets/, references/, and scripts/.

Required Workflow

Never guess real form field names from Chinese labels. For real data:

  1. Ask for or identify spaceId and formId.
    • If only a space name is known, resolve it with /magicflu/service/json/spaces/feed.
    • To traverse all spaces, use /magicflu/service/json/spaces/feed?start=0&limit=-1&bq=(created,orderby,desc).
    • If only a form label is known, resolve it with /magicflu/service/s/json/{spaceId}/forms/feed.
  2. Run scripts/fetch-form-spec.mjs, or ask the user for an exported fielddef JSON and import it.
  3. Use only fielddef.fields[].name as API keys, submit keys, and filter field names.
  4. Use fielddef.fields[].label only for UI text.
  5. Test locally before deployment.

Example fields in examples/ and assets/mock-data/ are demos only.

Page Contract

Generated pages must include:

const CONFIG = {
  apiBase: '', // local debug: 'http://127.0.0.1:3847'; same-origin production: ''
  spaceId: 'YOUR_SPACE_ID',
  formId: 'YOUR_FORM_ID',
};

function apiUrl(path) {
  const origin = CONFIG.apiBase ? CONFIG.apiBase.replace(/\/$/, '') : '';
  return `${origin}${path}`;
}

Same-origin pages rely on browser Cookie auth. Do not set an Authorization header in page code.

API Summary

Read references/api-summary.md when you need endpoint details, bq syntax, response shape, or field value formats.

Core paths:

CapabilityMethodPath
List all spacesGET/magicflu/service/json/spaces/feed?start=0&limit=-1&bq=(created,orderby,desc)
Find spaces by labelGET/magicflu/service/json/spaces/feed?start=0&limit=10&bq=(label,eq,{spaceLabel})
List forms in a spaceGET/magicflu/service/s/json/{spaceId}/forms/feed?start=0&limit=-1
Find forms by labelGET/magicflu/service/s/json/{spaceId}/forms/feed?start=0&limit=10&bq=(label,eq,{formLabel})
Field definitionGET/magicflu/service/s/jsonv2/{spaceId}/forms/{formId}?selector=fielddef&lng=en
List recordsGET/magicflu/service/s/jsonv2/{spaceId}/forms/{formId}/records/entry
Create recordPOST/magicflu/service/s/jsonv2/{spaceId}/forms/{formId}/records
Update recordPUT/magicflu/service/s/jsonv2/{spaceId}/forms/{formId}/records/entry/{recordId}
Delete recordDELETE/magicflu/service/s/jsonv2/{spaceId}/forms/{formId}/records/entry/{recordId}

Use the spaces endpoint when the user gives only a space name. The returned space id is items[].id; the display name is items[].label. Use the form-list endpoint when the user gives only a spaceId or form label. The returned form id is feed.entry[].id; the display name is feed.entry[].content.form.label; the English form key is feed.entry[].content.form.name.

Field rules:

  • API payload keys must be name, not label.
  • Omit empty values before submit.
  • Never submit "" for number fields.
  • Do not submit system, serial, secondary reference, image, attachment, location, webpage, comment, or external field-group fields.

Fetch Field Definitions

Account/password:

BASE_URL="http://appdev.com.magicflu.com:9999" \
MOFANG_USERNAME="你的账号" \
MOFANG_PASSWORD='你的密码' \
node scripts/fetch-form-spec.mjs \
  --spaceId <空间UUID> \
  --formId <表单UUID> \
  --out ./mock-data

If only names are known, resolve and fetch in one command:

BASE_URL="http://appdev.com.magicflu.com:9999" \
MOFANG_USERNAME="你的账号" \
MOFANG_PASSWORD='你的密码' \
node scripts/fetch-form-spec.mjs \
  --spaceLabel "空间名称" \
  --formLabel "表单名称" \
  --out ./mock-data

Cookie:

node scripts/fetch-form-spec.mjs \
  --baseUrl https://你的魔方域名 \
  --spaceId <空间UUID> \
  --formId <表单UUID> \
  --out ./mock-data \
  --cookie "浏览器 Cookie"

Offline import:

node scripts/fetch-form-spec.mjs \
  --spaceId <空间UUID> \
  --formId <表单UUID> \
  --out ./mock-data \
  --import-json ./fielddef-export.json

Output: mock-data/manifest.json, mock-data/<formId>/fielddef.json, records.seed.json, typesnippets.md, and api-outline.md.

Local Debug

Use the bundled demo data:

cp -R assets/mock-data ./mock-data
node scripts/mock-jsonv2.mjs --port 3847 --dir ./mock-data

Set page config:

CONFIG.apiBase = 'http://127.0.0.1:3847';

Proxy to a real environment only when the user explicitly wants real data behavior:

BASE_URL="http://appdev.com.magicflu.com:9999" \
MOFANG_USERNAME="你的账号" \
MOFANG_PASSWORD='你的密码' \
node scripts/mock-jsonv2.mjs --mode proxy --port 3847

Proxy mode forwards supported space, json, and jsonv2 calls to the real environment. POST, PUT, and DELETE will change real records.

Publish Same-Origin Pages

Before publishing, set page CONFIG.apiBase to ''.

BASE_URL="http://appdev.com.magicflu.com:9999" \
MOFANG_USERNAME="你的账号" \
MOFANG_PASSWORD='你的密码' \
node scripts/deploy.mjs \
  --spaceId <空间UUID> \
  --label "站点名称" \
  --shortcut custom-page \
  --files index.html

The deploy script logs in, creates a website, warms the session, uploads files through filemanager.jsp, and prints the final URL:

{BASE_URL}/magicflu/html/sites/userfiles/{spaceId}/{websiteId}/index.html

Read references/design.md, references/requirements.md, and references/filemanager.js only when debugging implementation details.

Examples

StackFilePurpose
Vanilla HTML+JSexamples/vanilla/list-page.htmlSame-origin list page
Vanilla HTML+JSexamples/vanilla/list-page-with-apibase.htmlList page wired to local mock
Vanilla HTML+JSexamples/vanilla/form-page.htmlCreate-record form
Reactexamples/react/MagicfluList.tsxList component
Vueexamples/vue/MagicfluForm.mdText-safe create-record form component

Validation

Run these from the skill root:

npm run check:scripts
npm run smoke:fetch-import
npm run smoke:mock
npm run smoke:upload