市场接口 市场
TextPress 提供完整的主题/插件市场 API,支持在线浏览、安装和更新。
主题市场
浏览和安装精美主题
插件市场
发现和安装实用插件
一键安装
从 URL 下载并自动安装
上传安装
上传 ZIP 包本地安装
获取主题列表
GET
/api/market/themes
获取市场中的主题列表。
请求参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
keyword | string | 否 | 搜索关键词 |
page | int | 否 | 页码,默认 1 |
per_page | int | 否 | 每页数量,默认 12 |
响应示例
JSON
{
"success": true,
"data": [
{
"id": 1,
"name": "Sales Star",
"slug": "sales-star",
"description": "专业的产品销售主题",
"version": "1.0.0",
"author": "TextPress",
"price": 0,
"downloads": 1234,
"rating": 4.8,
"screenshot": "/uploads/products/1/screenshot.png",
"demo_url": "https://demo.textpress.cn/sales-star",
"download_url": "/uploads/products/1/sales-star-v1.0.0.zip"
}
],
"total": 10,
"page": 1,
"per_page": 12,
"total_pages": 1
}
获取插件列表
GET
/api/market/plugins
获取市场中的插件列表,参数和响应格式与主题列表相同。
从 URL 安装
POST
/api/market/install
从指定 URL 下载 ZIP 包并安装主题或插件。
请求参数 (JSON)
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
type | string | 是 | 类型:theme 或 plugin |
download_url | string | 是 | ZIP 包下载地址 |
product_id | int | 否 | 产品 ID |
slug | string | 否 | 产品标识 |
请求示例
JavaScript
const response = await fetch('/api/market/install', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
type: 'theme',
download_url: 'https://example.com/my-theme.zip',
slug: 'my-theme'
})
});
const data = await response.json();
响应示例
JSON
{
"success": true,
"slug": "my-theme",
"name": "My Theme",
"message": "安装成功"
}
上传安装主题
POST
/admin/theme/upload
上传 ZIP 格式的主题包进行安装(需要管理员权限)。
请求参数 (FormData)
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
file | File | 是 | ZIP 格式的主题包,最大 50MB |
请求示例
JavaScript
const formData = new FormData();
formData.append('file', zipFile);
const xhr = new XMLHttpRequest();
xhr.upload.addEventListener('progress', (e) => {
if (e.lengthComputable) {
const percent = Math.round((e.loaded / e.total) * 100);
console.log('上传进度:', percent + '%');
}
});
xhr.onload = () => {
const result = JSON.parse(xhr.responseText);
if (result.success) {
console.log('安装成功:', result.name);
}
};
xhr.open('POST', '/admin/theme/upload');
xhr.send(formData);
响应示例
JSON
{
"success": true,
"slug": "my-theme",
"name": "My Theme",
"is_update": false,
"message": "安装成功"
}
响应字段说明
| 字段 | 类型 | 说明 |
|---|---|---|
success | boolean | 是否成功 |
slug | string | 主题标识 |
name | string | 主题名称 |
is_update | boolean | 是否为更新(已存在同名主题) |
message | string | 提示信息 |
上传安装插件
POST
/admin/plugin/upload
上传 ZIP 格式的插件包进行安装(需要管理员权限)。参数和响应格式与主题上传相同。
安装包结构要求
ZIP 包结构
上传的 ZIP 包可以直接包含文件,也可以有一层目录包装,系统会自动识别。
主题包结构
my-theme.zip
my-theme/
theme.json 必需 - 主题配置
functions.php 可选 - 主题函数
templates/
assets/
插件包结构
my-plugin.zip
my-plugin/
plugin.json 推荐 - 插件配置
my-plugin.php 必需 - 主文件
错误处理
| 错误信息 | 说明 | 解决方案 |
|---|---|---|
| 只支持 .zip 格式 | 上传的文件不是 ZIP 格式 | 确保上传 .zip 后缀的文件 |
| 文件大小不能超过 50MB | 文件过大 | 压缩或拆分文件 |
| 服务器不支持 ZIP 解压 | 缺少 php-zip 扩展 | 安装 php-zip 扩展 |
| 无效的主题/插件包 | 缺少配置文件 | 确保包含 theme.json 或 plugin.json |
| 解压失败 | ZIP 文件损坏 | 重新打包上传 |
集成示例
以下是完整的上传安装功能实现示例:
JavaScript
/**
* 上传安装主题/插件
* @param {File} file - ZIP 文件
* @param {string} type - 'theme' 或 'plugin'
*/
async function uploadAndInstall(file, type = 'theme') {
// 验证文件
if (!file.name.endsWith('.zip')) {
throw new Error('只支持 .zip 格式');
}
const formData = new FormData();
formData.append('file', file);
const endpoint = type === 'theme'
? '/admin/theme/upload'
: '/admin/plugin/upload';
// 使用 XMLHttpRequest 支持进度
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
// 上传进度
xhr.upload.addEventListener('progress', (e) => {
if (e.lengthComputable) {
const percent = Math.round((e.loaded / e.total) * 100);
console.log(`上传进度: ${percent}%`);
}
});
xhr.onload = () => {
try {
const result = JSON.parse(xhr.responseText);
if (result.success) {
resolve(result);
} else {
reject(new Error(result.message));
}
} catch (e) {
reject(new Error('响应解析失败'));
}
};
xhr.onerror = () => reject(new Error('网络错误'));
xhr.open('POST', endpoint);
xhr.send(formData);
});
}
// 使用示例
const fileInput = document.querySelector('input[type="file"]');
fileInput.addEventListener('change', async (e) => {
const file = e.target.files[0];
try {
const result = await uploadAndInstall(file, 'theme');
console.log('安装成功:', result.name);
// 询问是否启用
if (confirm(`${result.name} 安装成功,是否立即启用?`)) {
// 调用启用接口
await enableTheme(result.slug);
}
} catch (error) {
console.error('安装失败:', error.message);
}
});