我为小说忙:(一)TPNovel 的规划
上次说本月要开一个新项目,就是这个了:以系列文章的方式,记录 TPNovel 这个Typecho小说插件的开发过程。一边开发,一边写,到最后就放到自己的站上来使用。
这次,可以给自己的小说一个家了。
据说大佬的写作风格都是比较跳跃的,最后一本我读过1. 前言
本站的老读者应该都知道,大概是从一年前开始,笔者就断断续续提到『有正在写的小说』,而且在早期的文章里也稍微系统总结过:一共有四本,第一本烂尾,第二本20万字烂尾,第三本开了个头之后烂尾,第四本就是目前正在写的《如果瓷杯从未冷透》。关于写这些小说的心路历程,已经在之早期的文章里有所提及,因此这里不再赘述。
除了第一本之外,他们都有一个共同特点是,从未放到任何公开平台上供人阅读。当时的思想也很简单,就是想着写完之后再拿出来发,免得中途卡文导致很久不更新(好像有不少网文写手都是日更数千字的),然后读者又跑了。然而,在写了这么长时间的博客之后,已经习惯了『想更就更,没动力先歇会儿』的常态,再加上自己并非是专门写小说的作家,也不靠这件事赚钱,所以一旦停写就没什么动力续写,然后就可能永远不见天日了。考虑到不能让以前写过的东西白白浪费,好歹也是自己当时的一些想法,于是就慢慢放下了『全写完再发』执念。
既然执念已消,那么就该计划一下把他们放出来的事情了,于是也就有了『我为小说忙』这个全新的小系列。具体来说,一方面是作为插件开发笔记,另一方面也是作为一个催促,毕竟这件事已经拖很久了,再拖下去,怕不是花都谢了。
2. 各抒己见讲小说
作为这个系列的首篇文章,虽然分类会在『编程』下,但还是先偏个题,聊点简单的事情吧。毕竟,对于一个项目来说,事前的选型与路径规划,也是整个过程中必不可少的步骤。
这里面要考虑的问题很多,比如说,一个更省事的做法是,把小说放到某个主流的小说平台上,然后把链接放过来,完事。很多著名的网文作家(包括已经出版纸质书的)都是如此。在此情况下,我为什么决定要写 TPNovel,让他成为自己网站的一部分呢?
2.1 类型?
小说,其实是一个很宽泛的词语,可以指代很多不同的东西。这里不单单是指题材种类繁多(比如说玄幻小说,耽美小说,爽文小说,以及目前比较流行的修仙文、系统文、网游文),更重要的还有一点:在不同题材下,文字的表达方式,也是不一致的。
试举两例。首先是:
『东西呢?』
『拿到了。』
『人呢?』
来者怒目圆睁。
『......跑太快,没追上。』
以及:
两人在一张靠窗的圆桌旁坐下。窗外,城市喧嚣的背景音被咖啡馆的轻柔爵士乐完美地滤化、减弱,变成了一层温柔的、可以随时沉溺其中的背景音景。A端起卡布奇诺,轻抿了一口。那混合着浓郁烘焙香气、恰到好处的苦涩与牛奶的柔滑甘甜,瞬间唤醒了他因奔波而有些混沌的神经。他放下杯子,长长地吐出一口气,那口气中带着一丝微不可察的,属于职业侦探特有的,略显紧绷的锐利感。。
第二段是AI写的,内容不重要,这里我们重点关注文字的安排问题。第一个例子,笔者管他叫『短段落式』,比较类似于以前古龙的作品,以及现在手机时代的主流网文。特点是,每一段的长度都不算太长,对话、场景描写等,可以拆分成数个自然段。第二个例子,笔者叫『长段落式』,则是比较类似纸质小说年代的写法,每一段的长度较长,至少不会只有短短一行。
关于为什么会产生这样的区别,可分析的角度非常多,比如说『纸质书物理成本』,『快节奏叙事』等等,文学界也有很多专家已经给出了自己的答案,这里就不再班门弄斧了,只取一个比较相关的点:纸质年代的『可视空间』是比较宽的,现在的手机时代则与之相反,不论是屏幕本身的物理宽度,还是阅读软件对字号与页面排版的安排,都让可视空间的宽度有所缩减。
试想一下,在纸质书上,一个较长的段落,可以适当安排较小的段内行距,以及较大的段间距,整体来说显得疏密有致,比较容易阅读。然而如果是短段落,排版之后很容易出现『段间距变成行距』的问题,要么就是过宽,要么就是过窄,而且太过于均匀,很难产生分段的感觉。另一方面,手机时代的屏幕变窄,让原本在纸质书上显得很不美观的『短段落式』显得更合适,没有了一大堆文字的感觉,阅读起来也不容易出现串行等情况。作为参考,本段与上一段其实应该是连在一起的,但在手机端预览的时候还是决定在中间断开两半,就是这个原因。
笔者目前写的小说,可以说是介于二者之间,或者说二者皆有之,有时候一行极短,有时候又习惯写很长。虽然现在的小说平台一般都可以针对这样的情况做动态调整,至少也不会过于难看,不过毕竟那是别人的平台,想做定制或者针对性调整,都是不可能的。而如果是自己来实现平台与阅读页,那么自由度会高很多,可以针对读者反馈进行实时的优化,何乐而不为呢?
2.2 大平台?
关于小说,尤其是网文这一类,有阅读经验的朋友应该都知道,目前有几个比较有名的平台,比如起点中文网,晋江文学城,刺猬猫,等等等等。既然作为主流平台,上面的读者数量自然不会少到哪里去,换句话说,如果我把自己的小说放上去,可以很快地吸引到读者阅读,甚至可能在特殊情况下,被平台选中签约,从而获得一笔稿费收入。
这样的做法当然是没有问题的,不然这类大平台也不会存在了。然而,笔者的看法是:大平台好是好,但既然现在我有自己的博客,可以看做是有自己的平台,那么为什么不充分利用一下呢?
具体展开来说,主要是有这么几点:
- 流量获取:这个角度略显功利,但老实说,确实是第一考虑。虽然大平台可以很容易获客,但这样带来的流量终归还是有些单调,也没有什么太大的正反馈;放在自己的站点上,虽然流量来得不那么快,但获得的流量都能算到自己账上。这一点其实和独立博客比较类似,市面上并不是没有公共的博客平台,比如博客园,但在自己的站点上写东西,自给自足,没人来分账,个人形象也显得比较立体,成就感还是会高一些的。
- 平台风向:这一点其实并不太确定,但似乎有这个情况,也就是平台上面的作品有一个主流的文风。比如说起点的有不少是修仙类爽文类,晋江的以言情类为主,等等。因此引发了一个不确定算不算现象的现象:在大平台上,人的概念几乎消失,所有的产出都跟平台产生了联系。相反,在个人博客上,平台的概念是不存在的,人就是人,你就是你自己,不用担心『这是平台主流小说类型吗』之类的问题?
- 平台规则限制:这是比较迷的一点。笔者曾经在某小说平台上写过东西,某日,某篇文章点击发布后显示失败,说是有敏感词。看了一下,标出来的句子是:『钢笔帽被插上了』。所幸页面上提供了『我觉得这不是屏蔽词,有空给我人工复核一下呗』的按钮,点击后提交申诉,倒也顺利发布了。不过这件事之后,笔者对大平台的一些神奇的规矩就有所怀疑了。放在自己的平台上,自己能知道系统运行的细节,没这么多奇奇怪怪的事情。
也许还有很多其他的细碎原因,但也足够做出选择了。
2.3 其他CMS?
既然决定了要自己弄平台,那,怎么弄呢?
其中一条路子当然就是,找一些专供小说使用的CMS平台安装在服务器上,就可以对外服务了。又或者,自己手搓一个CMS系统,根据自己的喜好来定制各种细节,然后再放到服务器上。然而这两个方法都需要在目前的博客系统外,再维护一套别的CMS系统。对于一个以稳定快速为要务的站点来说,先不提可能引入了新的攻击面,光是需要再学习/习惯另一套操作方式,就足够否掉这一点了。毕竟,还是那句话,小说不算得上是主要项目(至少目前不是)。
因此,在『完全选择成品平台』以及『完全自己写CMS』之间,笔者选择了『TPNovel 插件』这个折衷的方案,即:CMS保持使用Typecho不变,但通过插件的方式,添加与小说相关的功能。这样可以避免重复造轮子,包括页面编辑,评论等,都可以继续复用Typecho的基础设施,原来的其他生态也依然适用,不必再维护第二套系统,总体来看也符合 KISS 原则。
3. 总体规划
聊了这么多,终于可以开始做大致的路径规划了。
这里只是简略记录,不排除后续有所变动的可能性。
3.1 项目定位
完全的自用插件,还是和以前一样,没有对外公开发布源代码的计划。
不是不想开源,而是笔者实在是没动力也没时间去维护一个开源项目,而且代码中很多地方都可能存在workaround,只是针对目前的架构调优,不一定适用于其他环境,放出来也很难说马上即插即用(目前已知的有:插件不能单独工作,需要在当前)。不过为了补偿这一点,完整的开发思路以及部分代码片段,照例还是会放出来的。
3.2 项目架构
目前来看,笔者会把整个小说项目划分为三大件:CMS基础,前端页面,后端小说附件。
CMS部分没有什么好说的,按上文说法,整个小说系统会建立在Typecho之上。更具体地说,是建立在系统的『独立页面』功能之上(站内有文章介绍过独立页面的优点)。这样可以直接复用Typecho的基础设施,包括文本编辑器,附件系统,评论系统,等等。这些功能不必在插件里重写,只需要根据官方文档调用接口并适配即可,省去了不少功夫。
然后是前端页面。这一部分名义上属于TPNovel项目的一部分,但实际规划中,最终写好的页面还是会放入usr/themes/<当前使用的主题>/目录下。这并不是说TPNovel会绑定某一个主题,而是说Typecho只会在这个地方找独立页面的模板罢了。实际上最后出来的页面是单独设计的,与原来的主题没有任何关系。
至于后端小说附件,就是插件代码的事情了。本质上,他的核心工作就是在独立页面这个基础之上,添加一套适用于小说的组织系统(目录,章节,翻页等)。剩下的都是锦上添花的事情了,比如说提供专门的RSS订阅,独立于博客自身的RSS,等等。需要注意的是,插件不负责自定义路由与页面渲染等操作,这依然是Typecho的活。自定义路由兴许会让URL好看些(比如说/novel/book-name/1/),也不用特地放俩页面到主题文件夹,全都由插件搞定。但对于这个自用项目而言,后续要处理的麻烦事(尤其是各种Corner Case,也就是不起眼角落里给你使绊子的东西),恐怕完全抵消了这一丁点的好处。
3.3 元数据存储
这一部分单独拎出来讲一下。Typecho有一个比较好的功能,就是内容(包括文字与独立页面)的『自定义字段』,也就是与某个内容相关联的若干个结构化键值对。在数据库中,被存储在typecho_fields表内:
比如这个例子,采用tpn作为命名空间由于其拥有良好的数据结构,查询存储都方便,在合理设计字段的情况下,可以替代掉相当大一部分(甚至全部)的额外数据表的需求,同样可以进一步降低开发难度。
4. 写在最后
这一篇作为首篇,就先说那么多了,接下来的篇目再来逐个部分分析与编写代码。
其实一开始写小说的时候,是想用文字去构建一个世界。现在看来,写这个插件,是不是也是『用代码去构建一个世界』呢?
(完)