15158846557 在线咨询 在线咨询
15158846557 在线咨询
所在位置: 首页 > 营销资讯 > 网站运营 > 思源笔记折腾记录-效果更好一点的发布

思源笔记折腾记录-效果更好一点的发布

时间:2023-07-27 23:30:02 | 来源:网站运营

时间:2023-07-27 23:30:02 来源:网站运营

思源笔记折腾记录-效果更好一点的发布:

一、前情提要:




我们在之前,通过引入express,实现了一个简单(lou)的发布功能。

现在我们来实现一个复杂一点的。




二、为什么要用思源鼓捣网站




如果你随便搜索一下cms的话,就会看到大概这样的描述:




cms指的是内容管理系统,可以用来管理网站的各种文件、数据、乃至其他信息。



额,为什么说到这个呢。




其实是之前我不是自建了一个网站吗,然后最开始用的是wordpress,之后鼓捣起来实在是有点麻烦。




就又换成了某个现成的建站系统。




然后发现哎呀好像还是不行,我写很多的东西的,他的编辑器虽然功能丰富记界面美观,但是写东西实在是太慢了。




之后又把内容迁移到了我来,开始是用obsidian编辑之后,复制到我来发布,后来是用思源编辑之后, 用我来发布。




再后来就发现,哎呀还是不行,我来的收费政策又改了,本来就赚不到钱,也不可能花太多钱在这个上面的,而且主要是发现自己手上没有数据,万一那边政策一个变化,文件不就等于丢了么。。。。。。




之后我在使用服务器上部署的思源的时候,突然想通了一件事情:




你看,我需要能够方便舒适地在各种地方编辑网站内容,思源可以做的对吧。




我需要能够上传下载和管理附件,思源也可以做的对吧。




我需要有一个基本的静态文件服务,思源也可以做的对吧。




我还需要它能够方便地“原样”在我自己的设备上和服务器上预览,欸,巧了,思源刚好开源了,界面可以直接摸,基础的样式框架也不用自己写了。




好耶~~~




额,其实最关键的是,现有的好多建站工具的文本编辑体验实在是有点不习惯,还是用熟悉的编辑器鼓捣起来舒服.....




好了,闲话说完了,我们看一下之前的发布效果:
















额,不是说这个。




是这个:











还记得有个人曾经说过,想要做到所见即所得的发布么......




这个完全不像好吧。




更好看一点的页面模板




还记得思源本身有一个能够按照原样发布html的功能吗?











嗯,就是这个。




它导出的html,是这样的:











看着还可以哦,我们来看一下是怎么做到的:











上面是导出文件的目录,嗯,所以我们只需要挨个导出文件,然后把他们发送给访问者就行了对吧。




额,你如果这样做其实也不是不行,不过我这里要用另外一种办法,毕竟我是想要用它来做一个简单的博客,那文档树、大纲、反向链接、 关系图、导航栏我还是都想要的。




所以我们还是要自己写一写。




获取块dom




还记得我们之前用的是哪个接口来弄发布内容的吗?




let 文档内容 = await noobApi.核心api.exportPreview( { "id": 文档数据.id } )


这个接口获取的DOM实际上对应的是这个界面:











额,其实也还挺好,我们复制到本站什么的也就基本上是这个样子了。




但是说好的原样的吗,我们必须给整一个差不多原样的出来。




这里需要的接口就是这个:




/api/getDoc


这个接口实际上就是获取文档DOM的接口。




这里我们先不纠结太多,直接按照这样传一下:




{id:<块id>size:102400mode:0}


也就是把之前的渲染函数里获取文档内容的部分从这样:




let 文档内容 = await noobApi.核心api.exportPreview( { id: 文档数据.id, } )


改成这样:




let 文档内容 = await noobApi.核心api.getDoc( { id: 文档数据.id, mode:0, size:102400 } )


好,现在刷新一下在浏览器,就可以看到渲染结果了,它长这样:











这是为什么呢?




我们可以打开思源的开发者工具,找到这个元素












然后删掉它看看(右键里面就有删除),后果美如画:











这个时候我们再看看之前导出的html里的内容:











等于我们其实只拿到了一个没头没尾的dom,光靠它,没有那些js 和css代码,显然弄不出一个好看的导出页面。




所以又悟了:只要把这些加到渲染结果里面就可以了。




创建一个渲染主题




这个时候就该停下来想想了,难道还像我们之前写菜单的时候那样,在js里面硬写这些来搞吗?




这样怕是有点难受。




所以我们另外想一个办法。




来看一下一些其他建站系统的主题:




这个是wordpress:




WordPress主题制作教程:主题文件解析-菜鸟笔记 (coonote.com)




index.php //主模板文件,所有主题都需要它style.css //样式表文件,不可缺少,并包含主题的信息标题rtl.css //如果网站语言的文本方向是从右到左,则会自动包含从右到左的样式表comments.php //评论模板。page.php //访问者请求单个页面时使用页面模板,这些页面是内置模板。home.php //默认情况下,主页模板是首页。如果您没有将WordPress设置为使用静态首页,则此模板用于显示最新帖子。header.php //头部模板文件通常包含您网站的文档类型,元信息,样式表和脚本的链接以及其他数据。footer.php //公共底部模板sidebar.php //侧边栏模板single.php中 //日志模板。archive.php //归档模板,如果分类标签页没有模板的话,会使用这个模板category.php //分类页模板tag.php //标签页模板search.php中 //搜索结果模板用于显示访问者的搜索结果。404.php //当WordPress无法找到与访问者请求匹配的帖子,页面或其他内容时,将使用404模板functions.php //增加WordPress功能


这是hugo




如何创建自己的hugo主题 - 简书 (jianshu.com)




所以我们也来搞一个发布主题系统,嘿嘿嘿。




其他的我们先不管,先来看看内容页面,要实现一个内容页面模板,无非就是弄一个模板,然后填内容进去,那么怎么实现内容模板呢?(小编写不出东西来了都这样)




这里我使用了一个非常杀马特的办法,我们要知道,electron的渲染进程虽然有node环境,但是它也有浏览器环境啊,所以我们就不去找各种奇怪的模板引擎了,我们直接这样:




let 渲染结果 = new DOMParser().parseFromString(docTemplate, "text/html"); 渲染结果.getElementById('content').innerHTML = 文档数据.content


这个是什么意思呢,就是生成了一个document​对象,所以在这个的基础上,我们可以使用js对这个对象进行各种操作,比如注入文档内容,这样也比较适合我们这种不大会写程序的嘛,不用学更多新的东西了,由于文档都是我们自己写的,就算解析成html,应该也不会搞出什么奇怪的问题。




然后我们使用它,来实现一个渲染函数, 这里模仿一下express对请求的处理,每一步对渲染结果做一点操作,最后就搞出来一个完整的页面了,因为是像管道一样流过这一堆函数,所以我们叫它管线渲染器吧:




//这个就随便导出一个文档就行了let 默认模板路径 = 代码片段路径 + 'publishTemplate/default/doc.html'async function 渲染页面内容(req,res,渲染结果){ let 块id = req.params.blockID let 页面数据 = await 获取数据(块id) 渲染结果.getElementById('publish-content').innerHTML = 页面数据.content console.log(渲染结果) return 渲染结果}let 默认渲染管线 = 生成管线渲染器([渲染页面内容],默认模板路径)


而这个是生成管线渲染器的实现:




export function 生成管线渲染器(渲染管线, 模板路径) { return async (req, res) => { //这里是告诉浏览器,我返回的是一个html页面 res.writeHead(200, { "Content-Type": "text/html;charset=utf-8" }); let 渲染结果 = new DOMParser().parseFromString(fs.readFileSync(模板路径), "text/html"); //这里是一个循环,不断地把渲染结果和请求喂给它们,所以渲染管线中的每一步也都可以跳出去,直接响应请求 for await (let 渲染函数 of 渲染管线) { try { //如果渲染结果没有这个函数说明它不是数据了 if (!渲染结果.querySelector) { let tempdoc = new DOMParser().parseFromString( 渲染结果, "text/html" ); 渲染结果 = tempdoc; } if (渲染结果.完成) { return 渲染结果; } if (渲染函数 instanceof Function) { 渲染结果 = (await 渲染函数(req, res, 渲染结果)) || ""; } let 文字渲染结果 = ""; try { 文字渲染结果 = 渲染结果.querySelector("body").innerHTML; } catch (e) { 文字渲染结果 = 渲染结果; let tempdoc = new DOMParser().parseFromString( 文字渲染结果, "text/html" ); 渲染结果 = tempdoc; console.error(e); } } catch (e) { console.error(e); continue; } } //如果有结果就返回结果 try { if (渲染结果) { res.end(渲染结果.documentElement.innerHTML) } else { res.end('渲染出错,没有有效的结果') } } catch (e) { 渲染结果 = null console.error(e) } //万一我们这里对它还有其他操作呢 return 渲染结果 }}


获取文档内容就不用说了:




async function 获取文档内容(块id) { let stmt = `select * from blocks where id in (select root_id from blocks where id = "${块id}" )` let 文档数据 = (await noobApi.核心api.sql({ stmt: stmt }))[0] let 文档内容 = await noobApi.核心api.getDoc( { id: 文档数据.id, mode: 0, size: 102400 } ) return 文档内容}


这样弄完之后,我们再访问一下,发现效果还是这样:











那问题出在哪里呢?




<link rel="stylesheet" type="text/css" id="themeDefaultStyle" href="stage/build/export/base.css?2.5.2" /> <link rel="stylesheet" type="text/css" id="themeStyle" href="appearance/themes/daylight/theme.css?2.5.2" />


这是导出的文件里的样式表,我们的服务器从根目录就直接跳转到渲染页面了,所以没有给他们返回正确的文件。




所以我们改一下路由:




发布应用.use('/', async (req, res, next) => { console.log(req)//首页重定向到帮助文档首页,你也可以自己选一个 req.url == '/' ? res.redirect('/20200812220555-lj3enxa') : null next()})发布应用.use('/:blockID', 默认渲染管线)


然后想办法提供一下那两个文件夹。




之前导出的页面文件夹里面其实就有这些文件了,所以我们把它们也放到publishTemplate/default​里面,然后给它们做下静态文件伺服就可以了:




发布应用.use('/appearance',express.static(代码片段路径 + 'publishTemplate/default/appearance'))发布应用.use('/stage',express.static(代码片段路径 + 'publishTemplate/default/stage'))


现在再访问一下试试看:











bingo,完成。




这里使用的 express.static 方法的作用就是把某个文件夹当成静态文件夹挂在路径下面,所以用了它之后就可以访问到对应的文件了.




虽然还有很多问题,但是基本的内容渲染出来了不是吗?




这次就先这样吧。









本文使用思源笔记写作

本文使用椽承设计小工具配合同步

本文使用 文章同步助手 同步

关键词:发布,效果,笔记,折腾,记录

74
73
25
news

版权所有© 亿企邦 1997-2025 保留一切法律许可权利。

为了最佳展示效果,本站不支持IE9及以下版本的浏览器,建议您使用谷歌Chrome浏览器。 点击下载Chrome浏览器
关闭