Typecho 文章部分加密插件

封面:夜桜霊夢(Pixiv ID:47139274)

不知不觉从年前咕到年后的感觉真是奇妙~(狗头)

插件很早就写好了,因为当时写 README 比较认真就一直没在博客上详细记一次,今天得空补一下插件介绍和开发笔记~

GitHub 项目地址:wuxianucw/PartiallyPassword


插件功能

Typecho 文章部分加密插件(PartiallyPassword)支持对某一篇文章的特定部分创建密码,访客需要正确输入密码才能查看内容。

原生 Typecho 文章加密功能仅支持加密整篇文章,设置密码后该篇文章包括标题全部对未正确输入密码的访客不可见,这在有时并不能满足我们更加细致的要求。很可能一篇文章中有部分文字我们仅希望『获得许可的个人或群体』查看,而另一部分则希望『所有人』都可见;又或者,我们需要对这个加密内容添加一个注释信息或说明文本,而不想完全隐藏这段思想。这时,使用 PartiallyPassword 即可轻松解决问题。

来个栗子?(密码:wuxianucw

当前版本支持自定义加密块的样式,以及配置加密块上的提示文本。详细内容请参考 README.md,在此不再赘述。

开发笔记

这个 idea 也不算是突然出现的,一直以来都有这方面需求,我目前的方针是『凡可使内容更好玩,且我力所能及可写者,抽空优先考虑开发。』包括首页头图的鼠标跟随、文章中[heimu]黑幕[/heimu]效果,甚至是输出在 Console 中的乱搞内容都或多或少贯彻了这一方针。

最初的版本(v1.0.0)是挂钩了 Widget_Abstract_Contents 中的 contentEx,算是妥协的方案。这个钩子在内容被解析后触发,也就是如果有什么旁路直接拿 text,我是拦不掉的,加密的内容会吐出来,不严谨,心里一直很不舒服,也在寻求解决方案。这一版本的默认样式也极难看,是本着能用就行的策略随意设置的,对密码输入的处理也极不协调,是在前端写入 Cookie 并刷新页面。唯一的优点是可以 PJAX 无刷新加载。

之后很快更新了 v1.1.1 版本,新增挂钩了 Widget_Abstract_Contents 中的 excerpt,在摘要中做一些处理。同时优化了默认样式,仔细想想极简风格不仅好写而且好看。

然后 v1.x 时代就结束了,v2.0.0 版本全面优化了整个流程,包括加密块的处理和密码提交的逻辑,前者交给了 Widget_Abstract_Contentsfilter 钩子,后者在 Widget_Abstract_Contents 中的 singleHandle 中进行,前端把密码 POST 上来,在后端走验证。filter 钩子是大杀器,text 在从数据库中取出来后立即经过 filter 处理,在这里搞定替换可以几乎完全避免加密内容意外泄露,唯一的不确定性只有当第三方插件也挂钩 filter 时,这个处理顺序问题……猜测是根据插件启用的先后顺序确定的,没有进行验证。自这个版本起,默认样式放弃了对 PJAX 的直接支持,换来的是更好的可移植性(在 Typecho 默认主题上可以直接使用),但是你仍然可以开动脑筋根据自己的主题情况自定义代码,实现 PJAX。

寒夜方舟向我提了 issue,称在后台编辑时,加密块保存后自动消失,吓得我心肺停止慌忙 fix。这时注意到后台取 text 也要走 filter,我直接给换掉了那么后台也看不见,保存后还能喜提数据丢失……遂 fix 该重大 bug,发布 v2.0.1 版本。通过 __TYPECHO_ADMIN__ 常量判断了一下前后端,照着 Typecho 的样子做了一点权限控制。

关于之后的开发工作,大方向是搞一个不同密码对应不同内容的新玩法,目前开发工作已全面暂停(咕)。

然后就做出来了一个全新的 v3.0.0 版本,也确实是实现了不同密码对应不同内容,并且换了一套密码方案,自 v3.0.0 起将使用全新的 JSON 密码方案。这套方案主要的思想就是使用 JSON 来储存密码,而不是一个字符串加一个分隔符。这样做带来的好处是明显的,“命名密码”由此诞生了。

由于这个改变比较大,导致 v2 升级到 v3 比较麻烦,我给出的解决方案是 Upgrade.php,使用它的时候需要格外谨慎,一经用完,也应该删除相关文件(upgrade.log 中会包含目前的所有密码配置,也是敏感信息)。这个解决方案我并不满意,我本来的想法更倾向于在命令行环境执行脚本而不是直接访问 URL,但考虑到这样做可能会给部分用户带来困扰,就退而求其次了。

仓库中我仍然保留了原先的 v2 分支,它是会继续维护的,如果您在使用 v2 版本时遇到了问题,同样可以提出 issue。

关于是否更新到 v3,以及新用户是选择 v2 还是 v3,我的建议是:按照你的需求来。如果你不需要 ppswitch 的新特性(具体参见 README),也觉得目前的版本就已经足够好了,那么不更新/选择 v2 会轻松许多;如果你愿意尝试新鲜事物,v3 绝不会是坏的选择。

看到评论有人吐槽没有按钮,我实话实说:懒得做了。有一说一,自定义样式的接口也是预留好的,如果你有需要完全可以自行实现(不会?可这也不是 bug,我为什么一定要改呢),所以至少暂时是不会考虑这个问题的。我个人更喜欢输入完毕后敲 Enter 键的感觉,不知有没有人同感?

再谈谈插件冲突问题。其实这个问题是很普遍的,尤其是在这种有后效性的操作上。一方面,处理冲突本身已经超出了插件功能的范畴,在 Typecho 的大框架下,插件能做的事毕竟有限(如果规规矩矩不乱搞);另一方面,插件的多样性和插件组合的多样性决定了作者不可能在单个插件的主仓库代码层面处理冲突。因此,处理冲突只能由使用者去做,作者能够提供的也就是一个对自己插件的技术参考。

最后还是一如既往展望一下未来,这次是彻底没有计划了,大家有好的 idea 可以告诉我~

如果您还满意的话,不妨给我个 Star ☆

插件下载

请移步 Releases 页面或点击下面的按钮,将帮您跳转过去。

最后修改:2020 年 12 月 12 日 06 : 19 PM
欢迎投食喵 ~

发表评论

38 条评论

  1. liveup

    typecho V1.3有较大的变动。希望插件继续适配。

  2. Cc

    你好 在1.2版本中,输入正确的密码会闪一下然后重新回到页面,后显示不出内容, 是否需要更新插件还是没设置好?

  3. momo

    您好抱歉打扰您了,typecho在升级更新为1.2.0版本、handsome主题9.0.2后,加密插件在输入正确密码后跳转白屏,再次刷新后回到需要重复输入密码的状态,请问是插件需要更新吗还是个人设置出错了

    1. 无限UCW
      @momo

      可能是相关处理逻辑中有异常情况,本插件是针对 Typecho 1.1 编写的,尚未针对 1.2 版本进行足够的测试。您可以考虑开启 PHP 报错,同时启用 Typecho 调试模式,然后针对跳转中的错误信息进行排查,必要时可在 GitHub 仓库提出 issue(附带尽可能详细的错误信息)。

      1. 超超
        @无限UCW

        我的也是这个问题

      2. momo
        @无限UCW

        开启调试模式后显示
        Warning: Undefined array key "action" in /www/wwwroot/typecho/usr/themes/handsome/libs/Request.php(222) : eval()'d code on line 1
        Warning: Undefined array key "type" in /www/wwwroot/typecho/usr/themes/handsome/component/header.php on line 10

  4. lxalxy

    请问为什么我的密码块上下都有3个感叹号呢?

    1. 无限UCW
      @lxalxy

      已在 3.1.0 版本引入“额外 Markdown 标记”配置项,将其设置为“关闭”即可。

      1. lxalxy
        @无限UCW

        嗯嗯,多谢大佬

    2. 无限UCW
      @lxalxy

      插件目前适配的是 Typecho 稳定版的默认 Markdown 渲染器,需要使用三感叹号语法内联 HTML,因此默认会有三感叹号的插入。未来版本将考虑增加相关配置项来控制展现。

  5. aoyouer

    很好用,谢谢啦

  6. 小宇

    密码填完也没法提交啊

    1. 无限UCW
      @小宇

      请使用 Enter 键。

      1. 木白
        @无限UCW

        哈哈,做个按钮吧,有这样疑惑的人应该会有不少

        1. 无限UCW
          @木白

          懒得做按钮了(理直气壮),如有需要可以自行编辑样式

        2. 天策无双
          @木白

          做个按钮就不极简风了,So……

  7. 天策无双

    好用,美滋滋的star了ヾ(≧∇≦*)ゝ

  8. 安梓

    在handsome主题7.0使用vditor编辑器时会导致上下出现三个感叹号
    如图:https://imgchr.com/i/UWnK9s
    后台编辑:https://imgchr.com/i/UWnYEF

    1. 无限UCW
      @安梓

      已在 3.1.0 版本引入“额外 Markdown 标记”配置项用于解决此问题,将其设置为“关闭”即可。

    2. 无限UCW
      @安梓

      第三方编辑器接管前台解析时会出现这种问题,这是由于插件的实现方式决定的,目前没有较好的兼容方案。如果你熟悉 PHP,可以自行修改 Plugin.php 中对 $placeholder 前后添加感叹号的相关内容,删去为兼容 Typecho 1.1 正式版而添加的感叹号即可。如果你不熟悉 PHP,或对这部分功能确有需求,请移步 GitHub issue。感谢您的支持。

  9. 严明

    你好, 启用加密插件后, 后台点开撰写新文章页面会出现一下错误
    Warning: call_user_func_array() expects parameter 1 to be a valid callback, class 'PartiallyPassword_Plugin' does not have a method 'pluginFields' in /www/wwwroot/Localhost/var/Typecho/Plugin.php on line 489
    加密语法无效。
    但是创建页面正常,是什么问题呢?

    没装别的插件。

    1. 无限UCW
      @严明

      这是一种边缘情况,暂时无法定位问题,我的环境下也没有复现。请在确认插件文件完整后,在 GitHub 上提出 issue,同时附带上发生此问题的 PHP 版本和 Typecho 版本。

  10. 嘎子哥

    titleshow插件和这个有冲突,两者只能用其一,不知道有没有办法解决,好想两个都能用啊,都是好插件
    titleshow项目地址:https://github.com/jrotty/Titleshow

    1. 无限UCW
      @嘎子哥

      这个暂时没有特别好的方案,因为两个插件都需要挂钩 Widget_Abstract_Contentsfilter 方法并对内容进行操作,有冲突也是在所难免的。可以尝试在我的插件的 Plugin.php 中第 157 行后插入以下代码:

      if($value['hidden']) return $value;

      或更加详细描述你的需求(需要何种情况下何插件起何作用等),以便我进一步评估。

      1. 嘎子哥
        @无限UCW

        试了下,还是不行。说下我期望的场景吧:
        对于某些文章,希望成为typecho中受密码保护的文章,但能够显示标题,使用titleshow,而另一些文章希望部分加密,使用PartiallyPassword。
        额,字打到这,我好像发现只使用PartiallyPassword可以实现上述场景,对于全文加密的文章,使用PartiallyPassword将文章从头包到尾

        1. 无限UCW
          @嘎子哥

          这样呢?

          if($value['hidden'] || $value['titleshow']) return $value;
  11. 秦小谅

    老哥自定义可以设置密码了,在哪里可以设置想要加密的文字

    1. 无限UCW
      @秦小谅

      请使用 [ppblock]需要加密的内容[/ppblock]。其中需要加密的内容可以多行。

      1. 秦小谅
        @无限UCW

        好的,非常感谢|´・ω・)ノ

  12. 阵雨兄

    很好用,谢谢博主。自己改了风格,pjax完美支持。OωO

  13. FzWjScJ

    问问大佬,那密码需要怎么设置呢

    1. 无限UCW
      @FzWjScJ

      在文章的“自定义字段”处设置。

  14. 131

    启动插件 显示服务器错误
    其他插件正常

  15. love02xp

    为嘛我使用时是无效

    1. 无限UCW
      @love02xp

      请确认文章自定义字段“是否开启文章部分加密”处于“开启”状态。

      1. love02xp
        @无限UCW

        可以了,确实是自己的问题
        感谢感谢。。。

  16. 寒夜方舟


    大佬棒棒哒

  17. UCW是苣佬

    哈哈