共计 3669 个字符,预计需要花费 10 分钟才能阅读完成。
应用 JBake(“mvn generate-resources”)构建您的动态网站或博客。应用布局、宏和数据文件。
咱们迁徙了整个 www.optaplanner.org 网站(1399 个文件)以应用 Java 和 Maven,而不是 Ruby 和 Rake 进行构建。从外表上看,什么都没有扭转。但在源代码中,对于咱们的 Java 开发人员团队来说,它是一个游戏规则扭转者。
咱们的 Java 团队当初能够轻松地为网站做出奉献。在实现迁徙后的几个小时内,咱们的一位开发人员曾经提交了一份不违心用十英尺长的杆子接触以前的源代码的提交。
咱们建设了这个网站。
咱们在 Java 和 Maven 上构建了这个站点。
咱们建设了这个网站。
咱们在 JBake 和 Freemarker 上建设了这个网站。
为什么应用动态网站生成器?
动态网站生成器将模板和内容文件转换为动态 HTML/JS/CSS 网站。对于咱们这样的我的项目,这比内容管理系统 (CMS) 有很多劣势:
托管很便宜。GitHub 页面甚至收费托管动态网站。
源文件进入 Git 进行备份和历史记录。
源文件为纯文本格式:
更改以拉取申请的模式呈现,以进行适当的审查和 CI 验证。
源代码在咱们的 IDE 中是凋谢的,这激励将它们与代码一起重构。这会缩小古老的内容。
多年来,Awestruct 始终为咱们服务。但因为不足流动,是时候降级了。
为什么是 JBake?
因为咱们是 Java 程序员。
有几个很好的动态网站生成器,比方 Jekyll (Ruby) 和 Hugo (Go)。咱们抉择 JBake (Java),因为:
咱们的网站当初应用 Maven (mvn generate-resources)构建。
无需装置任何货色。甚至不是 JBake。每个人都应用雷同版本的 JBake 构建,如 pom.xml.
而且速度很快:即便 mvn clean 在我的机器上构建 150 个输入页面也只须要 20 秒。
. 上面全是 Java。
编写条件表达式很简略。API (String.substring(), …) 很相熟。日期格局 (d MMMM yyyy) 和正则表达式的行为合乎预期。
最重要的是,谬误音讯很分明。
8 年来,我用 Awestruct (Ruby) 编写了这个网站。但我素来没有花工夫好好学习 Ruby,所以每次扭转都须要数小时的重复试验。我不能只是浏览谬误音讯并修复它。这不是鲁比的错。那是因为我素来没有花几天工夫来真正学习 Ruby。应用 JBake,我能够在很短的工夫内修复谬误:不再须要重复试验。
什么是 JBake?
JBake 是一个动态网站生成器,有很多选项:
应用 Maven 或 Gradle 构建。
咱们抉择 Maven,因为咱们所有的 repos 都是用 Maven 构建的(只管两个 OptaPlanner Quickstarts 也用 Gradle 构建,因为 OptaPlanner 也反对 Gradle)。
用 Asciidoc、Markdown 或 HTML 编写内容。
咱们抉择 Asciidoc 是因为它比 Markdown 更丰盛、更牢靠。此外,咱们所有的文档都是用 Asciidoc 编写的。
应用 Freemarker、Thymeleaf 或 Groovy 创立模板。
咱们抉择 Freemarker 是因为它是一个弱小的、通过实战考验的模板引擎。
技巧和诀窍
这些是构建高级动态网站的常见工作以及如何在 JBake-Freemarker 中实现每个工作。您甚至能够将这些 JBake 设计模式称为:
应用宏渲染共享内容
咱们简直所有的模板都显示雷同的最新版本面板:
最新公布
Freemarker 模板非常适合防止反复本人 (DRY):
templates/macros.ftl 应用输入 HTML 的宏创立:
<#macro latestReleases>
<div class="panel panel-default">
<div class="panel-heading">Latest release</div>
...
</div>
</#macro>
而后在 *.ftl 模板中应用它:
<#import "macros.ftl" as macros>
...
<div class="row">
<div class="col-md-9">
...
</div>
<div class="col-md-3">
<@macros.latestReleases/>
</div>
</div>
应用数据文件增加视频、事件或其余易失性数据
某些数据更改过于频繁,无奈在内容或模板文件中进行保护:
一个数据文件,例如一个简略的 *.yml 文件,能够很好地保留这样的易失性数据:
创立 data/videos.yml:
- youtubeId: blK7gxqu2B0
title: "Unit testing constraints"
...
- youtubeId: gIaHtATz6n8
title: "Maintenance scheduling"
...
- youtubeId: LTkoaBk-P6U
title: "Vaccination appointment scheduling"
...
而后在 ftl 模板中应用它:
<#assign videos = data.get('videos.yml').data>
<div class="panel panel-default">
<div class="panel-heading">Latest videos</div>
<div class="panel-body">
<ul>
<#list videos[0..6] as video>
<li>
<a href="https://youtu.be/${video.youtubeId}">${video.title}</a>
</li>
</#list>
</ul>
</div>
</div>
布局继承
所有 HTML 页面通常共享雷同的 HTML 头(元数据)、页眉(导航)和页脚。这些非常适合 base.ftl 布局,由所有其余模板扩大:
只管大多数内容应用 normalBase.ftl,但 useCaseBase.ftl 所有用例页面都有独自的模板,例如车辆路线问题 (VRP)、保护打算和轮班排班。
应用带有 的宏 <\#nested> 来构建布局继承:
创立 templates/base.ftl:
<#macro layout>
<html>
<head>
...
</head>
<body>
<div>
... <#-- header -->
</div>
<#nested>
<div>
... <#-- footer -->
</div>
</body>
</html>
</#macro>
扩大它 templates/useCaseBase.ftl 并引入自定义属性 related_tag:
<#import "base.ftl" as parent>
<@layout>${content.body}</@layout>
<#macro layout>
<@parent.layout>
<h1>${content.title}</h1>
<#nested>
<h2>Related videos</h2>
<#assign videos = data.get('videos.yml').data>
<#assign relatedVideos = videos?filter(video -> video.tags.contains(content.related_tag))>
<ul>
<#list relatedVideos as video>
<li><a href="https://youtu.be/${video.youtubeId}">${video.title}</a></li>
</#list>
</ul>
</@parent.layout>
</#macro>
创立 content/vehicleRoutingProblem.adoc 应用该模板并设置该 related_tag 属性的用例页面:
= Vehicle Routing Problem
:jbake-type: useCaseBase
:jbake-related_tag: vehicle routing
The Vehicle Routing Problem (VRP) optimizes the routes of delivery trucks,
cargo lorries, public transportation (buses, taxi's and airplanes)
or technicians on the road, by improving the order of the visits.
This routing optimization heavily reduces driving time and fuel consumption compared to manual planning:
...
开始
本人试试吧。要构建 www.optaplanner.org 网站,请运行以下命令:
$ git clone https://github.com/kiegroup/o…
…
$ cd optaplanner-website
$ mvn clean generate-resources
…
$ firefox target/website/index.html
或者看看源代码。