·设为首页收藏本站📧邮箱修改🎁免费下载专区💎积分✅卡密📒收藏夹👽聊天室
返回列表 发布新帖

Discuz! X5.0 开发技术文档 新增插件接口

7 0
发表于 前天 21:25 | 查看全部 阅读模式 | Google Chrome| Windows 10

马上注册,免费下载更多dz插件网资源。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
新增系统函数DISCUZ_PLUGIN()
X5.0 中新增了 DISCUZ_PLUGIN() 函数,代替类似“/source/plugin/xxx”目录的写法,例如:
  • require_once DISCUZ_PLUGIN('xxx').'/index.php';
提示:如果您的插件要同时兼容 Discuz!ᵂ 您必须使用此函数,但是,涉及前端调用的路径写法是 URI 的一部分,而非后台目录文件调用,无需修改。
DISCUZ_TEMPLATE()
X5.0 中新增了 DISCUZ_TEMPLATE() 函数,代替类似“/template/xxx”目录的写法,例如:
  • $f = DISCUZ_TEMPLATE('xxx').'/data.htm';
提示:如果您的插件要同时兼容 Discuz!ᵂ 您必须使用此函数,但是,涉及前端调用的路径写法是 URI 的一部分,而非后台目录文件调用,无需修改。
新增系统常量DISCUZ_DATA
X5.0 中新增了 DISCUZ_DATA 常量,代替类似“/data”目录的写法,例如:
  • $lock = DISCUZ_DATA.'cache/data.php';
提示:如果您的插件要同时兼容 Discuz!ᵂ 您必须使用此函数。由于 Discuz!ᵂ 中所有永久性文件都会存入对象存储,因此 DISCUZ_DATA 目录禁止写入永久文件,否则审核员有权将应用打回。
DISCUZ_ROOT_STATIC
对于 Discuz!ᵂ,由于 /data 目录禁止写入,您可以把永久文件写入到此目录中,它有以下特性:
  • 此目录与 DISCUZ_ROOT 意义相同,但只有存放的静态文件(md、txt、js、css、json、xml、图片等)可对外展示;
  • 如保存的文件和实际产品文件及路径相同,不会产生覆盖效果,也不会对外展示;
  • 此目录占用的空间将计算到 Discuz!ᵂ 用户的平台存储中;
提示:此常量只针对 Discuz!ᵂ 有实际作用,X5.0 开源版此常量与 DISCUZ_ROOT 相等。
多语言
Discuz!ᵂ 原生支持多语言内核,您只需自定义多语言 key 并设置此 key 对应的语言包文件路径即可
设置自定义语言
  • i18n('set', 'mylang', DISCUZ_ROOT.'./i18n/en');
设置多语言 mylang 的语言包文件路径为 DISCUZ_ROOT.’/i18n/en’ 目录,支持插件路径
读取设置的自定义语言列表
  • i18n('get');
把设置的语言 key 赋值给 $_G[‘cookie’][‘i18n’] 即可实时切换语言
其他第三方插件若要兼容 i18n 对应的语言 key,参考此范例 https://gitee.com/Discuz/DiscuzXPluginSample/tree/master/sample/i18n/mylang
自定义后台菜单
这是 Discuz!ᵂ 中的新增内容,插件无需添加 menu 扩展,即可实现菜单的添加与删除
您所添加的菜单请务必在卸载插件后清理完毕
准备工作
如果在非安装、卸载脚本中使用,最好是判断下方法是否存在
示例:
  • if(!function_exists('set_admin_menu')){
  •         include_once libfile('function/plugin');
  • }
添加菜单
完整示例:
  • if(!function_exists('set_admin_menu')){
  •         include_once libfile('function/plugin');
  • }
  • $menus = array(
  •     array('侧边菜单1','plugins?id=1'),
  •     array('侧边菜单2','plugins?id=2'),
  • );
  • set_admin_menu('顶部菜单名称', $menus);
删除菜单
完整示例:
  • if(!function_exists('remove_admin_menu')){
  •         include_once libfile('function/plugin');
  • }
  • remove_admin_menu('顶部菜单名称');//单独删除
  • remove_admin_menu(array('顶部菜单名称1','顶部菜单名称2'));//批量删除
自定义新平台
这是 Discuz!ᵂ 中的新增内容,开发者可直接添加一个平台管理中心,在这里,您可以完全设计整个后台的菜单以及界面。同时在“站长”->“多平台管理” 站长还能自行调整。
XML 格式规范
这是平台配置 XML 文件的模板:
  • <?xml version="1.0" encoding="ISO-8859-1"?>
  • <root>
  •     <name><![CDATA[新平台]]></name>
  •     <title><![CDATA[新平台]]></title>
  •     <framecss><![CDATA[xxx.css]]></framecss>
  •     <pagecss><![CDATA[ccc.css]]></pagecss>   
  •     <logo><![CDATA[<a class="logo"><img src="static/image/admincp/logo.svg"></a>]]></logo>
  •     <navbar><![CDATA[<form></form>]]></navbar>
  •     <menu>
  •         <menuId>主菜单1</menuId>
  •         <sub>
  •             <subId>action_operation_do1</subId>
  •             <title>子菜单1</title>
  •         </sub>
  •         <sub>
  •             <subId>action_operation_do2</subId>
  •             <title>子菜单2</title>
  •         </sub>
  •     </menu>
  •     <menu>
  •         <menuId>主菜单2</menuId>
  •         <sub>
  •             <subId>plugin_id:pmod1</subId>
  •             <title>子菜单3</title>
  •         </sub>
  •         <sub>
  •             <subId>plugin_id:pmod2</subId>
  •             <title>子菜单4</title>
  •         </sub>
  •     </menu>
  •     <userdef><![CDATA[1]]></userdef>
  • </root>
  • name:平台名称,在多平台列表中展示的名称;
  • title:平台网页标题,显示在浏览器标题栏中的名称;
  • logo:左上角 LOGO 区域 HTML;
  • navbar:右侧搜索区域 HTML;
  • framecss:框架页 CSS,可直接写 CSS 代码,也可以写文件 URL (.css 结尾);
  • pagecss:内容页 CSS,规则同 framecss;
  • menu:主菜单节点,多个主菜单按照顺序书写;
  • menuId:菜单 ID、外显名称,可写语言包名或中文;
  • sub 子菜单节点;
  • subId:子菜单 ID,格式“action_operation_do”,action、operation、do 为相应页面 GET 参数拼接的内容,opeartion、do 可省略;如果是跳转到插件页面,格式为 “plugin_id:pmod”,id 为插件唯一标识符 ID,pmod 为后台模块的参数,pmod 可省略;
  • title:外显名称,可写语言包名或中文;
  • type:1=区域开始,2=区域结束;
  • showMethod:显示此菜单项的条件,外调方法,系统值不建议修改。插件用 id::method 方式调用具体方法,系统会调用 plugin/id/ 中 class platform_id 的静态方法 method();
  • listMethod:菜单显示内容由具体方法返回,格式同 showMethod;
  • subPerms:当前菜单项关联的其他子菜单 ID,多个用逗号“,”分割, ID 格式见 subId;
添加平台
  • $xml = '<?xml version="1.0" encoding="ISO-8859-1"?>
  • ...
  • ';
  • menu::platform_add('test', $xml); // test 为平台标识,$xml 为配置数据
删除平台
  • menu::platform_del('test');// test 为平台标识
platform.class.php 详解
开发者需书写一个 platform.class.php 脚本
plugin/myplugin/platform.class.php 完整示例:
  • class platform_myplugin {
  •         // myplugin:showMethodSample
  •     public static function showMethodSample() {
  •         return true;
  •     }        
  •         // myplugin:listMethodSample
  •     public static function listMethodSample() {
  •         return array(
  •             array('menu_members_edit', 'members_search', 0, '', '', array('members_clean', 'members_repeat')),
  •             array(cplang('nav_home'), '', 1, 'homestatus'),
  •             array('menu_maint_doing', 'doing', 0, 'doingstatus'),
  •             array('menu_maint_share', 'share', 0, 'sharestatus'),
  •             array(cplang('nav_home'), '', 2, 'homestatus'),
  •         );
  •     }
  • }
showMethodSample 为 showMethod 的范例,返回 true/false 即可,true 时菜单项显示
listMethodSample 为 listMethod 的范例,返回的内容会替换掉相应位置中的数据。其中返回的数组与 XML 中 sub 下节点的对应关系为:
0:title
1:subId
2:type
3:showMethod
4:listMethod
5:subPerms
第三方登录
由于 X5.0 增加了全新的账号管理系统,通过此全新的账号平台,开发者可很方便的开发出自己的登录系统
第三方登录类固定的文件为 /acccount.class.php,例如插件目录为 sample,那么文件为 /source/plugin/sample/account.class.php
  • class account_sample extends account_base {
  •     // 不自动生成头像
  •     public bool $interface_noAutoAvatar = true;
  •     // 不支持绑定
  •     public bool $interface_noBind = false;
  •     public function __construct() {
  •         $this->conf = parent::getConfig('plugin_sample');
  •     }
  •     public static function name() {
  •         return '测试登录';
  •     }
  •     public static function icon() {
  •         return '<svg t="1715821283732" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="28056" width="20" height="20"><path d="M840.7 626.2c-33.3 33.3-144 23.5-144 23.5s-9.7-110.7 23.5-144c33.3-33.3 77.3-0.5 77.3 43.2 44.3 0 76.5 44 43.2 77.3zM611.2 560.7c-29.7 0-53.9-24.3-53.9-53.9V245.3c0-29.7 24.3-53.9 53.9-53.9 29.7 0 53.9 24.3 53.9 53.9v261.5c0 29.7-24.3 53.9-53.9 53.9zM226.3 614.7c-29.7 0-53.9-24.3-53.9-53.9V338.5c0-29.7 24.3-53.9 53.9-53.9 29.7 0 53.9 24.3 53.9 53.9v222.2c0.1 29.7-24.2 54-53.9 54zM482.9 551.5c-29.7 0-53.9-24.3-53.9-53.9V121.2c0-29.7 24.3-53.9 53.9-53.9 29.7 0 53.9 24.3 53.9 53.9v376.3c0 29.7-24.2 54-53.9 54zM354.6 571.5c-29.7 0-53.9-24.3-53.9-53.9v-337c0-29.7 24.3-53.9 53.9-53.9 29.7 0 53.9 24.3 53.9 53.9v337c0.1 29.7-24.2 53.9-53.9 53.9zM445.7 960c-67.4 0-130.8-26.2-178.4-73.9-47.7-47.7-73.9-111-73.9-178.4 0-18.2 14.8-33 33-33s33 14.8 33 33c0 102.8 83.6 186.4 186.4 186.4 102.8 0 186.4-83.6 186.4-186.4 0-18.2 14.8-33 33-33s33 14.8 33 33c0 67.4-26.2 130.8-73.9 178.4S513.1 960 445.7 960z" fill="#E95431" p-id="28057"></path></svg>';
  •     }
  •     // 通知发送
  •     public function notificationAdd($touid, $note, $notestring) {
  •     }
  •     // 用于自动登录,判断是否在环境中
  •     public function inEnv() {
  •         return isset($_SERVER['HTTP_USER_AGENT']) && strpos($_SERVER['HTTP_USER_AGENT'], 'xxx');
  •     }
  •     // 登录(绑定)跳转
  •     public function login($referer = '', $op = 0) {
  •         if(empty($_POST)) {
  •             echo
  •             <<<EOF
  • <form method="post" action="$_SERVER[PHP_SELF]?method=plugin_sample">
  •     User:<input name="user"><br />
  •     Pass:<input name="pass" type="password"><br />
  •     <input type="submit">   
  • </form>
  • EOF;
  •         } else {
  •             $data = array(
  •                 'test1' => array('pass' => '1', 'uid' => 'sampleUid1'),
  •                 'test2' => array('pass' => '1', 'uid' => 'sampleUid2'),
  •             );
  •             if(!isset($data[$_POST['user']])) {
  •                 echo 'User not found';
  •                 exit;
  •             }
  •             if($data[$_POST['user']]['pass' != $_POST['pass']) {
  •                 echo 'Password error';
  •                 exit;
  •             }
  •             $callback = $this->conf['callbackUrl'].'&uid='.$data[$_POST['user']]['uid'];
  •             echo '<a href="'.$callback.'">callback</a>';
  •         }
  •         exit;
  •     }
  •     // 登录回调,/api/account/callback.php?id=sample 会调用此方法
  •     public function getLoginUser() {
  •         global $_G;
  •         $account = new account();
  •         $param = array(
  •             'type' => 'plugin_sample',
  •             'atype' => parent::getAccountType('sample'),
  •             'account' => $_GET['uid'],
  •             'bindname' => $_GET['uid'],
  •         );
  •         if(!$account->checkUser($param)) {
  •             if($_G['uid']) {
  •                 $account->userBind($_G['uid'], $param);
  •             } else {
  •                 $param += array(
  •                     'username' => $_GET['uid'],
  •                     'password' => '',
  •                 );
  •                 $msg = $account->userRegister($param);
  •                 if($msg) {
  •                     if($msg == 'profile_username_duplicate' || $msg == 'profile_email_duplicate') {
  •                         dheader('Location: '.$_G['siteurl'].'?index=member&mod=register');
  •                     }
  •                     showmessage($msg);
  •                 }
  •             }
  •         } else {
  •             $account->userLogin();
  •         }
  •         dheader('Location: '.$_G['siteurl']);
  •     }
  •     // 管理后台
  •     public function admincp() {
  •         global $_G;
  •         $conf = $_G['setting']['account_plugin_confs']['sample'];
  •         if(!submitcheck('submit')) {
  •             showformheader('account&method=plugin_sample');
  •             ...
  •             showformfooter();
  •         } else {
  •             ...
  •             cpmsg('setting_update_succeed', 'action=account&method=plugin_sample', 'succeed');
  •         }
  •     }
  • }
DIY 模块
X5.0 允许通过插件拓展 DIY 的模块,您需要把 DIY 模块文件写到 /source/plugin/myplugin/block 目录下即可,目录中文件的内容同系统 /source/class/block。
子文件
由于 X5.0 用子文件 /source/child 代替了原先的 /source/include 目录,因此您可以通过注册接管的方式完全代替任何一个系统子文件的原始调用,您需要把子文件写到 /source/plugin/myplugin/child 目录下。
  • <?php
  • //childfile:forum/viewthread/postarr
  • if(!defined('IN_DISCUZ')) {
  •     exit('Access Denied');
  • }
  • ...
文件中添加 //childfile:…… 格式的注释,注册需要接管子文件。您可以在自己接管的子文件中,完全代替系统原有的逻辑,也可以继续调用系统原有逻辑,并在其之前、之后调用自己的逻辑。
forum/viewthread/postarr 表示接管 /source/app/forum/child/viewthread/postarr.php 文件。
global/core/ip 表示接管 /source/child/core/ip.php 文件。
友情提示:由于子文件接管的特殊性,同一个子文件有且只有一个插件接管。admin/* 禁止接管。
日志系统
X5.0 对系统的日志进行了全面的优化和开放,您可以把插件的日志接入到此处,站长可以在“操作日志”处统一查看。
添加日志的方法通过以下系统函数
  • logger('myplugin_text', $_G['member'], $_G['member']['uid'], array('p' => $text, 't' => $time));
myplugin_text 中,myplugin 为插件ID,text 为自定义日志类型。后续参数可酌情添加。
日志后台文件写到 /source/plugin/myplugin/log 目录下,文件名固定为 log_日志类型.php,例如上例中的 log_text.php
  • <?php
  • if(!defined('IN_DISCUZ') || !defined('IN_ADMINCP')) {
  •     exit('Access Denied');
  • }
  • showtableheader('', 'fixpadding');
  • showtablerow('class="header"', array('class="td23"', 'class="td24"', 'class="td23"', 'class="td23"', 'class="td23"'), array(
  •     cplang('time'),
  •     'text',
  •     cplang('logs_device'),
  • ));
  • foreach($logs as $k => $logrow) {
  •     $data = json_decode($logrow['data'], true);
  •     $device = json_decode($logrow['device'], true);
  •     showtablerow('', array('class="smallefont"', 'class="smallefont"', 'class="bold"', 'class="smallefont"', 'class="smallefont"'), array(
  •         dgmdate($logrow['dateline']),
  •         is_array($data['p']) ? print_r($data['p'], 1) : $data['p'],
  •         $_G['group']['allowviewip' ? 'ClientIP: '.$device['client_ip'].'&nbsp;&nbsp;<a href="javascript:;"pun" style="box-sizing: border-box; color: rgb(102, 102, 0);">.$logrow['id'].')">'.cplang('more').'</a>' : '-',
  •     ));
  •     echo showdevice($logrow['id'], $device, 6);
  • }
管理中心小组件
X5.0 的管理中心首页可通过小组件的方式进行拓展,要增加小组件您需要将脚本写到 /source/plugin/myplugin/admin/admin_widget.php 文件中,文件结构为:
  • <?php
  • namespace myplugin;
  • if(!defined('IN_DISCUZ') || !defined('IN_ADMINCP')) {
  •     exit('Access Denied');
  • }
  • class admin_widget {
  •     public static function widget_a() {
  •     }
  •     public static function widget_b_left() {
  •     }
  •     ...
  • }
adminwidget 类中可以写多个 “widget” 开头的小组件方法,默认小组件位于右侧,如果想写左侧的小组件,请让方法名以 “_left” 结尾。
设置项组件
X5.0 中可以定义自己的设置项,要增加设置项组件您需要将脚本写到 /source/plugin/myplugin/admin/component 目录中,一个文件一个组件,每个文件都以 component_ 开头命名,文件结构为:
component_a.php
  • <?php
  • namespace myplugin\admin;
  • if(!defined('IN_DISCUZ') || !defined('IN_ADMINCP')) {
  •     exit('Access Denied');
  • }
  • class component_a {
  •     var $name = '组件名称';
  •     // 编辑时显示的内容
  •     function show(&$var, &$extra) {
  •         ...
  •     }
  •     // 数据提交入口后进行打包
  •     function serialize($params, &$value) {
  •         ...
  •     }
  •     // 数据重新编辑前进行解包
  •     function unserialize($params, &$value) {
  •         ...
  •     }
  • }
定义后,插件代码中可用下面的函数进行调用:
  • showcomponent('测试1', 'abc1', 'yellow', 'myplugin:component_a');
表单提交后需要通过下面的函数对组件的数据进行序列化封装
  • serializecomponent();
自定义多媒体代码解析脚本
X5.0 中可以自定义 [media] 标签中视频解析的脚步,要增加新的解析脚本您需要将脚本写到 /source/plugin/myplugin/media 目录中,一个文件一个脚本,每个文件都以 media_ 开头命名,文件结构为:
media_video.php
  • <?php
  • namespace myplugin;
  • class media_video {
  •     public static $version = '1.0';
  •     public static $name = 'name';
  •     public static $checkurl = ['video.com/'];
  •     public static function parse($url, $width, $height) {
  •         if(preg_match('/^https?:\/\/video.com\/(\d+)/i', $url, $matches)) {
  •             $iframe = 'https://www.video.com/iframe/'.$matches[1];
  •             $flv = $imgurl = '';
  •         }
  •         return [$flv, $iframe, $url, $imgurl];
  •     }
  • }
分类信息类型
X5.0 中可以定义自己的分类信息类型,要增加新的类型您需要将脚本写到 /source/plugin/myplugin/threadtype 目录中,一个文件一个类型,每个文件都以 threadtype_ 开头命名,文件结构为:
threadtype_a.php
  • <?php
  • namespace myplugin;
  • if(!defined('IN_DISCUZ') || !defined('IN_ADMINCP')) {
  •     exit('Access Denied');
  • }
  • class threadtype_a {
  •     var $name = '类型名称';
  •     // 编辑时显示的内容
  •     function show($option, $params) {
  •         ...
  •     }
  •     // 结果输出时显示的内容
  •     function view($viewtype, $option, $params, $value) {
  •         ...
  •     }
  •     // 数据提交入口后进行打包
  •     function serialize($params, &$value) {
  •         ...
  •     }
  •     // 数据重新编辑前进行解包
  •     function unserialize($params, &$value) {
  •         ...
  •     }
  • }
JSON编辑器区块
X5.0 引入了全新的JSON编辑器,基于 Editor.js 内核,是区块风格(Block-Styled)编辑器,具有干净JSON输出的块样式,同时,让编辑器有更多的自由性和可扩展性。块是构成条目的结构单元,例如,Paragraph,Heading,Image,Video,List都是块。每个块由插件表示,以热插拔的形式灵活为编辑器扩展功能。
可以通过插件方式为JSON编辑器扩展功能区块,您需要把区块文件写到 /source/plugin/myplugin/editorblock 目录下。
区块类固定以 editorblock_自定义区块英文标识.php 命名, 如 editorblock_myBlock.php ,放在 editorblock 根目录,区块 js、css 静态资源放入 editorblock/tools/myBlock 目录下。
目录结构
  • editorblock   // 固定命名
  • ├── tools   // 固定命名
  •     ├── myBlock   // 自定义区块英文标识
  •         ├── myBlock.js    // 自定义区块核心js
  •         ├── myBlock.css    // 自定义区块核心css
  • ├── editorblock_myBlock.php        // 自定义区块核心类
区块核心类书写范例
以下是区块核心类书写范例,其中 getConfig() 、 getStyle() 、 getParser() 将支持后台在线编辑,即,用户可以自由定义区块展示结构与样式。
  • class editorblock_myBlock {
  •     var $version = '1.0.5'; // 版本
  •     var $name = '自定义区块名称'; // 区块名称
  •     var $available = 1; // 默认启用状态 0:不启用 1:启用
  •     var $columns = 1; //  默认是否支持多列 0:不支持 1:支持
  •     var $identifier = 'myBlock'; // 自定义区块标识
  •     var $description = '插入联系方式信息区块,可用于插入电话、微信号、QQ号等,添加内容格式为:类型标识(mobile、wechat、qq)/联系人名称/联系方式(电话、微信等)';  // 区块描述
  •     var $filename = 'myBlock';  // 区块文件名,与自定义区块标识一致即可
  •     var $copyright = '云诺';  // 版权,显示在后台JSON区块列表中
  •     var $type = '0'; // 0:数据类型 1:图片类型 2:附件类型
  •     function __construct() {
  •     }
  •     // 区块 数据结构 示例,参照 Editor.js 区块数据结构
  •     function getParameter() {
  •         return <<<EOF
  • {
  •     "data": {
  •             "channelType": "mobile", // mobile、wechat、qq
  •         "channelName": "云诺",
  •         "messageId": 123456
  •     },
  •     "id": "ZT8S70Q34G", // 区块id
  •     "type": "myBlock" // 区块类型
  • }
  • EOF;
  •     }
  •     /*
  •      * 区块 config 配置,参照 Editor.js 区块配置
  •      *
  •      * 结构(左顶头):
  •      *     {
  •      *         tools_自定义区块英文标识: {
  •      *             自定义区块英文标识: {
  •      *                 ...
  •      *             }
  •      *         }
  •      *     }
  •      */
  •     function getConfig() {
  •         return <<<EOF
  • {
  •    tools_myBlock: {
  •       myBlock: {
  •          class: myBlock,
  •          tunes: ['anchorTune'
  •       },
  •    }
  • }
  • EOF;
  •     }
  •     // 尚未启用
  •     function getI18n() {
  •         return <<<EOF
  • EOF;
  •     }
  •     // 区块在编辑器中的 显示样式 配置
  •     // CSS样式代码部分必须严格书写在<style type="text/css">......</style>内部。
  •     function getStyle() {
  •         return <<<EOF
  • <style type="text/css">
  • .ce-block {
  •     /* margin-bottom: 20px; */
  • }
  • .ce-block__content,.ce-toolbar__content {
  •     /* max-width:calc(100% - 50px) */
  •     margin-left: auto;
  •     margin-right: auto;
  • }
  • .ce-myBlock {
  •     position: relative;
  •     float: left;
  •     width: 280px;
  •     height: auto;
  •     padding: 15px 10px 15px 20px;
  •     box-sizing: border-box;
  •     border: 1px solid #3f9dffa3;
  •     border-radius: 50px;
  •     margin: 10px 15px;
  • }
  • .ce-myBlock dl {
  •     margin: 0
  • }
  • .ce-myBlock dl dt {
  •     width: 50px;
  •     height: 50px;
  •     float: left;
  •     position: relative;
  •     margin-right: 12px;
  • }
  • .ce-myBlock dl dt svg {
  •     width: 100%;
  •     height: 100%
  • }
  • .ce-myBlock dl dd {
  •     float: left;
  •     position: relative;
  • }
  • .ce-myBlock dl dd h3 {
  •     height: 20px;
  •     line-height: 20px;
  •     font-size: 14px;
  •     margin-top: 5px;
  • }
  • .ce-myBlock dl dd h3 em {
  •     font-style: normal;
  •     margin-left: 5px;
  •     color: #fa5555;
  •     font-size: 12px;
  • }
  • .ce-myBlock dl dd p.p1 {
  •     color: #999;
  • }
  • .ce-myBlock dl dd p {
  •     width: 185px;
  •     height: 20px;
  •     line-height: 20px;
  •     margin-top: 5px;
  •     white-space: nowrap;
  •     overflow: hidden;
  •     text-overflow: ellipsis;
  • }
  • </style>
  • EOF;
  •     }
  •     // 区块 解析模板 配置,解析模板开发方式见下文
  •     function getParser($block = array()) {
  •         global $_G;
  •         return <<<EOF
  • <div class="ce-block ce-block--focused" data-id="{id}" [if tunes.anchorTune.anchor=notnullid="{tunes.anchorTune.anchor}"[/if]>
  •     <div class="ce-block__content">
  •         <div class="ce-myBlock ">
  •             <dl>
  •                 <dt>
  •                     [if data.channelType=mobile
  •                     <svg t="1705559455679" class="icon" viewBox="0 0 1025 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="69723" width="80" height="80"><path d="M511.484254 0.066515C227.987504 0.066515-0.001023 227.399103-0.001023 510.114047c0 282.71392 227.987504 512.917906 511.485277 512.917906 283.461957 0 511.48016-230.203986 511.48016-512.917906C1022.964414 227.399103 794.94621 0.066515 511.484254 0.066515zM762.853281 772.349563l-57.003272 43.768853c-54.072523 16.044418-187.064466 42.271756-352.206644-190.872189-187.063443-252.120135-112.512517-394.946051-84.758406-419.698804l59.904345-42.270732 24.854061 7.306406 100.833523 145.69629-2.901073 23.320125-58.471716 40.803311c-26.28669 21.851681-8.772804 49.541323 10.237155 101.988836 17.543561 30.625508 57.003272 91.816149 83.290985 115.137297 45.297672 37.896098 65.777099 62.684668 96.468099 45.201481l55.505152-39.333844 21.977547 2.871397 105.142665 141.357472L762.853281 772.349563z" fill="#18CC73" p-id="69724"></path></svg>
  •                     [/if
  •                     [if data.channelType=wechat
  •                     <svg t="1705558999833" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="47545" width="80" height="80"><path d="M512 1.896C229.452 1.896 0 229.452 0 512s229.452 510.104 512 510.104S1022.104 794.548 1022.104 512 794.548 1.896 512 1.896z m-91.022 629.57c-26.548 0-49.304-5.688-75.852-11.377l-75.852 37.926 22.756-66.37c-54.993-37.926-87.23-87.23-87.23-147.912 0-104.296 98.607-185.837 218.074-185.837 108.089 0 201.007 64.474 219.97 153.6-7.585 0-13.274-1.896-20.859-1.896-104.296 0-185.837 77.748-185.837 172.563 0 15.17 1.896 30.34 7.585 45.511-7.585 3.793-15.17 3.793-22.755 3.793z m322.37 77.749l17.067 54.992-58.785-34.133c-22.756 5.689-43.615 11.378-66.37 11.378-104.297 0-185.838-70.163-185.838-157.393S530.963 424.77 635.26 424.77c98.608 0 185.837 70.163 185.837 159.29 0 47.407-32.237 91.021-77.748 125.155z" fill="#46BB36" p-id="47546"></path><path d="M318.578 379.26c0 17.066 13.274 30.34 30.34 30.34s30.341-13.274 30.341-30.34-13.274-30.341-30.34-30.341-30.341 13.274-30.341 30.34z m235.14 159.288c0 13.274 11.378 24.652 24.652 24.652 13.274 0 24.652-11.378 24.652-24.652 0-13.274-11.378-24.652-24.652-24.652-13.274-1.896-24.651 9.482-24.651 24.652z m-81.54-159.289c0 17.067 13.274 30.341 30.34 30.341 17.067 0 30.341-13.274 30.341-30.34 0-17.067-13.274-30.341-30.34-30.341-17.067 0-30.341 13.274-30.341 30.34zM675.08 538.55c0 13.273 11.378 24.651 24.652 24.651 13.274 0 24.652-11.378 24.652-24.652 0-13.274-11.378-24.652-24.652-24.652-13.274-1.896-24.652 9.482-24.652 24.652z" fill="#46BB36" p-id="47547"></path></svg>
  •                     [/if
  •                     [if data.channelType=qq
  •                     <svg t="1705559232025" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="57063" width="80" height="80"><path d="M511.500488 512.499512m-511.500488 0a511.500488 511.500488 0 1 0 1023.000976 0 511.500488 511.500488 0 1 0-1023.000976 0Z" fill="#1BC1FA" p-id="57064"></path><path d="M784.234146 572.440976c8.178014 0 16.273108 0.253752 24.282287 0.728288-16.961436-38.434466-42.247742-69.886751-58.977405-90.331785 2.822244-8.482716 11.30496-56.536788-25.443153-90.453666v-2.827239c0-132.850263-96.103149-231.785647-214.822213-231.785647-118.717065 0-214.82521 96.107145-214.825209 231.785647v2.827239c-33.915879 33.915879-25.437159 81.969951-19.782681 90.453666-25.444152 28.265397-73.49223 87.62343-76.320469 155.461182 0 16.961436 2.827239 45.226833 11.305959 56.531794 11.305959 14.133198 39.570357-2.827239 62.186272-48.054073 5.650482 19.788675 19.78368 53.709549 50.876316 93.281905-50.876316 11.302962-65.009514 62.186271-48.049077 90.450669 11.305959 19.788675 39.570357 33.920874 87.624429 33.920874 78.496343 0 115.815899-19.378076 134.378771-35.711126C492.644901 814.680414 490.520976 800.136617 490.520976 785.233171c0-117.522232 131.500581-212.792195 293.71317-212.792195z" fill="#FFFFFF" p-id="57065"></path><path d="M514.925143 819.204995c5.654478 0 11.309955 2.82624 14.132199 5.649483 16.960437 16.960437 53.709549 39.575352 138.50674 39.575352 48.054072 0 76.320468-16.960437 87.625428-33.920874 16.960437-28.264398 2.827239-79.147707-48.054072-90.450669 31.092636-39.572355 45.225834-73.493229 50.881311-93.281905 19.787676 45.226833 50.881311 62.18727 62.186271 48.054073 2.827239-11.30496 5.650482-39.570357 5.650482-56.531794-1.93511-23.223321-8.508691-45.121936-17.337069-65.128398-8.009179-0.475536-16.104273-0.729288-24.282287-0.729287-162.212589 0-293.713171 95.269963-293.71317 212.792195 0 14.903446 2.123926 29.447243 6.147996 43.485533a88.18688 88.18688 0 0 0 4.122973-3.864226c2.827239-2.823243 8.481717-5.649483 14.133198-5.649483z" fill="#FFFFFF" opacity=".4" p-id="57066"></path></svg>
  •                     [/if
  •                 </dt>
  •                 <dd>
  •                     <h3 class="comm" imagentlist="">{data.channelName}<em></em></h3>
  •                     <p class="p1"><em>{data.messageId}</em></p>
  •                 </dd>
  •             </dl>
  •         </div>
  •     </div>
  • </div>
  • EOF;
  •     }
  • }
区块核心JS开发方式
以 Editor.js 编辑器区块开发方式开放即可。
区块解析模板开发
变量使用方式:{字段名} , 多层级使用 . 进行连接, 如:{字段名1.字段名2.字段名3} ;
变量使用方式示例如:{id} 、 {type} 、 {data.alignment} 、 {data.items.text} ;
支持 [loop] 循环,示例区块代码如:
  • {
  •     "data": {
  •         ...
  •         "items": [
  •             {
  •                 "text" : "abc"
  •             },
  •             {
  •                 "text" : "def"
  •             },
  •             ...
  •         
  •     }
  • }
循环使用方式:
  • <ul>
  • [loop data.items]
  •    <li>{text}</li>
  • [/loop]
  • </ul>
循环索引(放到循环体内部,自动计数):
  • [loopindex
多列渲染(放到循环体内部,指定子数据块,仅用于多列渲染):
  • [column blocks
IF判断方式:
  • [if data.items=1
  •    {text}块数据变量 或者 普通字符串
  • [/if
URL转换绝对网址:
  • [url data.file.url
区块解析模板样式CSS开发
如区块前端解析需要css样式支持,可编写独立的 myBlock.css 文件,并使用 viewthread_postbottom 嵌入点往页面中植入该css文件。
  • class plugin_myplugin_forum extends plugin_myplugin {
  •     function viewthread_postbottom() {
  •         $postbottom[0 = '<link rel="stylesheet" type="text/css" href="source/plugin/myplugin/editorblock/tools/myBlock/myBlock.css?'.getglobal('style/verhash').'" />';
  •         return $postbottom;
  •     }
  • }
支付
通过拓展支付,可以让应用无需做额外过多的开发即可之间接入 Discuz! 系统的支付体系。甚至自定义一个新的支付通道。
自定义支付入口
  • payment::enable:是否启用支付服务
  • payment::channels:获取所有支付渠道(微信支付,支付宝,...),包含未启用的支付渠道,适用于定制支付页面
  • payment::get:根据支付渠道名称,创建一个支付实例对象,适用于接入新的支付方式
  • payment::create_order:创建一个支付订单
  • payment::query_order:支付订单状态查询
  • payment::finish_order:完成一个支付订单,如:补单,重试
  • payment::retry_callback_order:业务回调重试
  • payment::refund:退款
  • payment::refund_status:退款状态查询
  • payment::transfer:转账
  • payment::transfer_status:转账状态查询
自定义支付通道
  • payment::channels_add:添加支付通道
  • payment::channels_delete:删除支付通道
在 pay/pay_xxx.php 定义支付发起和回调方法
  • namespace myplugin;
  • // sample 仅实现了 pay 方法,更多参见 /class/pay
  • class pay_test extends \pay_base {
  •     public function callback($data, $order) {
  •         ...
  •     }
  •     public function pay($order) {
  •         ...
  •     }
  • }
在 admin/payment/payment_xxx.php 中可以添加后台设置脚本
  • namespace myplugin\admin;
  • class payment_test {
  •     var $name = 'xxx支付';
  •     public function admincp() {
  •         if(!submitcheck('submit')) {
  •             showformheader('ec&operation=method&id=myplugin:test');
  •             ......
  •             showsubmit('submit');
  •             showtablefooter();
  •             showformfooter();
  •         } else {
  •             ......
  •         }
  •     }
  • }
RESTFul API 接口
X5.0 增加了基于 oAuth2 协议的开放 API 接口,开发者可以通过设计 XML 文件,即可增加 API 接口, 详见 API Gitee 文档
插件范例
X5.0 新增插件接口完整范例见 sample 插件
我要说一句 收起回复

回复

 懒得打字嘛,点击右侧快捷回复【查看最新发布】   【应用商城享更多资源】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

图文热点
创宇盾启航版免费网站防御网站加速服务
投诉/建议联系

discuzaddons@vip.qq.com

未经授权禁止转载,复制和建立镜像,
如有违反,按照公告处理!!!
  • 联系QQ客服
  • 添加微信客服

联系DZ插件网微信客服|最近更新|Archiver|手机版|小黑屋|DZ插件网! ( 鄂ICP备20010621号-1 )|网站地图 知道创宇云防御

您的IP:3.139.83.210,GMT+8, 2024-11-14 10:57 , Processed in 0.217459 second(s), 75 queries , Gzip On, Redis On.

Powered by Discuz! X5.0 Licensed

© 2001-2024 Discuz! Team.

关灯 在本版发帖
扫一扫添加微信客服
QQ客服返回顶部
快速回复 返回顶部 返回列表