3

学用Eleventy(一):路由

 1 year ago
source link: https://nakeman.cn/blog/learning-eleventy-1/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

学用Eleventy(一):路由

Eleventy是什么

Eleventy(下称11ty)是node平台最时髦的 静态网站生成器(Web site generator)之一。如果你用过 ruby平台的Jeklly ,或者 hexo 创建过静态博客,一定明白 11ty 是什么。如果没有(只开发过数据库驱动的动态网站),了解一下 什么叫 静态型网站 就明白了。

静态型网站

现代网站有很多种形态,最常见类型有电商,社交,论坛和工具(像搜索引擎),但不能忘记还有原初的传统的网站形态。这种原始网站类型的功能是较简单的,页面是静态不怎么变化的。这种传统网站类型其实依然有很大的市场需求,例如用于企业营销,个人博客,和公司产品宣传册等。

静态网站功能可大可小,但无论功能如何,一般不手工制作,我们需要工具。开发网站我们一般使用框架,例如 ASP.NET, PHP Laravel,Node express等。对于静态网站来说,这些都是牛刀。Jeklly,11ty 等就是设计用来开发静态网站的 网站生成器

网站生成器

了解了静态网站的本质和需求,也要认识一下网站生成的原理。静态网站可大可小,共同的特点都由一系列静态页面构成,这些页面1)可以构成会话,或业务关系,2)页面有结构,3)也会有一些共通的数据,所以在制作时 可通过 数据 集中 生成这些页面,所以 叫生成器。

网站生成器,和我们一般开发者认知的 应用框架 其实 只是 工具的功能大小,和针对项目类型(主要是架构类型)不同而已,例如网生只适用于开发静态渲染的网站。网生和框架 本质是类似的,都是用来开发 某种架构的网站 的大型开发工具 。

网站是一种基于http的分布式系统,大型的网站的架构是很复杂的,开发它也就变得复杂。静态型网站的构架是最简单的,但它只是特例,类型不全面。网站架构主要由路由,页面和渲染方式组成,静态网站几乎感觉不到路由器的存在,页面渲染也只是直接响应用户的http 请求。网站架构的话题比较大,有机会介绍全能应用框架(例如next remix)再说。

生成器与应用框架

由上可得,静态型网站除了页面结构相对稳定,功能较单一,它的架构也是有自己的特点,11ty 就是针对开发此类架构特点的网站的便利工具。

11ty 由于针对于网站类型属于小型,小规模的,所以11ty被定义为 网站生成器,而不是常见的应用框架。然,这两者界限不是特别清楚。有一种看法是,应用框架是集成保证网站商业品质 的一系列工具和资源,包括:

  • 第一,提高开发效率,网站性能和开发者的开发体验的工具
  • 第二,有丰富成熟的社区和生态

从这个界定上看,11ty 的确不像 gatsby , next那的全面。11ty 主打特点 就是灵活,包前端框架独立,模板引擎独立,你可选择你喜欢的前端库,模板引擎 开发和扩展,11ty社区主背靠node社区。

11ty 继承了流行生成器的所有优点和便利性(几乎复制了Jeklly的特性),并有所创新,具体如何便利,我们以分析一个 使用11ty开发的博客为例。

本教程以系列完成,并且不从头介始如何使用11ty,主要以介绍如何 使用11ty 工具特性 开发 网站常规架构块(building block),包括 路由,渲染和页面交互等。故,假设读者 至少有过 web开发经验,不限于node 平台的经验。

路由是什么

在开始分析博客源码前,先介绍网站架构最重的建构块——路由。

当我们拿一个新项目需求,或者项目源码要阅读,应该从哪里着手,着手设计和分析呢?很多人会不自觉的从具体的交互功能,和具体模块源码分析开始,因为那很直观。然而,更有效的方式 其实是从路由着手,只是路由比较抽象的,对生手不友好。

网站程序作一种GUI应用 是一定有路由的,因为路由是指 页面的路由——页面的切换,有用的应用很少只有一个页面,大型应用路由很复杂。

路由程序的构成

不是所有网站类型 有明显 路由模块,它们一定有页面,但不一定很具体有一个路由模块,像React Router这种库,或者express有一个router对象。

想像一下一个网站,有一个 ==产品列表==(product-list)页,点某个产品可看 ==产品的详细==(product?id=123),这个产品详细页(product)有一个返回主面的链接。

product-page-routing

从这个最简单的例子可看 路由程序 的组成。

网站路由功能主要由一个 路由模块实现,且有相关的一些数据结构,和概念组成。

  • ==路由项==就是被加载的页面,例如上面的产品列表页(product-list)和产品明细页(product?id=123);页面的URL地址就是==路由项==。一些集中式路由,还会有由多个表项组成 ==路由表== 数据结构;
  • ==路由器==负责监测用户的路由请求(http页面请求),查询路由表,再执行页面加载

简单的网站,例如静态型的,路由任务比较简单——文件名就是路由项,路由模块集成在http server上去了;但对复杂的网站,可能需更强更复杂的路由功能,例如1)路由有参数需要处理,2)对路由请求的访问授权,3)将路由功能移到前端等功能等等,这需要一个独立的路由模块负责。

网站常见路由功能主要有以下一些:

  1. 静态路由:一般是简单的静态页面
  2. 逻辑路由:为页面定义一个新名(路由表项),如博客文章有一个富语义的url地址
  3. 动态路由或函数路由:页面加载需参数,例如产品明细页需要一个产品id
  4. 嵌套路由:这个比较复杂,将页面的布局信息提取出来,高级框架才有这个功能,像remix,next也有了
  5. 自由路由:一般页面只有交互功能,带导航跳转(通过 link交互)的叫自由路由
  6. 编程路由:像redirect 那通过代码 实现路由转向
  7. 特殊路由:像 页面访问授权 那样 给路由处理添加特殊业务逻辑

以上是网站 页面路由 小理论,并不算全面(有待完善)。下面开始分析项目代码。

我们准备以分析11ty官方提供的博客模板(eleventy-base-blog)为例子,不过开始之前先介绍一下常规博客网站的功能。

博客属于内容管理(CMS)的一种,它可以做成动态的,因为博主要发布新文章和编辑页面内容,例如 wordpress 就是专业制作动态博客。但是如果博客更新比较慢(常常都是),做成静态也是比较合理的。

博客的网站功能可大可小的,如果用过wordpress就知道 有大量插件可用就理解了,不过博客核心功能主要是围绕 博文(post)的展示和整理,例如 打tag和 分类归档等。

按照功能丰富程度分类,博客可分为

  1. 简单博客:无评论和搜索功能,静态生成
  2. 标准博客:如以jamstack 架构实现 评论和搜索,本地数据生成
  3. 传统博客:集成中后台界面和数据库

我将要分析的 eleventy-base-blog,它属于第一种,并且更简单一点,后面会介绍。

博客页面组成模式

任何站点都 是由一集 页面组成的,这些页面的功能 有很多种类,和复杂度,博客类站点 有一定的 页面组成模式,和固定的业务数据,例如:blog post tag page category 等,博客网站常见有以下的模块和功能:

  • index 首页:时间倒序的 post 分页列表
  • category:post 分页列表,按大类过滤
  • tag : post 分页列表,按标签过滤
  • archie 归档:post 分级列表,按日期 (年月)分组
  • post :post 明细页
  • page :page 明细页, page是特殊的post ,page列表通常以 导航菜单项 显示在 公共导航栏上
  • search:post 分页列表,按关键词过滤

eleventy-base-blog

此博客模板只实现了 index tag archie post page 五个模块,具体路由表如下:

/
/tags
/tags/$tag-name
/posts
/posts/$post-name
/about

此路由表中,有1)静态路由 和 2)动态路由,还有一个,3)逻辑路由(从源码可以看到 模块文件名和路由名不同)。接着来看看11ty的 网站路由开发技术 如何实现这个路由 的。

11ty的路由技术

这里重点提醒,页面路由和渲染是相互协作的两个任务,但它们的职责有时候比较模糊,区别主要在,路由的任务是围绕着路由表的;渲染的任务围绕着 页面结构和状态数据的。

好,我们先看eleventy-base-blog项目源码组成概况(精简路由相关的内容):

[radar@fedora eleventy-base-blog]$ tree --gitignore
.
├── _site
├── 404.md
├── about
│   └── index.md
├── archive.njk
├── _includes
├── index.njk
├── posts
│   ├── firstpost.md
│   ├── posts.json
│   ├── secondpost.md
├── tags-list.njk
└── tags.njk

1 文件目录即是路由表

11ty支持File-System Routing,这是现在很多新进的框架(像gatsby next remix)都支持的路由技术 。这种路由表定义方式的确对开发者很友好,非常的直观。

11ty路由技术主要有以下几条规则:

第一,所有 页面模板 (包括有目录的)和路由项一对一,11ty支持多种模板引擎格式(这里有njk 和 数据内容模板 md);

第二,带下划线的(_)是中间处理数据,和不相关数据(如 _site),例如位于 _include目录里的布局layout模板,不会生成独立的页面;

第三,默认根目录就是路由目录,当然 为了清晰也可放进一个src目录,编译时再指定;

2 静态路由

文件路经就是 route值。静态是指页面文件 ==在路由处理时== 不作任何处理,不是页面内容静态不变,页面内容是 渲染的任务。base-blog有以下静态路由:

1 页面 模块文件 路由名
2 首页 /index.njk /
3 关于 /about/index.md /about
4 404 /404.md /404

3 逻辑路由

有时候我们想隐藏实现细节,让用户看到一个友好的路由名,例如给博文一个别名。这是最简单的 ==路由处理== 任务了。

1 页面 模块文件 路由名
2 存档 /archive.njk /posts
3 所有tags /tags-list.njk /tags

要改写页面模板的route值,要通过 模板 front matter 的 permalink 属性。例如 /archive.njk:

---
layout: layouts/home.njk
permalink: /posts/
---

4 动态路由

路由本身就是一种以页面为单元分割程序功能的技术,所以==路由和页面==常常可以概念互换。而应用程序常常有一组相似的页面,可抽象出一通用页面模板,再用特定的数据派生多个具体的页面,有点像函数参数派生具体函数,这就是动态路由,其实也可叫==函数路由==。函数路由不负页面动态内容(那是渲染的职责),只负责 ==路由处理==中的参数处理——给页面模板传参数,再具体(由渲染器)渲染出不同的页面。

base-blog 有两个函数路由:

1 页面 模块文件 路由名
2 某篇文章 /posts/[post-slug].md /posts/[post-slug]
3 某个tag的所有文章 /tags /tags/[tag]

第一个函数路由(2 某篇文章),是一种二级结构(列表明细)的页面分割,有点像菜单,点击条目(route)将内容在新页面上展开;

第二个(3 某个tag的所有文章 ),是一种搜索结果集的页面分割,tag是搜索关键字;

搜索结果集常要分页,有分页的函数路由页面(base-blog没有实现,postslist.njk这个模板没有实现分页)会有多个关键字(其中一个是页码);

一项工具的设计 会想方设法针对最复杂的任务 作出优化,多个参数的函数路由是复杂的页面路由任务,11ty 的路由技术 有data cascadecollectionpagination 等函数路由优化技术。其中,数据源层叠 data cascade 是 11ty技巧的重心,渲染技术大量基于这个工具,路由也有。

参考此篇和文档。

5 编程路由和特殊路由

此两类路由功能需要用户参与,例如用户登录,属于运行时路由(相对于上面几种属于构建时路由),11ty 不支持,以及base-blog也 没有这个功能需求。

路由、页面 和渲染

网站 是由一集交互功能组成的,当交互功能增多并且变得丰富后,需要一个独立的路由程序 将交互功能分组,并且提供导航跳转,这是页面路由器最基本逻辑。这里我们必须注意将 路由、页面渲染,和交互区分开来。

掌握了网站的路由(功能种类,和路由表),对网站的功能就能有宏观的把握,接下来就可以纵向的展开,开发 每个路由项(页面)的具体功能。它就是 渲染,和交互。


  1. 不同的网站有不同的具体路由器实例,使用了框架或生成器,这个路由器实例是开发者在框架路由API之定制出来的。所谓路由技术是指,框架或生成器提供的路由定制API。例如文件系统式路由表,路由器是从文件系统中读出路由项信息,再执行路由操作。开发者在开发路由器实例需要做什么,取决于路由需求,和框架提供的API。

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK