::: alert-warning Markdown区块的架构设计已经变更,文档正在重构当中 ::: 区块是在CMS插件模块中提供的。因此,我们延续前面已经创建的插件模块`test-cmspluginhello`,制作一个区块`iframe` > 如何制作插件,请参见:[开发篇 - 制作插件](https://cabloy.com/zh-cn/articles/7db5180043074119ac53515daec5dcf1.html) ## 1. 引用区块及Schema 在模块的`meta`中引用`区块`及`Schema` `src/module/test-cmspluginhello/backend/src/meta.js` ``` javascript module.exports = app => { const schemas = require('./config/validation/schemas.js')(app); const blocks = require('./config/blocks.js')(app); const meta = { ... validation: { validators: { blockIFrame: { schemas: 'blockIFrame', }, }, keywords: {}, schemas: { blockIFrame: schemas.blockIFrame, }, }, cms: { plugin: { blocks, }, }, }; return meta; }; ``` | 名称 | 说明 | |----|----| | cms.plugin.blocks | 本模块所提供的区块清单 | | validation.validators.blockIFrame | 区块所对应的validator | | validation.schemas.blockIFrame | 区块所对应的schema | ## 2. 定义区块 `src/module/test-cmspluginhello/backend/src/config/blocks.js` ``` javascript module.exports = app => { const blockIFrame = require('./block/iframe.js')(app); return { blockIFrame, }; }; ``` `src/module/test-cmspluginhello/backend/src/config/block/iframe.js` ``` javascript module.exports = app => { const block = { validator: 'blockIFrame', bean: 'iframe', }; return block; }; ``` | 名称 | 说明 | |----|----| | validator | 区块的验证器,用于区块编辑页面的渲染与参数验证 | | bean | 区块Bean组件,用于内容渲染 | ## 3. 定义Bean组件 `src/module/test-cmspluginhello/backend/src/bean/cms.block.iframe.js` ``` javascript module.exports = ctx => { class CMSBlock { render({ md, options, block, token, index, content }) { const url = md.utils.escapeHtml(content.url); const width = md.utils.escapeHtml(content.width || '100%'); const height = md.utils.escapeHtml(content.height || '300px'); return `
\n`; } } return CMSBlock; }; ``` | 名称 | 说明 | |----|----| | md | MarkdownIt实例对象,参见: [MarkdownIt](https://markdown-it.github.io/markdown-it/#MarkdownIt) | | md.utils.escapeHtml | 特别的,经常需要通过此方法对用户输入的内容进行安全转译,从而避免`注入漏洞`的发生 | | options | 扩展参数 | | options.utils.text | 通过此方法返回国际化字符串 | | options.blocks | 所有区块清单 | | block | 区块的对象定义 | | token | MarkdownIt渲染参数 | | index | MarkdownIt渲染参数 | | content | 用户输入的内容 | ## 4. 注册Bean组件 `src/module/test-cmspluginhello/backend/src/beans.js` ``` javascript const cmsBlockIFrame = require('./bean/cms.block.iframe.js'); module.exports = app => { const beans = { // block 'cms.block.iframe': { mode: 'ctx', bean: cmsBlockIFrame, }, }; return beans; }; ``` | 注册名称 | 场景 | 所属模块 | global | beanFullName | |----|----|----|----|----| | iframe | cms.block | test-cmspluginhello | false | test-cmspluginhello.cms.block.iframe | ## 5. 定义Schema `JSON Schema`用来验证用户输入的数据是否符合预期,如果不符合预期,就会有醒目的提示 > 关于JSON Schema,请参见:[表单验证](https://cabloy.com/zh-cn/articles/form-validation.html) `src/module/test-cmspluginhello/backend/src/config/validation/schemas.js` ``` javascript module.exports = app => { const schemas = { }; // block iframe schemas.blockIFrame = { type: 'object', properties: { url: { type: 'string', ebType: 'text', ebTitle: 'URL', format: 'uri', notEmpty: true, }, width: { type: 'string', ebType: 'text', ebTitle: 'Width', }, height: { type: 'string', ebType: 'text', ebTitle: 'Height', }, }, }; return schemas; }; ``` ## 6. 后端资源定义 在一个复杂的系统中,会涉及到`资源授权`的问题,我们需要对区块进行`权限控制`。模块`a-cms`提供了一个资源类型`a-cms:block`,只需定义`静态资源`,并指定角色,即可同时完成资源的注册与初始授权 ### 6.1 定义静态资源 定义一个`静态资源`数组 `src/module/test-cmspluginhello/backend/src/config/static/resources.js` ``` javascript module.exports = app => { const moduleInfo = app.meta.mockUtil.parseInfoFromPackage(__dirname); const resources = [ // cms block { atomName: 'Embed Page', atomStaticKey: 'blockIFrame', atomRevision: 0, atomCategoryId: 'a-cms:block.General', resourceType: 'a-cms:block', resourceConfig: JSON.stringify({ default: { url: '', width: '', height: '', }, validator: { module: moduleInfo.relativeName, validator: 'blockIFrame', }, }), resourceRoles: 'root', }, ]; return resources; }; ``` | 名称 | 说明 | |----|----| | atomStaticKey | 系统自动添加模块名称前缀,生成`test-cmspluginhello:blockIFrame` | | atomCategoryId | 资源归属目录。资源类型全称`a-cms:block:button`作为一级目录 | | resourceType | 资源类型全称 | | resourceConfig | 资源配置信息 | | resourceConfig.default | 区块的缺省值 | | resourceConfig.validator | 区块的验证器 | | resourceRoles | 资源授权对象,这里是角色`root` | > 角色`root`是整个角色树的根,也就意味着所有用户(包括`匿名用户`)均可访问此`资源` > 更多配置说明,参见[静态资源](https://cabloy.com/zh-cn/articles/resource-static.html) ### 6.2 注册静态资源 前面定义好一组`静态资源`,接下来就需要在模块的`meta`文件中进行注册 `src/module/test-cmspluginhello/backend/src/meta.js` ``` javascript const staticResources = require('./config/static/resources.js')(app); base: { statics: { 'a-base.resource': { items: staticResources, }, }, }, ``` | 名称 | 说明 | |----|----| | a-base.resource | 原子类型的全称。在这里,原子类型`resource`是由模块`a-base`提供的 | | items | 静态资源数组 |