个人建站:主站与静态static资料的正确衔接
1 netlify文件夹体系
使用blogdown进行netlify建站,下述三个文件夹及作用需要区分清楚:
content
文件夹,主要进行写作或者接口配置(链接等),对接包括:post、publication、course、project等static
文件夹,主要存放来自其他仓库的静态资料。例如,xaringan slide课件制作往往在我的另一个课程仓库(如course-econometrics
),相关文件资料(html
)需要提前拷贝到这个文件夹对应位置。public
文件夹,是建站结果的最终目录树文件系统。netlify服务器网站可以方便国际用户访问,但国内访问速度较慢。public/
后期还要更新到本地另外一个域名服务器网站(方便国内访问)。(见之前的博客文章)
1.1 netlify content文件系统
levelName
1 netlify
2 |--static
3 |--content
4 | |--course-advanced-statistics
5 | |--course-econometrics
6 | | |--data
7 | | |--schedule-theory.Rmd
8 | | °--schedule-theory.html
9 | |--post
10 | |--project
11 | °--publication
12 |--public
13 |--config
14 °--netlify.Rproj
1.2 netlify static文件夹系统
levelName
1 netlify
2 |--static
3 | |--course-advanced-statistics
4 | °--course-econometrics
5 | |--data
6 | |--pic
7 | | |--chpt1-log.png
8 | | °--chpt2-reg.png
9 | |--reading
10 | | |--cht01-history.files
11 | | °--cht01-history.html
12 | |--01-introduction-slide.html
13 | °--02-simple-reg-basic-slide.html
14 |--content
15 |--public
16 |--config
17 °--netlify.Rproj
1.3 netlify public文件系统
levelName
1 netlify
2 |--static
3 |--content
4 |--public
5 | |--course-advanced-statistics
6 | °--course-econometrics
7 | |--schedule-theory
8 | |--data
9 | |--pic
10 | | |--chpt1-log.png
11 | | °--chpt2-reg.png
12 | |--01-introduction-slide.html
13 | °--02-simple-reg-basic-slide.html
14 |--config
15 °--netlify.Rproj
2 netlify相关联的Github仓库
目前而言,neglify主站相关联的主要github仓库有:
主站仓库:
netlify
仓库,基于hugo-academic网站模板,集合了众多的其他仓库的展示材料教学课程仓库:主要包括本科课程《计量经济学》
course-econometrics
;本科课程《统计学原理》course-statistics
;研究生课程《中级计量经济学》master-SEM
等。主要关联材料包括:课件Xaringan slide;补充材料html;pdf等。研究项目仓库:包括各类开源的研究类仓库,如agri-trade-open;team-students等。
其他仓库
2.1 Xaringan slide的正确操作
使用Xaringan制作教学slide。需要注意到Xaringan制作的slide是不能独立封装的(self-contained),也即它需要依赖各种必要组件或资源。
2.1.1 xaringan slide的典型文件结构
课程仓库下xaringan slide制作的典型文件结构:
levelName
1 course-econometrics
2 |--data
3 |--pic
4 | |--chpt1-log.png
5 | °--chpt1-curve-points.png
6 |--01-class-instruction
7 |--02-lab-exercise
8 |--03-slide-class
9 | |--libs
10 | | |--crosstalk-1.1.1
11 | | |--htmlwidgets-1.5.3
12 | | | °--htmlwidgets.js
13 | | °--remark-latest.min.js
14 | |--01-introduction-slide_files
15 | | °--figure-html
16 | | |--unnamed-chunk-14-1.png
17 | | °--unnamed-chunk-15-1.png
18 | |--01-introduction-slide.html
19 | °--01-introduction-slide.Rmd
20 |--template
21 |--EViews
22 |--mycss
23 |--public
24 °--course-econometrics.Rproj
2.1.2 Xaringan Rmd调用本地图片文件
值得注意的是Xaringan Rmd使用本地图片文件(存放在pic/
文件夹下),应该使用相对路径,而不是绝对路径(参看the full path approach doesn’t work)。也即意味着:
不能使用绝对路径
D:/github/course-econometrics/pic/chpt1-log.png
同时也不能使用
here::here("pic","chpt1-log.png")
,因为它也会给出绝对路径"D:/github/course-econometrics/pic/chpt1-log.png"
那么Rmd文件01-introduction-slide.Rmd
对上述本地图片的函数化引用应该设为相对路径形式,如:
markdown
语法:![]("../pic/chpt1-log.png")
或者
knitr
语法:include_graphics("../pic/chpt1-log.png")
总结起来,图片绝对路径和相对路径的差异比较如下:
绝对路径直接无法渲染出图形
相对路径可以渲染出图形,而且可以使用chrome浏览器开发工具看到html元素
# html develop tool view
<div class="figure" style="text-align: center">
<img src="../pic/chpt1-log.png" alt="一份样本数据" width="693">
<p class="caption">一份样本数据</p>
</div>
2.1.3 Xaringan Rmd代码块生成的graph
Rmd使用代码块生成的图片这会自动存放在同名文件夹下的一个文件夹内。如01-introduction-slide.Rmd
,则代码块chunk-14
制图将存放在自动生成的文件夹01-introduction-slide_files/figure-html/unnamed-chunk-14-1.png
。
例如,R代码块14如下:
# r code chunk 14
ggplot(data.frame(x = seq(from = -5, to=5,length =500 )), aes(x = x)) +
stat_function(fun = dnorm, args = list(0,1),
aes(color = "mean=0, sd=1")) +
stat_function(fun = dnorm, args = list(0.5,2),
aes(color = "mean=0.5, sd=2")) +
scale_colour_manual("期望和标准差", values = c("red", "blue"))+
scale_y_continuous(name = "概率值(probability)") +
theme(legend.text = element_text(size=16), legend.title = element_text(size=16))
可以使用chrome浏览器开发工具看到其对应的html元素:
<!--- html develop tool view--->
<div class="figure" style="text-align: center">
<img src="01-introduction-slide_files/figure-html/unnamed-chunk-14-1.png" alt="正态分布(n=500)">
<p class="caption">正态分布(n=500)</p>
</div>
3 若干netlify对接技巧
3.1 netlify内部相互链接
如果要直接在/content/course-econometrics
下用Rmd文件生成.html,然后再别处来调用这个内部的html文件?
1.基于主站的相对链接引用(已测试)。参看“队长”问答Linking to another post in blogdown
- 设置基准地址,修改
config.toml
参数:
# config.toml
baseurl = "https://yourdomain.netlify.app/"
- 设定内部引用规则,修改
config.toml
参数:
# config.toml
[permalinks]
# If only creating events which are talks, we can optimize event URLs for talks.
event = "/talk/:slug/"
# Workaround Hugo publishing taxonomy URLs as plurals - consistently use singular across Academic.
tags = "/tag/:slug/"
categories = "/category/:slug/"
publication_types = "/publication-type/:slug/"
post = "/:year/:month/:day/:slug/"
- Rmd内部链接1:对于hugo标准模块内容的链接。所谓hugo标准模块内容,一般包括hugo版本内置好的
post
、publication
、tags
等,可以通过上述config.toml
的参数块[permalinks]
看到其影子。因此,对于hugo标准模块内容的链接引用,都需要在这里指定链接的参数形式。值得说明的是:a.务必要按前述各个模块的链接地址规则进行url设定。b.不要画蛇添足/2020/10/05/hugo-big-update/index.en.html
(哪怕文件夹下有这个html文件);c.只要设定了refer ID(如{#your-section-refer}
),就可以进行更进一步的链接。
例如,以链接其他博文post为例,见之前的一篇博客文章谈到的“双服务器建站需求”。
其背后具体代码如下:
# note your can refer the section ID as your have set
例如,以链接其他博文post为例,见之前的一篇博客文章谈到的["双服务器建站需求"](/2020/10/05/hugo-big-update/#double-site)。
当然,博文内部章节或任意内容的自我链接(需要事先设定为{#a-ref-id}
)也是一种常见的引用方式。此时对同一篇博文post内部ref ID的引用,则可以直接采用[link-text](#a-ref-id)
的形式。
例如,请查看前面的content文件系统树形图。
其背后代码为:
# 需要事先设定好引用指针
# you should specify the reference ID before link it
例如,请查看前面的content文件系统[树形图](#dir-content)。
- Rmd内部链接2:对于非hugo标准模块内容的链接。与上述对应,非hugo标准模块内容一般指用户根据hugo空白模板
widget = "blank"
设定的页面。主站的课程系列(包括course-econometrics、course-advanced-statistics等)的内容(各种课程的文件结构可以参看前面提及的content文件系统树形图)就是基于hugo空白模板widget = "blank"
生成的。具体模板参数可以逐层追溯看到,例如先查看netlify/content/course-econometrics/_index.md
的yaml参数区域,然后进一步追溯其继承至netlify/config/_default/menus.toml
的toml参数区域,最后发现它的模板是netlify/content/home/teaching.md
ymal参数区域指定的widget = "blank"
。
此时,如果要链接在外部拷贝的一个特定静态网页文件,其存放路径netlify/static/course-econometrics/reading/cht01-history.html
(具体可参看前面提到的netlify static文件夹系统树形图)。此时路径指向应精准和明确。
例如,请点击查看《计量经济学》课程扩展阅读资料计量经济学的前世今生。
其背后的具体代码为:
# 路径指向应精准和明确,包含了后缀.html
# specify the file with full path
例如,请点击查看《计量经济学》课程扩展阅读资料[计量经济学的前世今生](/course-econometrics/reading/cht01-history.html)。
2.利用hugo的shortcode特性(未测试)。参看yihui提到的Shortcode方法。正文行内引用方式:
[第一章](r blogdown::shortcodex("relref", "chapter01-introduction.html"))
需要注意的是不能直接引用chapter01-introduction.Rmd
;但是可以直接引用chapter01-introduction.md
或者chapter01-introduction.html
。此外还要注意引用路径是相对的。例如:
[博客文章提到](r blogdown::shortcodex("relref", "../post/2019-02-24-xaringan-for-course-slide.html"))
3.2 netlify指定Rmd输出格式
用.Rmd生成的文档能不能有其他的输出格式呢?还能做些别的么?
# add this in yaml area
output:
blogdown::html_page:
toc: true
number_sections: true
4 对接失败与报错
4.1 include_url()服务器拒绝访问
报错内容:使用knitr::include_url()
函数后,hugo或blogdown渲染网站,都无法显示对本地静态("static/course/slide.html"
)文件Xaringan slide
。
具体报错内容如下
本地预览下,
include_url('/path/to/file.html')
则显示报错localhost 拒绝了我们的连接请求。
。markdown语法[](/path/to/file.html)
则只显示为纯文本。netlify built
在线建站后,include_url('/path/to/file.html')
则显示服务器.netlify.app 拒绝了我们的连接请求。
。但是markdown语法[](/path/to/file.html)
则显示正常。chrome开发工具显示:
<div id="main-frame-error class="interstitial-wrapper" </div>
。
1.use markdown syntax(link Ok)。课件(Xaringan slide)第01章-绪论.html 。
[第01章-绪论.html](/course-statistics/03-slide-class/03-visualization.html)
2.try local graphic(graph OK)。
knitr::include_graphics("/pic/facet-multiple-geom.png", error = FALSE)
3.test the include_url()
(error):
# out.extra='style="border: none;"', out.width='80%'
knitr::include_url("/course-statistics/03-slide-class/03-visualization.html")
4.try iframe html tag(error):
<iframe seamless src="/course-statistics/03-slide-class/03-visualization.html" width="100%" height="500"></iframe>
5.test xaringanExtra::embed_xaringan()
(error):
xaringanExtra::embed_xaringan(
url = "/course-statistics/03-slide-class/03-visualization.html",
ratio = "16:9"
)
排除可能的问题:
win10 系统防火墙设置
chrome隐私设置
knitr::include_url()
函数是否正确,包括chunk option
设定。url地址是否正确。外部绝对url地址显示正确。本地相对地址则报错。但使用
knitr::include_graphic()
加载本地图片则能正确显示图片。排除url地址误写。使用
iframe tag
方法,仍旧报错。使用
xaringanExtra::embed_xaringan()
,仍旧报错。
怀疑的可能原因:
根据hugo团队的观点,它们会原生支持
rveal.js
,但不是remark.js
。(见队长讨论)win10操作系统静默升级,改变了hugo的链接访问权限??
Netlify
的建站规则发生了变化?knitr
包的bug(iframe id失效)?