模板: 通过 SQL 实现动态双链

image.png

思源现阶段有一个缺点,双链不是动态的,你只能生成已有的文档的双链,而不能获取在将来写的文档的双链,需要用户做一个手动的收集.(可能之后的子页面视图会改变这一状况).而个人感觉上 SQL 查询的样式,在视觉上占地儿太大了.于是尝试通过 SQL 来实现 "双链的"效果.要考虑的点有两个.

因为 SQL 块本身带有打开对应文档的功能,所以需要需要查询出的"文本".最直接,最简单的,就是显示出对应文档的一级标题. 但这版本思源笔记会默认在最顶端显示文件名, 很多情况下我不会去写一级标题,此外当查询标题块的时候,会直接显示该标题下的全部内容,并不适合作为双链来展示. 最佳的查询对象是普通的文本块.

而我自己会在每个文档头生成基础的文档信息, 这些内容全部都是普通的文本块.(在本文开头所展示的内容,我会给他们设置不同的属性),所以我直接根据需求将想要的特定文档信息通过 SQL 查询出来.

每一项的 name 我都设置为了 DocInfo 方便管理,alias 则根据不同的功能设置不同的值.

@Path: /SiYuan/动态双链.sy 我给这个本文块的 alias 设置为 @Path,而当我想要获取一个文档的双链时,我就会通过 SQL 查询该属性.

SELECT * FROM blocks WHERE box='.action{$docBox}' and name='@Path' and content LIKE '%?%'

其次就是 SQL 嵌入块的样式.我个人不希望一个提示性的链接会侵占太多空间,同时需要我能够方便的点击打开笔记的按钮, 因此通过 CSS 将其设定为,查询语句中有 @Path 时,会直接更改 SQL 的样式 ,且将 iocn 调整为出现在左侧.

示意图

image.png

本文仅代表一种思路,并不代表一个优秀的实操方式. 是否能够有一个有实际作用,有效的 SQL 动态链接,取决于每个人的笔记组织方式和个人习惯.

更新

2021 年 8 月 4 日

将两个超级块看上去像是一个文本块. 效果参见开头的图片中的 @Assets 字段,该字段通过 SQL 嵌入块获取该笔记本中的的 Assets 文档(用于统一管理该笔记本所需要用的外部资源)

将嵌入的 SQL 块宽度设置为随内容长度变化. 并且隐藏了 DocInfo 的属性标识.

DynLink 模板专门用于插入 SQL 语句,但是该语句需要换行插入

后续有时间的话会再编写一个模板,专门用于插入动态的双链.格式即为 @Source:{{SQL语句}} .但由于更改了 CSS 为随着内容长短变化,并且也只是一个两列的超级块, 也仅限需要在 SQL 块前加一些简短的注释的情况下使用.

代码

CSS
/****************************************DocInfo****************************************/
/***************************************************************************************/
/***************************************************************************************/
/*整体的颜色,字体*/
[data-node-id][name="@DocInfo"]{
	font-size: 14px!important; 
	padding:0px!important;
	color:#7a8892;
	font-style:italic;
}
/*粗体的颜色*/
[data-node-id][name=@DocInfo] Strong{
	font-size: 14px!important; 
	padding:0px!important;
	color:#7a8892!important;
	font-style:italic;
}
/*去除DocInfo部分的别名和命名的显示*/
[data-node-id][name=\@DocInfo] .protyle-attr{
	display: none!important;
}
/*让超级块中的两个块,实现根据内容调整宽度*/
.protyle-wysiwyg [data-node-id][name=\@DocInfo].sb[data-sb-layout="col"]>div{
	flex:none!important;
}

/*更改Assert部分的宽度*/
[data-node-id][data-type=NodeSuperBlock][name=DocInfo]+[data-type=NodeSuperBlock].sb[data-sb-layout=row]{
	width:fit-content!important;
}
/*Assert和链接之间的间隔*/
[data-node-id][name=\@DocInfo][alias=\@AssetsHead]{
	margin-right: 10px;
}

/*调整SQL嵌入块中的图标*/
.protyle-wysiwyg [data-content*=\@DocInfo][data-node-id].render-node[data-type="NodeBlockQueryEmbed"] .protyle-icons{
	left:4px;
	right:auto;
}
/*sql块的宽度和高度*/
.protyle-wysiwyg [data-content*=\@DocInfo][data-node-id].render-node[data-type="NodeBlockQueryEmbed"]{
	padding : 0px!important;
	width:fit-content!important;
	min-height:fit-content;
}


Templates
DocInfo
.action{/*获取文档的基本信息*/}
.action{$docID:=.id}
.action{$docTitle := .title}
.action{$docBox :=" "}
.action{$docPath := " "}
.action{$docCreated := " "}
.action{$docUpdated := " "}
.action{$getDocInfo := (queryBlocks "SELECT * FROM blocks WHERE id='?' and type='d' " $docID )}
.action{range $v:= $getDocInfo}
	.action{$docBox =$v.Box}
	.action{$docPath = $v.Path}
	.action{$docCreated = toDate "20060102150405" $v.Created | date "2006-01-02"}
	.action{$docUpdated = $v.Updated}
.action{end}

.action{/*获取Assets所在的文件*/}
.action{$getAssets := (queryBlocks "SELECT * FROM blocks WHERE box = '?' and  type= 'd' and path like '%Assets%' LIMIT -1" $docBox)}
.action{$assetsID:=" "}
.action{range $v:= $getAssets}
	.action{$assetsID = $v.ID}
.action{end}


.action{/*DOCPART*/}
--- 
{: name="@DocInfoBegin" alias=""}
###### 备注:
{: name="@DocInfo" alias=""}
@CreateTime: .action{$docCreated}
{: name="@DocInfo" alias=""}
@Author: Crowds
{: name="@DocInfo" alias=""}
@Type: Assets / Doc / Schedule /Draft
{: name="@DocInfo" alias=""}

{{{col
{{{
@Assets: 
{: name="@DocInfo" alias="@AssetsHead"}
}}}
{: name="" alias=""}

{{{
{{SELECT * FROM blocks WHERE box='.action{$docBox}' and name="@DocInfo" and alias='@Path' and content LIKE '%Assets%'  }}
}}}
}}}
{: name="@DocInfo" alias="@Assets"}

@Path: .action{$docPath}
{: name="@DocInfo" alias="@Path" style="color:var(--b3-font-color6);!important"}

---
{: name="@DocInfoEnd" alias=""}
.action{/*获取文档的基本信息*/}
.action{$docID:=.id}
.action{$docTitle := .title}
.action{$docBox :=" "}
.action{$docPath := " "}
.action{$docCreated := " "}
.action{$docUpdated := " "}
.action{$getDocInfo := (queryBlocks "SELECT * FROM blocks WHERE id='?' and type='d' " $docID )}
.action{range $v:= $getDocInfo}
	.action{$docBox =$v.Box}
	.action{$docPath = $v.Path}
	.action{$docCreated = toDate "20060102150405" $v.Created | date "2006-01-02"}
	.action{$docUpdated = $v.Updated}
.action{end}


{{SELECT * FROM blocks WHERE box='.action{$docBox}' and name="@DocInfo" and alias='@Path' and content LIKE '%?%' }}
4 操作
crowds21 在 2021-08-05 08:29:27 更新了该帖
crowds21 在 2021-08-04 16:46:45 更新了该帖
crowds21 在 2021-08-04 16:15:28 更新了该帖
crowds21 在 2021-08-03 21:09:58 更新了该帖

广告 我要投放

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...
  • crowds21 1 评论
    订阅者 作者

    同样这个效果可以应用到生成文档目录上。不过有了子页面后,就不需要这个功能了。

    还可以试一下,能不能把 sql 嵌入块和文本块放在同一行
    crowds21 1 赞同
  • a1993613
    支持者 订阅者

    要不楼主直接提交到集市里的模板那吧,这样更方便大家使用

    1 回复
  • crowds21
    订阅者 作者

    这个是需要配合 CSS 才能有最好体验的. 上面两个已经是全部的代码了,无脑复制就可以了.也只是一个思路而已,自己对模板和 CSS 修改起来也不是太难.

    模板集市上架的话需要经常性维护,比较费时费力.而且整个工作流程在我个人的笔记本里还没有得到一个比较好的实际应用,思路还需要继续修改,效果还需要实际观察,比如现有的 Organized 其实还有挺多毛病的.

    我个人希望能整合成一整套再上传上去.

    所以目前来说我更倾向于把实际应用发现的问题先汇总到帖子里,集市的话,等再整理一下吧.

  • crowds21
    订阅者 作者

    这种思路还是太复杂了. 涉及 CSS 还有大量的属性.对于经常需要编辑的区域,我能接受的对 CSS 的复杂度,只有一个调整特定 SQL 的长度. 只能是牺牲视觉上的效果了.

    所以并列的效果,还是只在 DocInfo 中提供比较好.其余地方,使用其他的属性用作区分.

    动态的任务交给之后的挂件块是否会更好一些? 但是 iframe 也是,视觉上有些过于占地方了,不适合放在文本中间.在头部或者尾部,用作集中展示好一些.