「开发者」大概算是进阶建议贴

超级版主 沉冰浮水 2019-5-16 8446

根据个人经验和理念,整理出的一些“这样写可能比较好”的内容,或者原来普遍使用方法其实已经有了替代。。

-------------------

初学者 Teaching 计划-博友杂谈-ZBlogger技术交流中心

https://bbs.zblogcn.com/thread-102975.html

「QQ群:我的咸鱼心」「「水坑」系列教程索引
我大概率能够解决你实际面临的问题(收费),只是”你提出的问题“要如何回答则可能是另一个问题。

最后于 2022-7-8 被沉冰浮水编辑 ,原因:
最新回复 (25)
全部楼主
  • 超级版主 沉冰浮水 2020-5-18 0
    引用 2

    Z-Blog相关资讯RSS订阅-博友杂谈-ZBlogger技术交流中心

    https://bbs.zblogcn.com/thread-100631.html

    [开发者]正则表达式相关专贴-开发者中心-ZBlogger技术交流中心

    https://bbs.zblogcn.com/thread-101713.html

    ZBLOG应用中心验证回调服务端接收插件-开发者中心-ZBlogger技术交流中心

    https://bbs.zblogcn.com/thread-94905.html

    【开发者】1.6新增应用打包时排除文件(夹)功能专贴-开发者中心-ZBlogger技术交流中心

    https://bbs.zblogcn.com/thread-102780.html

    「QQ群:我的咸鱼心」「「水坑」系列教程索引
    我大概率能够解决你实际面临的问题(收费),只是”你提出的问题“要如何回答则可能是另一个问题。

    最后于 2020-6-19 被沉冰浮水编辑 ,原因:
  • 超级版主 沉冰浮水 2020-5-18 0
    引用 3

    ## 不要跨文件闭合HTML标签

    默认主题已按此标准修改:https://github.com/zblogcn/zblogphp/tree/master/zb_users/theme/default/template

    下图是默认模板的结构,除了html和body外,div#divAll之类的结束也在footer.php。很难排查是否正确闭合

    所以“让所有标签在当前文件闭合”感觉会好一些:

    {* Template Name:首页及列表页 *}
    <!DOCTYPE html>
    <html lang="{$lang['lang_bcp47']}">
    <head>
      {template:header}
    </head>
    <body class="multi {$type}">
      <!-- 历史原因,header被上边占了,这里可以用hero,而不是放在在一个文件里 -->
      {template:hero}
      <div id="divNavBar">
        <ul>{module:navbar}</ul>
      </div>
      <div id="divMiddle">
        <div id="divMain">列表索引或正文内容</div>
        <div id="divSidebar">{template:sidebar}</div>
      </div>
      {template:footer}
    </body>
    </html>

    「QQ群:我的咸鱼心」「「水坑」系列教程索引
    我大概率能够解决你实际面临的问题(收费),只是”你提出的问题“要如何回答则可能是另一个问题。

    最后于 2021-3-7 被沉冰浮水编辑 ,原因:
  • 超级版主 沉冰浮水 2020-5-18 0
    引用 4

    文章页经常读取Tag作为关键词,然而不知道从什么时候起,都是在模板里遍历然后拼接,其实直接使用$article->TagsToNameString()或者$article->TagsName←←至少在14年就已经有这个方法了。。。

    「QQ群:我的咸鱼心」「「水坑」系列教程索引
    我大概率能够解决你实际面临的问题(收费),只是”你提出的问题“要如何回答则可能是另一个问题。

    最后于 2020-5-18 被沉冰浮水编辑 ,原因:
  • 超级版主 沉冰浮水 2020-5-20 0
    引用 5

    tags等系统模块内容的重建:

    zblog支持自定义module-tags等模板,但是在新主题启用时并不会主动更新到相应的模块,可使用下边方法触发重建:

    1、单纯重建相应内容:

    $zbp->AddBuildModule('tags');
    $zbp->AddBuildModule('previous'); // 可以依次添加多个要重建的模块
    $zbp->BuildModule();

    2、对模块其他属性进行设置后重建:

    // 将tags类似改为div
    $mod = $zbp->modulesbyfilename["tags"];
    $mod->Type = "div";
    $mod->Build();
    $mod->Save();

    「QQ群:我的咸鱼心」「「水坑」系列教程索引
    我大概率能够解决你实际面临的问题(收费),只是”你提出的问题“要如何回答则可能是另一个问题。

    最后于 2020-5-20 被沉冰浮水编辑 ,原因:
  • 超级版主 沉冰浮水 2020-5-25 0
    引用 6
    jQuery里不能用箭头函数。。

    「QQ群:我的咸鱼心」「「水坑」系列教程索引
    我大概率能够解决你实际面临的问题(收费),只是”你提出的问题“要如何回答则可能是另一个问题。

  • 超级版主 沉冰浮水 2020-5-28 0
    引用 7

    【VSCode】【PHP】【扩展】

    PHP DocBlocker - Visual Studio Marketplace

    https://marketplace.visualstudio.com/items?itemName=neilbrayfield.php-docblocker

    更多扩展见:

    【列表】VSCode插件推荐_电脑网络_沉冰浮水

    https://www.wdssmq.com/post/20201120794.html

    其中重点推荐的:

    [Format HTML in PHP]

    [PHP Intelephense]

    [Prettier]

    [Bracket Pair Colorizer]

    「QQ群:我的咸鱼心」「「水坑」系列教程索引
    我大概率能够解决你实际面临的问题(收费),只是”你提出的问题“要如何回答则可能是另一个问题。

    最后于 2020-12-7 被沉冰浮水编辑 ,原因:
  • 超级版主 沉冰浮水 2020-5-30 0
    引用 8

    【编辑器】【代码片段】【VSCode】

    一些常用代码可以预先设置为代码片段,比如下边定义可以通过输入zbp快速生成global $zbp;

      "zbp": {
        "prefix": "zbp",
        "body": "global \\$zbp;",
        "description": "函数内调用zbp全局变量"
      }

    wdssmq/snippets: Z-Blog程序编辑器代码提示片段

    https://github.com/wdssmq/snippets

    「QQ群:我的咸鱼心」「「水坑」系列教程索引
    我大概率能够解决你实际面临的问题(收费),只是”你提出的问题“要如何回答则可能是另一个问题。

    最后于 2021-7-21 被沉冰浮水编辑 ,原因:
  • 超级版主 沉冰浮水 2020-7-20 0
    引用 9

    【倡议】

    主题开发者可以在事实层面上逐步将 commentpost.php 改成 comment-post.php

    没啥特别的理由,,强迫症使然。。

    「QQ群:我的咸鱼心」「「水坑」系列教程索引
    我大概率能够解决你实际面临的问题(收费),只是”你提出的问题“要如何回答则可能是另一个问题。

    最后于 2022-7-8 被沉冰浮水编辑 ,原因:
  • 超级版主 沉冰浮水 2020-9-12 0
    引用 10

    【主题】【tips】

    <!-- 编辑入口 -->
    <span data-id="{$article.ID}" data-type="{$article.Type}" class="js-edt [is-pulled-right is-hidden]">[编辑]</span>

    JS:

        $(".js-edt").each(function () {
          const id = $(this).data("id");
          const type = $(this).data("type");
          const act = type ? "PageEdt" : "ArticleEdt";
          $(this).html(
            '[<a title="编辑" rel="external" href="' +
              window.bloghost +
              `zb_system/cmd.php?act=${act}&id=${id}">编辑</a>]`
          );
        }).removeClass("is-hidden hidden");

    JS部分可以用浏览器脚本引入,类似这样:https://github.com/wdssmq/userscript/blob/master/zblog/edt.user.js

    「QQ群:我的咸鱼心」「「水坑」系列教程索引
    我大概率能够解决你实际面临的问题(收费),只是”你提出的问题“要如何回答则可能是另一个问题。

  • 超级版主 沉冰浮水 2020-9-19 0
    引用 11

    【关于应用配置中图片的上传】【来自水水的Diss】

    主题 logo,favicon,二维码等允许用户自行上传的图片,目前大部分都是调用 UE 的上传组件并且进了附件文件夹。。如果更换主题或者更换二维码内容时旧图片会形成冗余。。虽然也可以复用地址,但是找到旧图片也会很麻烦。所以你们连个 move_uploaded_file 都不会自己写么,自己写么,写么,么。

    -------------

    实际保存路径见 20 楼;

    -------------------

    具体请参考如下主题,并理解具体意图后使用,后边 Git 地址内的东西也很重要;

    mzERK - Z-Blog 应用中心

    https://app.zblogcn.com/?id=2120

    https://gitee.com/wdssmq/ZBP_THEME/blob/master/mzERK/include.php#L95

    https://gitee.com/wdssmq/ZBP_THEME/blob/master/mzERK/include.php#L153

    https://gitee.com/wdssmq/ZBP_THEME/blob/master/mzERK/zbignore.txt

    ----------------

    $act = GetVars("act", "GET");
    if ($act === "save") {
      CheckIsRefererValid();
      // 配置项保存 ↓
      foreach ($_POST as $key => $value) {
        $zbp->Config("mzERK")->$key = $value;
      }
      $zbp->SaveConfig("mzERK");
      // 配置项保存结束 ↑
      $extList = "png|jpg|jpeg|ico"; // 上传相关开始
      foreach ($_FILES as $key => $value) {
        if ($_FILES[$key]['error'] === 0) {
          $ext = GetFileExt($_FILES[$key]['name']);
          $file = mzERK_Path("u-{$key}"); // 根据字段返回实际文件路径,参考 mzERK 主题
          // 只允许覆盖已有文件,不允许增加新文件
          if (!HasNameInString($extList, $ext) || !is_file($file)) {
            continue;
          }
          // 接受上传文件
          if (is_uploaded_file($_FILES[$key]['tmp_name'])) {
            move_uploaded_file($_FILES[$key]['tmp_name'], $file);
          }
        }
      } // 上传结束
      $zbp->SetHint('good');
      Redirect('./main.php');
    }

    「QQ群:我的咸鱼心」「「水坑」系列教程索引
    我大概率能够解决你实际面临的问题(收费),只是”你提出的问题“要如何回答则可能是另一个问题。

    最后于 2022-7-8 被沉冰浮水编辑 ,原因:
  • 超级版主 沉冰浮水 2020-11-24 0
    引用 12

    【百度事件统计封装】

      // 百度统计事件
      function _hmtLOG(...args) {
        // const args = [].slice.call(arguments, 0);
        if ("undefined" !== typeof _hmt) {
          _hmt.push(["_trackEvent", ...args]);
        }
        console.log(args);
      }
      // 使用,最多支持三个参数
      _hmtLOG("阅读更多", "点击");
      _hmtLOG("阅读更多", "计时结束");
      _hmtLOG("阅读更多", "跳过");


    「QQ群:我的咸鱼心」「「水坑」系列教程索引
    我大概率能够解决你实际面临的问题(收费),只是”你提出的问题“要如何回答则可能是另一个问题。

  • 超级版主 沉冰浮水 2020-12-4 0
    引用 13

    “随机”文章函数

    function xnxf_GenRnd($nums)
    {
      // 一种比较节省资源的随机文章获取方法-ZBLOG教程-鸟儿网络
      // https://www.birdol.com/zblogjiaocheng/756.html
      // 有修改和补充,以及list()方法是不是有php版本要求。。
      global $zbp;
      $sql = $zbp->db->sql->Select(
        $zbp->table['Post'],
        array("MIN(log_ID)", "MAX(log_ID)"),
        array(
          array('=', 'log_Type', '0'),
          array('=', 'log_Status', '0'),
        ),
        array('log_PostTime' => 'ASC'),
        null,
        null
      );
      $array = $zbp->db->Query($sql);
      list($min, $max) = explode(':', join(":", $array[0]));
      // list($min, $max) = $array[0]; // ← 这样写取不到值
      // 判断相等时仍然有$min和$min+1两种取法
      if ($max - $nums >= $min) {
        $i = mt_rand($min, $max - $nums + 1);
      } else {
        $i = $min;
      }
      $order = '';
      $where = array(
        array('=', 'log_Status', '0'),
        array('>=', 'log_ID', $i)
      );
      $articles = $zbp->GetArticleList(array('*'), $where, $order, array($nums), '');
      $rltHtml = "<h3 class=\"is-px-14 title\">随机文章</h3><ul class=\"a-color\">";
      foreach ($articles as $article) {
        $rltHtml .= "<li class=\"li-nowrap\"><a href=\"{$article->Url}\" title=\"{$article->Title}\">{$article->Title}</a></li>";
      }
      return $rltHtml . "</ul>";
    }


    「QQ群:我的咸鱼心」「「水坑」系列教程索引
    我大概率能够解决你实际面临的问题(收费),只是”你提出的问题“要如何回答则可能是另一个问题。

  • 用户 dokit 2021-1-16 0
    引用 14
    沉冰浮水 文章页经常读取Tag作为关键词,然而不知道从什么时候起,都是在模板里遍历然后拼接,其实直接使用$article-&gt;TagsToNameString()或者$article-&gt ...
    获取带链接的tag,还是需要遍历一下吧?
  • 超级版主 沉冰浮水 2021-8-23 0
    引用 15

    取消评论后自动保存用户信息:

    zbp.plugin.unbind("userinfo.readFromHtml", "system");


    「QQ群:我的咸鱼心」「「水坑」系列教程索引
    我大概率能够解决你实际面临的问题(收费),只是”你提出的问题“要如何回答则可能是另一个问题。

  • 超级版主 沉冰浮水 2021-9-3 0
    引用 16

    「后台配置项应用 tab 切换」

    后台配置项如果略多,可以尝试拆分成 tab;

    main.php ↓

    <?php
    // ……………………
    $action='root';
    if (!$zbp->CheckRights($action)) {$zbp->ShowError(6);die();}
    if (!$zbp->CheckPlugin('appid')) {$zbp->ShowError(48);die();}
    
    // 权限仅需要检查一次
    if (count($_POST) > 0) {
     CheckIsRefererValid();
    }
    // ……………………
    ?>
    
    
    <div id="divMain2">
    <div class="content-box">
      <ul class="content-box-tabs">
        <li><a href="#tab1" class="default-tab current">基本设置</a></li>
        <li><a href="#tab2">幻灯片</a></li>
        <li><a href="#tab3">缩略图</a></li>
      </ul>
      <div style="clear: both"></div>
      <div class="content-box-content">
        <div class="tab-content default-tab" id="tab1">
          <?php include "admin/basic.php"; ?>
        </div>
        <div class="tab-content" id="tab2">
          <?php include "admin/slide.php"; ?>
        </div>
        <div class="tab-content" id="tab3">
          <?php include "admin/thumbnail.php"; ?>
        </div>
      </div>
    </div>
    </div>


    admin/basic.php ↓

    <?php
    if (!isset($zbp)) {
        exit;
    }
    $act = GetVars('act', 'GET');
    $suc = GetVars('suc', 'GET');
    if ($act == 'saveBasic') {
        // 前边判断过了这里可以不用
        // CheckIsRefererValid();
        // 拆分后保存项目和流程也应该根据实际修改
        foreach ($_POST as $key => $val) {
            if (substr($key, 0, 5) == 'read_') {
                continue;
            }
            $zbp->Config('appid')->$key = trim($val);
        }
        // 图片相关的请参考这下边贴子
        // https://bbs.zblogcn.com/thread-101310.html#485997
    
        $zbp->SaveConfig('appid');
        $zbp->BuildTemplate();
        $zbp->SetHint('good');
        Redirect('./main.php' . ($suc == null ? '' : "?act={$suc}"));
    }
    ?>
    <form action="<?php echo BuildSafeURL("main.php?act=saveBasic"); ?>" method="post">
        <table width="100%" class="tableBorder">
            <tr>
                <th width="10%">项目</th>
                <th>内容</th>
                <th width="45%">说明</th>
            </tr>
            <tr>
                <td>配置项 A</td>
                <td><?php zbpform::text("aaa", $zbp->Config("appid")->aaa, "90%"); ?></td>
                <td></td>
            </tr>
            <tr>
                <td></td>
                <td colspan="2"><input type="submit" value="提交" /></td>
            </tr>
        </table>
    </form>


    「QQ群:我的咸鱼心」「「水坑」系列教程索引
    我大概率能够解决你实际面临的问题(收费),只是”你提出的问题“要如何回答则可能是另一个问题。

  • 超级版主 沉冰浮水 2021-9-3 0
    引用 17

    接 16 楼:

    $(function () {
      // tabs
      function fnToggleTab() {
        if (location.hash !== "") {
          $(".tab-content").hide();
          $(".content-box-tabs a").removeClass("current");
          $(location.hash).show();
          $('a[href="' + location.hash + '"]').addClass("current");
        }
      }
      fnToggleTab();
      $(".content-box-tabs a").click(function () {
        //alert(this.href);
        window.history.pushState(null, null, this.href.replace(/#tab1/, ""));
      });
    );


    「QQ群:我的咸鱼心」「「水坑」系列教程索引
    我大概率能够解决你实际面临的问题(收费),只是”你提出的问题“要如何回答则可能是另一个问题。

  • 应用开发者 勇康博客网 2022-6-22 0
    引用 18
    受益匪浅
  • 应用开发者 包子也沉默 2022-7-5 0
    引用 19
    mark
  • 超级版主 沉冰浮水 2022-7-8 0
    引用 20

    接 11 楼 ——

    --------

    主题或插件需要由用户自行上传图片之类的静态文件时;

    1、可放在 app 自身目录下,但是需要在打包 zba 时排除;

    2、上传至 zb_users/static 内,具体为:zb_users/static/theme_ID/ 或 zb_users/static/plugin_ID/,卸载时提供选项是否删除,或者给个 hint 提示;

    --------------

    「开发者」1.6 新增应用打包时排除文件(夹)功能专贴-开发者中心-ZBlogger技术交流中心

    https://bbs.zblogcn.com/thread-102780.html

    「QQ群:我的咸鱼心」「「水坑」系列教程索引
    我大概率能够解决你实际面临的问题(收费),只是”你提出的问题“要如何回答则可能是另一个问题。

  • 超级版主 沉冰浮水 2022-7-8 0
    引用 21
    接 20 楼,对于一些随时都可以删除的缓存文件,同样可以生成于 zb_users/cache/ 内,以规范格式命名就好;

    「QQ群:我的咸鱼心」「「水坑」系列教程索引
    我大概率能够解决你实际面临的问题(收费),只是”你提出的问题“要如何回答则可能是另一个问题。

  • 超级版主 沉冰浮水 2022-9-16 0
    引用 22

    「中间模板」

    一个东西前台并不需要经常变。。可以从数据库里取出来生成一个文件,前台直接调用文件,而不是现场拼接。。

    一个 m- 开头的模板

    mzDanron/template/m-slide.php

    https://gitee.com/wdssmq/ZBP_THEME/blob/master/mzDanron/template/m-slide.php

    通过模板编译接口变成 n-

    mzDanron/include.php

    https://gitee.com/wdssmq/ZBP_THEME/blob/master/mzDanron/include.php#L88

    实际调用的时候调用 n-

    mzDanron/template/focus.php

    https://gitee.com/wdssmq/ZBP_THEME/blob/master/mzDanron/template/focus.php


    对于热门文章,随机文章等数据,同样可以用生成模板文件的方式进行缓存。。

    mzDanron/include.php · 沉冰浮水/ZBP_THEME - Gitee.com:

    https://gitee.com/wdssmq/ZBP_THEME/blob/master/mzDanron/include.php#L109

    「QQ群:我的咸鱼心」「「水坑」系列教程索引
    我大概率能够解决你实际面临的问题(收费),只是”你提出的问题“要如何回答则可能是另一个问题。

    最后于 4月前 被沉冰浮水编辑 ,原因:
  • 超级版主 沉冰浮水 11月前 0
    引用 23

    「初始化分类 ID」

    需要指定分类 ID 使用的功能效果,在初始化指定时要考虑是否存在;

    global $zbp;
    if (!$zbp->HasConfig('demo')) {
        // 初始化指定分类
        $zbp->LoadCategories();
        $category = null;
        ksort($zbp->categories_all);
        foreach ($zbp->categories_all as $key => $cate) {
            if ($cate->RootID == 0) {
                $category = $zbp->categories_all[$key];
                break;
            }
        }
        // 保存至配置项
        if ($category) {
            $zbp->Config('demo')->category = $category->ID;
        } else {
            // 虽然几率很小,也有可能全部分类被删除了,此时只能在调用时加一个非零判断
            // 所以帮用户的使用姿势兜底到何种程度也是很折磨人的
            $zbp->Config('demo')->category = 0;
        }
        $zbp->SaveConfig('demo');
    }

    「QQ群:我的咸鱼心」「「水坑」系列教程索引
    我大概率能够解决你实际面临的问题(收费),只是”你提出的问题“要如何回答则可能是另一个问题。

  • 超级版主 沉冰浮水 9月前 0
    引用 24

    「VSCode」「代码片段演示」


    「QQ群:我的咸鱼心」「「水坑」系列教程索引
    我大概率能够解决你实际面临的问题(收费),只是”你提出的问题“要如何回答则可能是另一个问题。

  • 超级版主 沉冰浮水 6月前 0
    引用 25
    13 楼的随机 和 22 楼的「中间模板」可以结合起来

    不要在前台直接引用的模板文件里用随机,可以把随机的结果生成一个缓存模板,由前台直接引入;

    mzDanron/include.php · 沉冰浮水/ZBP_THEME - Gitee.com
    https://gitee.com/wdssmq/ZBP_THEME/blob/master/mzDanron/include.php#L110

    「QQ群:我的咸鱼心」「「水坑」系列教程索引
    我大概率能够解决你实际面临的问题(收费),只是”你提出的问题“要如何回答则可能是另一个问题。

  • 超级版主 沉冰浮水 6月前 0
    引用 26
    // var/script.js 
    const abc = "#abc#";

    挂编译接口或者配置项保存时生成:

    // bin/script.js
    const abc = "实际的值";

    -----

    // 接口挂载
    function ActivePlugin_diySth()
    {
      Add_Filter_Plugin('Filter_Plugin_Zbp_BuildTemplate', 'diySth_BuildTemp')
    }
    
    // 模板编译调用
    function diySth_BuildTemp(&$templates)
    {
      $templates['header'] = str_replace('{$header}', '{$header}  	<link rel="stylesheet" href="' . diySth_Path("b-css", "host") . '?v=2022080610" media="screen" />', $templates['header']);
      $templates['footer'] = str_replace('{$footer}', '{$footer}<script src="' . diySth_Path("b-js", "host") . '?v=2022080610"></script>', $templates['footer']);
    }
    
    // 使用 var/script.js 生成 bin/script.js
    function diySth_GenBinJS($data)
    {
      $src = diySth_Path("var/script.js");
      $dst = diySth_Path("bin/script.js");
      $js = file_get_contents($src);
      // $data = array("abc"=>"123", "def"=>"456");
      // 三种替换方式
      $js = str_replace("const diySth_Data = {};", "const diySth_Data = " . json_encode($data) . ";", $js);
      // 有个 strtr() ,需要按如下格式传入数组
      $js = strtr($js, array("#abc#" => "123", "#def#" => "456"));
      // 正则回调替换 "#abc#" 形式的字符串
      $js = preg_replace_callback("/#([^#]+)#/", function ($matches) use ($data) {
        return $data[$matches[1]];
      }, $js);
      file_put_contents($dst, $js);
    }


    个人习惯:

    var/ 插件自带但一般并不直接使用的文件,预置图片之类的;

    usr/ 用户自行上传指定的文件,一般和 var/ 内同名文件对应,首次安装时可从 var/ 复制一份;

    bin/ 以 var/ 或 /usr 内文件为输入源进一步修改生成,或者其他需要先生成再直接使用的文件;

    上边三个算是同一体系,usr/ 和 /bin 视情况也可能只用一个;

    其他有 db/ cfg/ 之类可以放文件形式的数据,当然也可以都放在 usr/ 里。。


    以上全部文件夹,除 var/ 外都在打包时排除。。


    「QQ群:我的咸鱼心」「「水坑」系列教程索引
    我大概率能够解决你实际面临的问题(收费),只是”你提出的问题“要如何回答则可能是另一个问题。

    • ZBlogger技术交流中心
      27
          
返回