「瞬きも平気。」 古川政良的疯话记事。内含观剧笔记,同人创作,生活叨叨。 目前正在百合丘女子学院绝赞挂职中。 二半夜发病悲鸣是每个同人女的人生必经之路。 Assault Lily / 重生 / 白夜追凶 / 刀锋上的救赎 / 花归葬。

Re:从零开始的主题写作之路!

!Warning
本文实时(?)记录Bitcron主题「白梦」的写作过程,除了搞事的思路,也分享一些自己想到的比较Tricky的做法或者其他大大们提议的绝赞的想法。

作者有话要说:本文或可作为Baco的系列教程《Bitcron主题制作系列教程》的一个案例补充,所以虽然会介绍一些Tricky的写法,但是并不会系统介绍一个板子要怎么写,想看系统教学请移步Bacoちゃん(嗯!?)的教程~

我想写个板子

一句话总结:开始写板子之前,要知道自己写这个板子想干什么,特别是功能上的要求。

「白梦」是我在某天晚上喝多了茶水睡不着(……)的时候突然想做的一个板子,其实也是在写完「正则」后有点尝到甜头了(?),想搞一笔大的(??),当时就给自己定下了几个想要实现的功能:

这是个写同人小说的作者(就是我)要用的板子,所以这个博客里肯定有很多很多文档是同人小说,我希望这部分文章在展示上能有别于其他日常文章,更符合一般同人圈里阅读文章的习惯:

  1. 原作CP是一定要在Index页面里就展示出来的,'文前预警'我本来在想要不要在Index页展示出来,因为一般它会比较长……最后考虑到作者的博客毕竟不是论坛或者LOFTER,会找过来的估计都对作者会写什么内容有所预期,所以预警这部分只放在文章开头,就不在Index里显示了。
  2. 出于个人偏好,我还是要在Index的展示里加上'字数'——督促自己早日平坑啊早日平坑。
  3. 如果可以,希望原作CP能特别地独立出来进行归档,不跟日常文章归档在一起。
  4. 对五万字以上的大长篇的单独章节进行特别处理,使它能在阅读的时候很顺滑地读下来,不用在茫茫文档中找下一章。
  5. 特别地,对“每个CP的必经之路”的两个文体:论坛体、知乎体,进行界面上的改造,让它们看起来就像一个真的论坛贴或者知乎回答。

列完了基本要求以后你还可以画个蓝图,这对之后写Jade文件和CSS文件会有所帮助~

Daydream_Blueprint

如果是第一次写模板的话,一个蓝图会对你规划DIV有帮助的~

metadata的特性

一句话总结:因地制宜,调整方法。

Bitcron确实是一个拓展性很大的引擎,能自定义的地方非常多,虽然API写得不太好读吧(……),所以我感觉只要不是太过分的要求应该都能满足。

要搞像我这么乱来的特殊功能,有一个Bitcron特殊功能是绝对少不了的:metadata

详细的说明看这里:meta支持 - Bitcron API

简单来说metadata就是对文章的一些文本以外信息的声明,在Bitcron上写文章的时候,我们写的tags: xxx, xxx, xxx也是一个meta,不过tags这个meta比较特殊,这个稍后再说。

我最初的想法就是直接用大量的metadata来实现显示和独立分类,最初的想法是这样的:设置若干个metadata,包括:fandom(原作)、CP(配对)、characters(角色)、rating(分级)、summary(参考AO3)、genre(体裁),由作者填写,其中fandom和CP对应单独的url进行归档。

然而在第一晚的试验的时候,我发现了两个问题:

第一,自定义的metadata在调用的时候类型是一个str,也就是一个key只能对应一个value,我在尝试给它赋一个列表的时候尝试失败了……不过在问过Hepo以后,这个问题得到了解决:自定义metadata,一个key可以给多个value吗?

意思是只要赋值的时候这么写:

---
key:
 - value1
 - value2
 - value3
---

就可以给key赋一个列表了,不过有一个缺点,就是哪怕你只有一个value,为了保持它list的类型,也要写成list的形式。

第二,d.get_data并不能按照metadata来进行检索,我最初是去研究了挺久get_data这个函数的:模板API - get_data,研究完了以后发现了一个很要命的事儿:这个函数拿数据的时候,要么是按照文件夹/路径来检索的,要么是按照时间来检索的,并没有根据meta来检索的参数……

这就有点麻烦了,因为我本来打算的是直接get到同一个meta的数据,然后再列出来作为一个归档的,但是这个数据拿不到怎么办呢?莫非真的要像我在邮件里对Baco说的那样咱们不要归档了吗。

好在办法总是比问题多,Hepo在我的提问下给我提供了一个绝赞的建议:

这个实现不了,不是所有字段都可以被索引的,而没有索引的查询是性能极低的。 建议可以使用 status、path 这些可查询的属性进行改造。
或者使用 tags 也可以呀, 比如 tags: __xxxx 这种特别标记的, 一来不要在全局的网站 tag 呈现中显示, 二来也可以作为 filter 来用。

卧槽,看到“用带标记的tags来进行归类”这个操作,我的第一想法:真是太酷了……

于是最后整理下来,剩下的matadata就只剩下了:

其他都因为感到没什么必要砍掉了(写summary我认真想了一下,确实欧美圈这么约定俗成的更多一些,国产圈和日漫圈我基本没见过,所以还是算了),而原来的fandomCP两个需要检索的本来的metadata,改为在tags内用特殊标记定义。

最终写起来应该是这样:

---
title: 深夜树洞,国麻过后我喜欢的CP应该就没有后续了
tags: fandom_天才麻将少女 cp_咲和 cp_照堇 论坛体
genre: forum
warning: 
 - 正主全文未出现
status: public
…
---

写起来大概就像上面那样。

对带标记的Tag进行截断

一句话总结:不懂就查,试错中改进……

tags内进行标记解决了检索的问题,同时根据Hepo的指点,可以用if not tag_name.startswith('__')作判断,区分不同的标记,于是我根据tag.startwith("fandom_")tag.startwith("cp_")以及不带标记 把tags分成了三类进行输出。

但是有个问题。

如果直接这么写:

for tag in post.tags
  if tag.startwith("fandom_")
    span.info_name= tag
  elif

那么输出来的结果会带上特殊标记。

好丑。

所以我需要对tag进行一个截断,因为我的前缀标记都是固定的,所以只要从特定的位数开始截断就行,比如cp_XXXX,我只要从第三位(计算机一般是零开始计数的)开始截断就可以了。

最终经过自己折腾和网上各路神仙们留下的宝贵材料,终于实现了这个小技巧,在jade文件中直接书写行内js,代码片段如下:

span.info
  i.fa.fa-book
span.info_name= '原作:'
  for tag in post.tags
    if tag.startswith('fandom_')
      span.info_item
        script.
          var i = "{{tag}}";
          i = i.substring(7);
          document.write(i.link("/tag/{{tag}}"))

其中i = i.substring(7)代表从i的第8个字符(从0开始数就是第7个啦)开始截断,如果有长度要求的话,也可以写两个数,比如i = i.substring(3, 5)代表从第3个字符到第6个字符。

在查的时候其实我主要查的是html里写js的,因为jade的教程确实不多,然后按照jade的逻辑自己写了一遍,对照Baco给的神器html2jade转出来的代码改了改bug,幸好能编译通过……

h.show实现特殊模板的载入

一句话总结:判断是重要的。

接下来是另外一个重要的,但是也很棘手的功能:知乎体/论坛体的渲染。

想一想,难实现的地方在哪里呢?

  1. 要对页面进行独立渲染,所以不能载入原本的base.jade,但是其他文章又需要载入base.jade
  2. 知乎回答会有很多额外的信息,而markdown原文检索是不太现实的。

然后在研究的时候我一直在想如果Bitcron的APP功能可以自定义就好了,好想问问Hepo啥时候开放APP自定义……

然后我突然看到了这个说明:在 Markdown 中引入快捷模板

登时豁然开朗,于是去尝试了一下h.show到底是个什么效果,最后发现是在文里你写code的那一块载入模板,其他部分还是会正常输出文本。

好吧,那我看看怎么改一改……

最终的办法是,在post.jade的最开头,引入特殊模板的判断:

if post.metadata.genre in ["zhihu"]
  +h.show("zhihu")
elif post.metadata.genre in ["forum"]
  +h.show("forum")
else
  extends base.jade
  

注意:为了在特殊模板状态下,让你文章的其他东西不要在页面中显示,你一般文章的格式(也就是post.jade的核心部分)需要全部放到else之下(也就是通过了else的判断之后再输出),所以如果是拿自己原来的post.jade改造的话,主体部分的缩进要多一个。

然后在template文件夹里建一个show的子文件夹,特殊模板的jade和scss就放在这里,参见上文那个快捷模板的说明。

然后是第二个问题,额外信息的处理。

我简单粗暴全部用metadata填写了,就是这么潇洒。

所以知乎体需要填一大堆metadata,不过无所谓啦,写正文里也是写,填meta里也是写,无所谓……

我把知乎体的文件单独拿出来了,具体的说明可以看这里:Bitcron快捷模板「知乎体」

最终效果是这样的:

End.
Comments
Write a Comment
  • 欢迎加入Bitcron模板制作大家庭!(暂时只有我一个成员吧可能)总之太好了哈哈哈!你技术如此之好,我都想退役了(爽朗)

    • @水八口 不行啊啊啊啊!你退役了就剩我一个了!很寂寞的!(什么)而且我技术哪里好了(。)还不是边查边骚扰你和Hepo(什么)

      • @矩阵良 我发现你吸收API的速度非常快,反正比我快多了,内心好欣慰(辛苦拉扯大的孩子终于能够独当一面了{大误})。不过设计的细节还有待优化(←来自火眼金睛的处女座)

        咱可以考虑做个combi呀,我出设计你编码,或者你出想法我设计你再编码,或者你设计我优化你编码(对,全都是你编码{爽朗})

        • @水八口 然后Github上就出现了一堆“Designed by 水八口,Code by 矩阵良”……画面太美23333我觉得阔以有!有设计的时候我写板子Jade的速度还是很快的!写CSS速度比较不行,因为调不到好看的位置(……)唉不要为难一个理工直男做设计……

          • @矩阵良 感觉找到了灵魂伴侣!我审美在线呀,我来!我一直希望把功能定好后有人给我写好框架,我来写样式,哈哈哈哈哈哈哈哈哈哈!搭配好的话搞不好会成为Bitcron御用主题设计团队的一员(Hepo在扶额)

            • @水八口 可以有!我贼拉不喜欢写CSS因为写CSS太多细节调整消磨热情……靠,我把手头这个写完了咱俩合作来一个吧!(Hepo表示这个写代码的小同学三天两头问奇怪的问题真的能行吗(大雾))

              • @矩阵良 好哇!你算是厉害的,我看Hepo的回复经常不知道什么意思……

                那么还是邮件沟通细节吧!

  • 看到你们这么认真的钻研精神我都感动了!

    • @小F 是我需求太吊诡,不折腾就没人带了(泪奔ing)

    • @小F 哈哈,快来加入阵营!我感觉你把设计稿交给她做得更快[捂脸]

  • 问下metadata是list的话,要怎么用for来遍历里面的内容呢

  • for i in post.metadata.cc

    {{i}}

    原来是这样。。。

    • @XX 不好意思最近生病中睡得比较早……嗯,就跟tags啊category啊一样的写法