一周前,我构建了 Notion Flow 浏览器扩展:
而刚刚更新的 0.4.1 版本:
支持了兼容 AWS S3 API 的自建 OSS 服务,如 Cloudflare R2:
Cloudflare R2 | 零出口费用分布式对象存储 | Cloudflare | Cloudflare
本篇文章简单介绍一下我是如何使用这个浏览器扩展用于我的 Github Jekyll 博客的。
Jekyll 静态博客是基于 Ruby 构建的,支持插件。所以我自己写了几个插件(Jekyll 博客的插件位于 _plugins
目录下,写好 ruby 文件后,丢到该目录下,重启服务即可)来处理 Liquid 模板语言,而内容就是来自 Notion Flow 转换的 Notion 内容。如处理 bookmark 的插件内容如下:
{%raw%}
module Jekyll
class RenderBookMarkBlock < Liquid::Block
def initialize(tag_name, attr, tokens)
super
# 普通的链接没有 yid 和 bid
attrs = attr.scan(/url\\=\\"(.*)\\"\\stitle\\=\\"(.*)\\"\\simg\\=\\"(.*)\\"\\syid\\=\\"(.*)\\"\\sbid\\=\\"(.*)\\"/)
if !attrs.empty?
# 外部的 video 链接,youtube、bilibili(如本文上一篇博客就是)
@url = attrs[0][0]
@title = attrs[0][1]
@img = attrs[0][2]
@yid = attrs[0][3]
@bid = attrs[0][4]
@firstChar = (@title)[0].upcase
@error = ""
else
# 正常和 notion 一样的 bookmark(如本文上面三个链接就是)
attrs = attr.scan(/url\\=\\"(.*)\\"\\stitle\\=\\"(.*)\\"\\simg\\=\\"(.*)\\"/)
@url = attrs[0][0]
@title = attrs[0][1]
@img = attrs[0][2]
@firstChar = (@title)[0].upcase
@error = ""
end
end
def render(context)
@desc = super
if [email protected]? && [email protected]?
"<p class='embed-responsive embed-responsive-16by9'><iframe src='<https://www.youtube.com/embed/#{@yid}?rel=0>' title='YouTube video player' frameborder='0' allow='accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture' allowfullscreen></iframe></p>"
elsif [email protected]? && [email protected]?
"<p class='embed-responsive embed-responsive-16by9' style='border-bottom: 1px solid #ddd;'><iframe src='//player.bilibili.com/player.html?bvid=#{@bid}&high_quality=1&as_wide=1' scrolling='no' border='0' frameborder='no' framespacing='0' allowfullscreen></iframe></p>"
else
"<p><a class='link-bookmark' href='#{@url}' target='_blank'><span data-bookmark-img='#{@img}' data-bookmark-title='#{@firstChar}'><img src='#{@img}'/></span><span><span>#{@title}</span><span>#{@desc}</span><span>#{@url}</span></span></a></p>"
end
end
end
end
# 上传的 video
module Jekyll
class RenderVideoBlock < Liquid::Block
def initialize(tag_name, attr, tokens)
super
attrs = attr.scan(/caption\\=\\"(.*)\\"\\simg\\=\\"(.*)\\"\\ssuffix\\=\\"(.*)\\"/)
@caption = attrs[0][0]
@img = attrs[0][1]
@suffix = attrs[0][2]
end
def render(context)
text = super
"<p caption='#{@caption}'><video controls muted><source src='#{@img}' type='video/#{@suffix}' /></video></p>"
end
end
end
Liquid::Template.register_tag('render_bookmark', Jekyll::RenderBookMarkBlock)
Liquid::Template.register_tag('render_video', Jekyll::RenderVideoBlock)
{%endraw%}
这段的逻辑是如果遇到 Notion 的 bookmark 模块链接是 Youtube、Bilibili,则转成嵌入视频的 HTML(iframe),否则转成类似于 Notion bookmark 的 HTML(需要配合 CSS 实现)。
所以我使用 Notion Flow 将 Notion 内容转换成 Markdown 格式的同时,自定义了 bookmark 等模块的转换规则,以让博客能够显示 Youtube、Bilibili 和与 Notion 一样的 bookmark 样式内容,如下:
video: function video(block) {
if (block.type === 'file') {
// 用户自己上传的 video 文件,用默认 video 插件处理
return `{% render_video caption="${block.caption}" img="${block.url}" suffix="${block.suffix}" %}\\n![${block.caption}](${block.url})\\n{% endrender_video %}\\n`;
} else if (block.type === 'external') {
// 外部链接、youtube 和 bilibili 视频链接,用 bookmark 处理
return `{% render_bookmark url="${block.url}" title="${block.caption || ''}" img="" yid="${block.yid}" bid="${block.bid}" %}{% endrender_bookmark %}\\n`;
}
}
这里需要注意(我不太懂 ruby), Liquid 模板的标签之间,必须有文本内容(你可以不用),否则,ruby 插件无法生成 HTML。即:
{% render_video %}这里必须有任意内容!{% endrender_video %}
这样在 ruby 插件中,super
变量拿到的就是「这里必须有任意内容!」这句话(你可以不使用该变量)。如果没有这段内容,则插件压根不会返回任何内容。