Farseerfc的小窝 - material//farseerfc.me/zhs/2015-01-25T22:45:00+09:00重新设计了 Pelican 的主题与插件2015-01-25T22:45:00+09:002015-01-25T22:45:00+09:00farseerfctag:farseerfc.me,2015-01-25:/zhs/redesign-pelican-theme.html
<!-- PELICAN_BEGIN_SUMMARY -->
<div class="label label-warning">
<strong>2015年2月14日更新</strong></div>
<!-- PELICAN_END_SUMMARY -->
<div class="section" id="id2">
<h2><a class="toc-backref" href="#id38">前言: 新天新地,将一切都更新了 <a class="footnote-reference" href="#id37" id="id1">[1]</a></a></h2>
<!-- PELICAN_BEGIN_SUMMARY -->
<p>不知不觉间放任这边长草很久了,从上次
<a class="reference external" href="//farseerfc.me/zhs/try-pelican.html">折腾主题</a> 到现在都快三年了,
而从上次 <a class="reference external" href="//farseerfc.me/zhs/marry-me.html">写了篇告白信</a> 到现在也有快两年了。
这期间曾经把主题配色从 <a class="reference external" href="http://getbootstrap.com/2.3.2/">Bootstrap 2</a> 默认的
白底黑字改成了让眼睛更舒适的黑底白字,也不过是用 drop-in 的配色方案而已,没有本质上的改进。</p>
<p>洞中一日世上千载,两年里 Bootstrap 已经升上 <a class="reference external" href="http://getbootstrap.com/">v3.3</a> ,
而 Pelican 则已经升到 <a class="reference external" href="https://github.com/getpelican/pelican/releases/tag/3.5.0">3.5</a> 了。
早就眼馋 Bootstrap 和 Pelican 中的诸多新功能新设计,不过无奈于时间有限只能饱饱眼福。</p>
<p>近日想写的东西越积越多,终于下定决心花了前前后后 <strong>两个月</strong> 的时间重新设计了一遍
Pelican 的主题,配合一些我觉得有用的插件。于是本博客就变成你们现在看到的样子了。
(以及本篇博文也用了两个月的时间写完,其间还发了几篇别的短文,算是恢复写博客的尝试吧 …</p></div>
<!-- PELICAN_BEGIN_SUMMARY -->
<div class="label label-warning">
<strong>2015年2月14日更新</strong></div>
<!-- PELICAN_END_SUMMARY -->
<div class="section" id="id2">
<h2><a class="toc-backref" href="#id38">前言: 新天新地,将一切都更新了 <a class="footnote-reference" href="#id37" id="id1">[1]</a></a></h2>
<!-- PELICAN_BEGIN_SUMMARY -->
<p>不知不觉间放任这边长草很久了,从上次
<a class="reference external" href="//farseerfc.me/zhs/try-pelican.html">折腾主题</a> 到现在都快三年了,
而从上次 <a class="reference external" href="//farseerfc.me/zhs/marry-me.html">写了篇告白信</a> 到现在也有快两年了。
这期间曾经把主题配色从 <a class="reference external" href="http://getbootstrap.com/2.3.2/">Bootstrap 2</a> 默认的
白底黑字改成了让眼睛更舒适的黑底白字,也不过是用 drop-in 的配色方案而已,没有本质上的改进。</p>
<p>洞中一日世上千载,两年里 Bootstrap 已经升上 <a class="reference external" href="http://getbootstrap.com/">v3.3</a> ,
而 Pelican 则已经升到 <a class="reference external" href="https://github.com/getpelican/pelican/releases/tag/3.5.0">3.5</a> 了。
早就眼馋 Bootstrap 和 Pelican 中的诸多新功能新设计,不过无奈于时间有限只能饱饱眼福。</p>
<p>近日想写的东西越积越多,终于下定决心花了前前后后 <strong>两个月</strong> 的时间重新设计了一遍
Pelican 的主题,配合一些我觉得有用的插件。于是本博客就变成你们现在看到的样子了。
(以及本篇博文也用了两个月的时间写完,其间还发了几篇别的短文,算是恢复写博客的尝试吧。)</p>
<!-- PELICAN_END_SUMMARY -->
<div class="panel panel-default">
<div class="panel-heading">
在迈阿密参加 <a class="reference external" href="http://icsr2015.ipd.kit.edu/">ICSR 2015</a> 的时候
拍到的街边一家叫 Pelican 的旅馆</div>
<div class="panel-body">
<img alt="Pelican Hotel" class="img-responsive" src="//farseerfc.me/zhs/images/pelican.jpg"/>
</div>
</div>
<div class="section" id="bootstrap-3">
<h3><a class="toc-backref" href="#id39">Bootstrap 3 的新设计</a></h3>
<ul class="simple">
<li>全新的 <ruby><rb>优先移动设备</rb><rp>(</rp><rt>mobile-first</rt><rp>)</rp></ruby> <ruby><rb>响应式</rb><rp>(</rp><rt>responsive</rt><rp>)</rp></ruby> 设计。
原本Bootstrap 2虽然有响应式设计,
不过诸多细节不能符合我的需求,最终还是得手工 hack <code class="code">
@media</code>
查询去微调。
现在的 <ruby><rb>优先移动设备</rb><rp>(</rp><rt>mobile-first</rt><rp>)</rp></ruby> <ruby><rb>响应式</rb><rp>(</rp><rt>responsive</rt><rp>)</rp></ruby>
<ruby><rb>栅格系统</rb><rp>(</rp><rt>grid system</rt><rp>)</rp></ruby> 则相对显得科学很多了,也终于能在手持
设备上看起来舒服一些。诸位可以尝试改变窗口宽度,或者在不同的手持设备上打开这个
blog ,体验一下这个页面在不同显示器大小中的效果。如果仍有问题欢迎
<a class="reference external" href="https://github.com/farseerfc/pelican-bootstrap3/issues">发 Issue 给我</a> 。</li>
<li>科学的 <ruby><rb>导航栏</rb><rp>(</rp><rt>Navbar</rt><rp>)</rp></ruby> 。
比 Bootstrap 2 那个科学很多了。无论是 <ruby><rb>保持</rb><rp>(</rp><rt>sticky</rt><rp>)</rp></ruby> 在上端还是跟着浮动,
或者像这边这样 <a class="reference external" href="http://www.virtuosoft.eu/code/bootstrap-autohidingnavbar/">自动隐藏</a> 都很简单。</li>
</ul>
<p>更多细节参考 <a class="reference external" href="http://getbootstrap.com/">Bootstrap 3 主页</a> 。</p>
</div>
<div class="section" id="pelican-3-5">
<h3><a class="toc-backref" href="#id40">Pelican 3.5 的新功能</a></h3>
<ul class="simple">
<li>Python 2 和 Python 3 统一代码:
再没有恼人的 unicode 相关的问题了。这对 blog 系统来说相当重要啊。
而且还能方便切换 pypy 等不同的解释器。</li>
<li>全新的插件系统:非常多功能强大的 <a class="reference external" href="https://github.com/getpelican/pelican-plugins">插件</a> 等着你。</li>
<li>增强了导入系统:嗯总算可以导入我的中文的 wordpress 博客了。(虽然那边长草更久了……)</li>
<li><a class="reference external" href="http://pelican.readthedocs.org/en/latest/content.html#linking-to-internal-content">站内链接</a>
:不用 <ruby><rb>硬编码</rb><rp>(</rp><rt>hard code</rt><rp>)</rp></ruby> 目标页面的链接了,可以直接写源文件的位置然后让 pelican
处理,这样能简化各种 <ruby><rb>插件</rb><rp>(</rp><rt>plugin</rt><rp>)</rp></ruby> 和 <ruby><rb>主题</rb><rp>(</rp><rt>theme</rt><rp>)</rp></ruby> 的实现。</li>
</ul>
<p>更多细节参考 <a class="reference external" href="http://pelican.readthedocs.org/en/latest/">Pelican 文档</a> 。</p>
</div>
<div class="section" id="id11">
<h3><a class="toc-backref" href="#id41">新的文件夹布局</a></h3>
<div class="panel panel-default">
<div class="panel-heading">
Pelican 的新文件夹布局</div>
<div class="panel-body">
<pre><span class="code-line"></span>
<span class="code-line"><span style="color:blue;font-weight:bold;">.</span></span>
<span class="code-line">├── <span style="color:blue;font-weight:bold;">cache</span> 生成页面的 pickle 缓存</span>
<span class="code-line">├── <span style="color:blue;font-weight:bold;">content</span> 读取的全部内容</span>
<span class="code-line">│ ├── <span style="color:blue;font-weight:bold;"><categories></span> 按分类存放的文章</span>
<span class="code-line">│ ├── <span style="color:blue;font-weight:bold;">pages</span> 像 About 这样的固定页面</span>
<span class="code-line">│ └── <span style="color:blue;font-weight:bold;">static</span> 文章内用到的静态内容</span>
<span class="code-line">├── <span style="color:blue;font-weight:bold;">drafts</span> 文章的草稿箱</span>
<span class="code-line">├── <span style="color:green;font-weight:bold;">Makefile</span> 生成用的 makefile</span>
<span class="code-line">├── <span style="color:green;font-weight:bold;">pelicanconf.py</span> 测试时用的快速 Pelican 配置</span>
<span class="code-line">├── <span style="color:green;font-weight:bold;">publishconf.py</span> 部署时用的耗时 Pelican 配置</span>
<span class="code-line">├── <span style="color:teal;font-weight:bold;">output</span> -> <span style="color:blue;font-weight:bold;">../farseerfc.github.io</span></span>
<span class="code-line">├── <span style="color:teal;font-weight:bold;">plugins</span> -> <span style="color:blue;font-weight:bold;">../pelican-plugins</span></span>
<span class="code-line">└── <span style="color:teal;font-weight:bold;">theme</span> -> <span style="color:blue;font-weight:bold;">../pelican-bootstrap3</span></span>
</pre></div>
</div>
<p><a class="reference external" href="https://github.com/farseerfc/farseerfc.github.com">之前的博客</a> 仍然留在
github 上,其中的内容完全搬过来了。开始写老博客的时候 Pelican 版本较早,没有形成好的
文件夹布局,导致生成的文章、使用的模板和撰写的内容全都混在一起,非常难以管理,
于是趁改版之际用了新的文件夹布局方式,并分为 4 个 git repo 分别管理历史。</p>
<p>首先是存放 <a class="reference external" href="https://github.com/farseerfc/farseerfc">总的博客内容的 repo</a> ,
其布局是如图那样的。这样将生成的静态网站和生成网站用的配置啦内容啦分开之后,顿时清晰了很多。</p>
<p>然后这个内容 repo 中的三个符号链接分别指向三个子 repo(没用 <code class="code">
git submodule</code>
管理纯粹是因为偷懒)。 theme 指向
<a class="reference external" href="https://github.com/farseerfc/pelican-bootstrap3">pelican-bootstrap3</a>
,是我修改过的 pelican 主题。
plugins 指向 <a class="reference external" href="https://github.com/farseerfc/pelican-plugins">pelican-plugins</a>
,由于 plugins 的质量有些参差不齐,其中不少 plugin
都按我的需要做了些许修改,一些是功能改进,另一些则是修bug(比如不少plugin只支持 python 2)。
最后 output 指向
<a class="reference external" href="https://github.com/farseerfc/farseerfc.github.io">farseerfc.github.io</a>
也就是发布的静态网站啦。</p>
<p>接下来从 <strong>主题</strong> 和 <strong>插件</strong> 两个方面介绍一下改版的细节。</p>
</div>
</div>
<div class="section" id="material-design-bootstrap-3">
<h2><a class="toc-backref" href="#id42">主题: Material Design 风格的 Bootstrap 3</a></h2>
<p>上篇 <a class="reference external" href="//farseerfc.me/zhs/summarize-material-design-css-framework.html">博文</a>
就总结了我为了这个博客寻找了一堆 CSS 框架,并且最终决定用
<a class="reference external" href="http://fezvrasta.github.io/bootstrap-material-design/">bootstrap-material-design</a>
, <a class="reference external" href="https://github.com/DandyDev/pelican-bootstrap3">DandyDev/pelican-bootstrap3</a>
和 <a class="reference external" href="http://getbootstrap.com/">Bootstrap 3</a> 这三个项目结合的方式实现这个模板的主题。
这三个项目都或多或少经过了我的修改,修改后的项目以 pelican-bootstrap3 为基础放在
<a class="reference external" href="https://github.com/farseerfc/pelican-bootstrap3">这里</a> ,包括 <a class="reference external" href="https://github.com/farseerfc/pelican-bootstrap3/tree/master/static/bootstrap">Bootstrap3 样式</a>
和 <a class="reference external" href="https://github.com/farseerfc/pelican-bootstrap3/tree/master/static/material">Material 样式</a>。</p>
<div class="section" id="id16">
<h3><a class="toc-backref" href="#id43">对 Bootstrap 3 的定制</a></h3>
<p>由于架构完善,修改 Bootstrap 3 感觉非常简单。另一方面我在 Web 前端技术上的技能点也不多,
所以修改的地方非常有限,只能按我自己的需求定制而已。</p>
<div class="section" id="id17">
<h4><a class="toc-backref" href="#id44">响应式设备的大小</a></h4>
<div class="panel panel-default">
<div class="panel-heading">
修改了 Bootstrap 3 响应式设备的大小</div>
<div class="panel-body">
<div class="highlight"><pre><span class="code-line"><span></span><span class="p">@</span><span class="k">screen-xs</span><span class="o">:</span> <span class="nt">320px</span><span class="p">;</span></span>
<span class="code-line"><span class="p">@</span><span class="k">screen-sm</span><span class="o">:</span> <span class="nt">598px</span><span class="p">;</span> <span class="c">/* 768px; */</span></span>
<span class="code-line"><span class="p">@</span><span class="k">screen-md</span><span class="o">:</span> <span class="nt">952px</span><span class="p">;</span> <span class="c">/* 992px; */</span></span>
<span class="code-line"><span class="p">@</span><span class="k">screen-lg</span><span class="o">:</span> <span class="nt">1350px</span><span class="p">;</span> <span class="c">/* 1200px; */</span></span>
<span class="code-line"><span class="p">@</span><span class="k">screen-xl</span><span class="o">:</span> <span class="nt">2030px</span><span class="p">;</span></span>
<span class="code-line"><span class="p">@</span><span class="k">container-sm</span><span class="o">:</span> <span class="nt">582px</span><span class="p">;</span> <span class="c">/* 750px; */</span></span>
<span class="code-line"><span class="p">@</span><span class="k">container-md</span><span class="o">:</span> <span class="nt">930px</span><span class="p">;</span> <span class="c">/* 970px; */</span></span>
<span class="code-line"><span class="p">@</span><span class="k">container-lg</span><span class="o">:</span> <span class="nt">1320px</span><span class="p">;</span> <span class="c">/* 1170px; */</span></span>
<span class="code-line"><span class="p">@</span><span class="k">container-xl</span><span class="o">:</span> <span class="nt">1990px</span><span class="p">;</span></span>
</pre></div>
</div>
</div>
<p>首先把 Bootstrap 3 默认适配的几个 <a class="reference external" href="http://getbootstrap.com/css/#grid">响应式设备的大小</a>
改成了我需要的大小。 <code class="code">
xs</code>
和 <code class="code">
sm</code>
的大小分别按照我的手机屏幕 <strong>竖屏</strong> 和
<strong>横屏</strong> 时候的浏览器页面宽度来算, <code class="code">
md</code>
是想兼容 Nexus 7 横屏 960 的宽度以及
一个常见上网本 1024 的宽度。 <code class="code">
lg</code>
的大小则按照常见的笔记本 1366 宽的屏幕来适配。</p>
<p>这里 Bootstrap 3 支持的设备大小的一个问题是,它最多考虑到 1200 像素宽的显示器,而更宽的
比如 1600、 2048 甚至 2560 像素宽的显示器现在也并不少见,其结果就是页面中左右两侧
有很大的空间被浪费掉了。作为深受这一问题困扰的用户之一,我用
<a class="reference external" href="http://stackoverflow.com/a/25644266">这里介绍的方法</a>
给 bootstrap 增加了一类「 <ruby><rb>比大更大</rb><rp>(</rp><rt>bigger than bigger</rt><rp>)</rp></ruby> 」的
<code class="code">
xl</code>
响应式设备尺寸,宽度设为支持 2048 像素宽的显示器,具体的修改反映在
<a class="reference external" href="https://github.com/farseerfc/pelican-bootstrap3/blob/master/static/bootstrap/variables.less">variables.less</a>
文件里。</p>
</div>
<div class="section" id="id20">
<h4><a class="toc-backref" href="#id45">根据宽度自动分栏和瀑布式布局</a></h4>
<p>接下来目标是让主页的文章列表像 Google+ 主页那样根据显示器宽度自动调整分栏,使得宽度不同的
显示器上每个分栏的宽度接近。想要达到的效果是,根据上面定义的屏幕宽度尺寸:</p>
<table border="0" class="table docutils borderless">
<colgroup>
<col width="26%"/>
<col width="17%"/>
<col width="18%"/>
<col width="39%"/>
</colgroup>
<tbody valign="top">
<tr><td><code class="code">
xs</code>
用单栏 <ruby><rb>流动</rb><rp>(</rp><rt>fluid</rt><rp>)</rp></ruby> 布局</td>
<td colspan="2"><code class="code">
sm</code>
用上方单栏文章列表、下方双栏 <ruby><rb>侧边栏</rb><rp>(</rp><rt>sidebar</rt><rp>)</rp></ruby> 固定布局</td>
<td><code class="code">
md</code>
用单栏文章列表、单栏 侧边栏 固定布局</td>
</tr>
<tr><td><table border="0" class="table first docutils last borderless">
<colgroup>
<col width="100%"/>
</colgroup>
<tbody valign="top">
<tr><td><ruby><rb>导航栏</rb><rp>(</rp><rt>Navbar</rt><rp>)</rp></ruby></td>
</tr>
<tr><td>文章</td>
</tr>
<tr><td>侧边栏</td>
</tr>
<tr><td>底栏</td>
</tr>
</tbody>
</table>
</td>
<td colspan="2"><table border="0" class="table first docutils last borderless">
<colgroup>
<col width="53%"/>
<col width="47%"/>
</colgroup>
<tbody valign="top">
<tr><td colspan="2">导航栏</td>
</tr>
<tr><td colspan="2">文章</td>
</tr>
<tr><td>侧边栏 1</td>
<td>侧边栏 2</td>
</tr>
<tr><td colspan="2"><ruby><rb>底栏</rb><rp>(</rp><rt>footer</rt><rp>)</rp></ruby></td>
</tr>
</tbody>
</table>
</td>
<td><table border="0" class="table first docutils last borderless">
<colgroup>
<col width="53%"/>
<col width="47%"/>
</colgroup>
<tbody valign="top">
<tr><td colspan="2">导航栏</td>
</tr>
<tr><td>文章 1</td>
<td>侧边栏 1</td>
</tr>
<tr><td>文章 2</td>
<td>侧边栏 2</td>
</tr>
<tr><td colspan="2"><ruby><rb>底栏</rb><rp>(</rp><rt>footer</rt><rp>)</rp></ruby></td>
</tr>
</tbody>
</table>
</td>
</tr>
<tr><td colspan="2"><code class="code">
lg</code>
用双栏文章列表、单栏 侧边栏 固定布局</td>
<td colspan="2"><code class="code">
xl</code>
用三栏文章列表、双栏 侧边栏 固定布局</td>
</tr>
<tr><td colspan="2"><table border="0" class="table first docutils last borderless">
<colgroup>
<col width="35%"/>
<col width="35%"/>
<col width="31%"/>
</colgroup>
<tbody valign="top">
<tr><td colspan="3">导航栏</td>
</tr>
<tr><td>文章 1</td>
<td>文章 3</td>
<td>侧边栏 1</td>
</tr>
<tr><td>文章 2</td>
<td>文章 4</td>
<td>侧边栏 2</td>
</tr>
<tr><td colspan="3"><ruby><rb>底栏</rb><rp>(</rp><rt>footer</rt><rp>)</rp></ruby></td>
</tr>
</tbody>
</table>
</td>
<td colspan="2"><table border="0" class="table first docutils last borderless">
<colgroup>
<col width="26%"/>
<col width="26%"/>
<col width="26%"/>
<col width="23%"/>
</colgroup>
<tbody valign="top">
<tr><td colspan="4">导航栏</td>
</tr>
<tr><td>文章 1</td>
<td>文章 3</td>
<td>文章 5</td>
<td>侧边栏 1</td>
</tr>
<tr><td>文章 2</td>
<td>文章 4</td>
<td>文章 6</td>
<td>侧边栏 2</td>
</tr>
<tr><td colspan="4"><ruby><rb>底栏</rb><rp>(</rp><rt>footer</rt><rp>)</rp></ruby></td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
<p>一开始纯粹用 Bootstrap3 的响应式栅格实现这个分栏布局,结果发现效果不太理想,
因为文章列表和侧边栏的高度是变化的,会导致栅格间留下大片空白。后来改用
<a class="reference external" href="http://cssdeck.com/labs/pinterest-like-waterfall-design-purely-css">这里示范的纯CSS瀑布式布局</a>
实现文章和侧边栏的布局,具体的实现代码在
<a class="reference external" href="https://github.com/farseerfc/pelican-bootstrap3/blob/master/static/bootstrap/waterfall.less">waterfall.less</a>
,总算达到了想要的布局了。</p>
</div>
<div class="section" id="id21">
<h4><a class="toc-backref" href="#id46">正文的样式</a></h4>
<p>最最重要的是文章正文的样式。这里我想要达到的效果是,在大屏幕上用更大的字号,让读者
看起来更舒适,同时在小屏幕上用比较小的字号,最终保证基本上「一行」的文字数接近。这个修改
主要针对 <code class="code">
.jumbotron</code>
,
用了 <a class="reference external" href="https://github.com/farseerfc/pelican-bootstrap3/blob/master/static/bootstrap/jumbotron.less">不太科学的方式</a>
代码太长就不贴全了。</p>
</div>
<div class="section" id="id23">
<h4><a class="toc-backref" href="#id47">一些细微的定制</a></h4>
<p>把主题配色改成了现在这样的淡紫色
<code class="code">
@brand-primary: darken(#6B5594, 6.5%);</code>
,配合我的头像风格, 这个修改只需要一行。
接着删掉了 <code class="code">
.btn</code>
的 <code class="code">
white-space: nowrap;</code>
让按钮的文字可以换行,
这也只是一行修改。</p>
<div class="label label-warning">
<strong>2015年1月29日更新</strong></div>
<p>另外我也不太喜欢 Bootstrap 3 默认在手机上的 <ruby><rb>折叠导航栏</rb><rp>(</rp><rt>collapsed navbar</rt><rp>)</rp></ruby> ,
折叠之后的操作不够直观方便而且依赖 javascript 所以有 bug …… 于是我把它关掉了,
具体方式是在 variables.less 把 <code class="code">
@grid-float-breakpoint</code>
和
<code class="code">
@grid-float-breakpoint-max</code>
都设为0就可以了。</p>
</div>
</div>
<div class="section" id="id24">
<h3><a class="toc-backref" href="#id48">对 bootstrap-material-design 的定制</a></h3>
<p>这里定制的地方不多。原样式中一个不太科学的做法是所有 <code class="code">
.btn</code>
都强制加上了阴影
效果,这在已经有阴影的环境里用的话非常碍眼,像是 Win9x 风格的厚重睫毛膏。既然可以单独
给每个样式加阴影,于是就把 <code class="code">
.btn</code>
强制的阴影去掉了,只保留鼠标悬停之后强调的阴影。</p>
<p>其它定制的细节么就是统一配色风格,修补漏洞错误,微调响应式效果而已,这里不细说。</p>
</div>
<div class="section" id="id25">
<h3><a class="toc-backref" href="#id49">将以上两者整合在 pelican-bootstrap3 里</a></h3>
<div class="panel panel-default">
<div class="panel-heading">
Pelican 实现显示源代码按钮</div>
<div class="panel-body">
<p>显示源代码按钮借用了 Pelican 配置中自带的 <code class="code">
OUTPUT_SOURCES</code>
选项将源文件复制到输出文件夹:</p>
<div class="highlight"><pre><span class="code-line"><span></span><span class="n">OUTPUT_SOURCES</span> <span class="o">=</span> <span class="kc">True</span></span>
<span class="code-line"><span class="n">OUTPUT_SOURCES_EXTENSION</span> <span class="o">=</span> <span class="s1">'.rst'</span></span>
</pre></div>
<p>然后在 Makefile 里用 pygmentize 把所有源代码文件着色:</p>
<div class="highlight"><pre><span class="code-line"><span></span>find -iname <span class="s2">"*.rst"</span> <span class="p">|</span> parallel -I@ pygmentize -f html -o @.html @</span>
</pre></div>
<p>最后在按钮按下的时候用 jQuery 载入源代码:</p>
<div class="highlight"><pre><span class="code-line"><span></span><span class="p"><</span><span class="nt">a</span> <span class="na">onclick</span><span class="o">=</span><span class="s">"$.get('{{SITEURL}}/{{article.slug}}.rst.html', function(data){$('#source-code').html(data)});$('#article-content').toggle();$('#source-content').toggle();"</span><span class="p">></span></span>
</pre></div>
<p>虽然难看的 hack 比较多,但是能用!</p>
</div>
</div>
<p>虽说 pelican-bootstrap3 是我 fork 出来的,不过由于我修改的地方实在太多,代码看来基本上
接近重写了一份。好在之前有给 pelican 写 bootstrap 2 主题的经验,这次修改算得上驾轻就熟。
可以对比一下 <a class="reference external" href="http://dandydev.net/">上游作者的博客</a> 和这里的样子体会一下感觉。
具体修改过的地方包括:</p>
<ol class="arabic simple">
<li>套用 bootstrap-material-design 的各个元素样式。</li>
<li>在文章列表模板应用上面提到的 Bootstrap 3 的栅格布局和瀑布式布局。</li>
<li>翻译到多个语言,这里在后面的 i18n-subsite 插件里详述。</li>
<li>套用后面会介绍到的各种插件。</li>
<li>统一侧边栏的样式到一个模板里。</li>
<li>添加 Atom 订阅按钮和 breadcrumb 条。</li>
<li>对正文中出现的插图,添加点击放大的功能,通过 Bootstrap 的 <code class="code">
modal</code>
实现。</li>
<li>上面提到的用 <a class="reference external" href="http://www.virtuosoft.eu/code/bootstrap-autohidingnavbar/">这个bootstrap插件</a>
让导航栏自动隐藏。</li>
<li><strong>显示源代码按钮</strong> ,也就是每篇文章信息栏中的
<button class="btn btn-primary"><i class="fa fa-code"></i></button> 按钮。</li>
</ol>
</div>
</div>
<div class="section" id="pelican-restructuredtext">
<h2><a class="toc-backref" href="#id50">插件: 发挥 Pelican 和 reStructuredText 的优势</a></h2>
<p>先列举一下我目前用到的所有插件:</p>
<div class="highlight"><pre><span class="code-line"><span></span><span class="n">PLUGINS</span> <span class="o">=</span> <span class="p">[</span><span class="s2">"i18n_subsites"</span><span class="p">,</span></span>
<span class="code-line"> <span class="s2">"plantuml"</span><span class="p">,</span></span>
<span class="code-line"> <span class="s2">"youku"</span><span class="p">,</span></span>
<span class="code-line"> <span class="s2">"youtube"</span><span class="p">,</span></span>
<span class="code-line"> <span class="s1">'tipue_search'</span><span class="p">,</span></span>
<span class="code-line"> <span class="s1">'neighbors'</span><span class="p">,</span></span>
<span class="code-line"> <span class="s1">'series'</span><span class="p">,</span></span>
<span class="code-line"> <span class="s1">'bootstrapify'</span><span class="p">,</span></span>
<span class="code-line"> <span class="s1">'twitter_bootstrap_rst_directives'</span><span class="p">,</span></span>
<span class="code-line"> <span class="s2">"render_math"</span><span class="p">,</span></span>
<span class="code-line"> <span class="s1">'extract_toc'</span><span class="p">,</span></span>
<span class="code-line"> <span class="s1">'summary'</span><span class="p">]</span></span>
</pre></div>
<p>嗯其实不算多。接下来逐一介绍一下这些各具特色的插件。</p>
<div class="section" id="i18n-subsites">
<h3><a class="toc-backref" href="#id51">i18n-subsites</a></h3>
<p>这个插件的目的是创建 <ruby><rb>国际化</rb><rp>(</rp><rt>internationalization</rt><rp>)</rp></ruby>
<ruby><rb>子站</rb><rp>(</rp><rt>subsite</rt><rp>)</rp></ruby> 。</p>
<p>之前介绍 Pelican 配置的时候就提到过,
原本的 Pelican 就支持一篇文章用多种语言书写,有 <code class="code">
lang</code>
属性注明这篇文章使用的
语言,以及 <code class="code">
slug</code>
属性注明多语言的翻译之间的关联,换句话说同一篇文章的多个语言
版本应该有相同的 <code class="code">
slug</code>
和不同的 <code class="code">
lang</code>
。然后原本 Pelican 里对多语言的
实现方式是,首先有一个 <strong>主语言</strong> 是模板和大部分文章采用的语言,文章列表中会优先列出
用 <strong>主语言</strong> 撰写的文章,然后从 <strong>主语言</strong> 的文章链接到别的翻译版本。
很多博客系统和CMS对多语言的支持都是这样的,这种处理方式的缺点也显而易见:作为 <strong>主语言</strong>
的语言必须足够通用,才能让进来的人找到合适的翻译版本,所以通常 <strong>主语言</strong> 都是英语。</p>
<p>而这个插件做的事情描述起来很简单:将文章按语言属性分到多个子站,每个子站独立放在各自的文件夹。
比如主站是 <a class="reference external" href="https://farseerfc.github.io/">https://farseerfc.github.io/</a> 的话,那么英语的子站就可以是
<a class="reference external" href="https://farseerfc.github.io/en/">https://farseerfc.github.io/en/</a> 。
然后分别对多个子站生成静态页面。具体的实现方式是对 pelican 的页面生成步骤做了拆分:</p>
<ol class="arabic simple">
<li>pelican 按正常情况读入文章,生成元信息。</li>
<li>i18n-subsites 针对每个语言,覆盖掉 pelican 的一些选项设置比如路径和 URL ,
分别调用 pelican 的页面生成器按模板生成文章。</li>
<li>对共用的静态内容比如模板的 js 和 css 文件,只在主站中生成,子站中的相应链接全部链回主站。</li>
</ol>
<p>虽然描述起来简单,但是这个插件可以说最大化利用了 Pelican 的插件系统,实现细节相对比较
复杂,大概是我用的这些插件里面最复杂的了。不夸张的说 Pelican 3.4 支持的新插件 API 和
站内链接功能基本上就是为了配合这个插件的。至于具体它会覆盖哪些 Pelican 的配置,请参阅它的
<a class="reference external" href="https://github.com/farseerfc/pelican-plugins/blob/master/i18n_subsites/README.rst">README.md文件</a> 。</p>
<p>按内容拆分多语言子站的做法只解决了问题的一半,还留下另一半的问题,也即对模板的翻译。
对这个问题, i18n-subsites 提供了两套方案供选择:</p>
<ol class="arabic simple">
<li>用覆盖配置路径的方式让每个子站套用不同的模板。这配置起来简单,但是对模板维护起来有点困难。</li>
<li>用 jinja2 的 i18n 插件,配合 Python 的 gettext 库实现内容翻译。这个方案
<a class="reference external" href="https://github.com/farseerfc/pelican-plugins/blob/master/i18n_subsites/localizing_using_jinja2.rst">配置起来比较复杂</a> ,但是配置好之后用起来就很方便了。
只是要记得每次修改了模板都要更新翻译,处理 *.po 和 *.mo 文件等等琐碎事宜。</li>
</ol>
<p>这里我用 jinja2 的 i18n 插件的方式实现了模板的翻译,
<a class="reference external" href="https://github.com/farseerfc/pelican-bootstrap3/tree/master/translations">各个语言的翻译在这里</a> ,
然后用 <a class="reference external" href="https://github.com/farseerfc/pelican-bootstrap3/blob/master/SConstruct">这里的 SCons 脚本</a>
根据内容是否变化自动更新 po 和 mo 文件。</p>
<p>配置好这一套方案之后,还要注意在模板和文章中处理好链接。用 Pelican 3.4 之后推荐的
新的文章间链接的写法以及将 <code class="code">
SITEURL</code>
设置为实际 URL 并且关闭 <code class="code">
RELATIVE_URLS</code>
之后,应该就不会出没什么问题了(可能还要考虑使用的模板和插件的兼容性,大部分都是写死了 URL 的问题)。</p>
</div>
<div class="section" id="plantuml">
<h3><a class="toc-backref" href="#id52">plantuml</a></h3>
<div class="panel panel-default">
<div class="panel-heading">
嵌入 PlantUML 的示例</div>
<div class="panel-body">
<img alt="uml diagram" class="uml img-responsive" src="//farseerfc.me/uml/8e4b1ee3.png"/>
</div>
</div>
<p><a class="reference external" href="http://plantuml.sourceforge.net/">PlantUML</a> 是一个Java实现的,
用接近文字描述的语言绘制 UML 图或者 GUI 界面图的工具,非常适合嵌入在
Markdown、 reStructuredText、 AsciiDoc 等这种轻量级标记语言里。
然后么这个 plantuml 插件就是定义了一个新的 reStructuredText
<ruby><rb>指示符</rb><rp>(</rp><rt>directive</rt><rp>)</rp></ruby> <code class="code">
.. uml::</code>
,把嵌入的内容提取出来调用 plantuml 命令处理
成图像然后再插入到文章中。</p>
<p>比如示例里的这个 UML 图就是用这样一段简单的文字描述生成的:</p>
<div class="highlight"><pre><span class="code-line"><span></span><span class="p">..</span> <span class="ow">uml</span><span class="p">::</span></span>
<span class="code-line"></span>
<span class="code-line"> Object <|-- ArrayList</span>
<span class="code-line"></span>
<span class="code-line"> Object : equals()</span>
<span class="code-line"> ArrayList : Object[] elementData</span>
<span class="code-line"> ArrayList : size()</span>
</pre></div>
<p>实际用起来这个插件实现上稍微有点小问题:首先它只支持 python2,所以我把它改写成了 python
2 和 3 都通用的语法;其次它原本输出的文件夹似乎会被 pelican 删掉,所以把它改了个位置;
然后它输出的 URL 也和 i18n-subsites 插件间有不兼容的问题,也顺带修掉了。
<a class="reference external" href="https://github.com/farseerfc/pelican-plugins/tree/master/plantuml">修改之后的代码在这里</a> 。</p>
<div class="label label-warning">
<strong>2015年1月30日更新</strong></div>
<div class="panel panel-default">
<div class="panel-heading">
嵌入 Ditaa 的示例</div>
<div class="panel-body">
<img alt="ditaa diagram" class="ditaa img-responsive" src="//farseerfc.me/uml/973a8424.png"/>
</div>
</div>
<p>plantuml 是绘制UML的,除此之外还有一个类似的工具是绘制一般的 <ruby><rb>流程图</rb><rp>(</rp><rt>diagram</rt><rp>)</rp></ruby>
的,叫 <a class="reference external" href="http://ditaa.sourceforge.net/">ditaa</a> ,和 plantuml 非常像,也比较像
reStructuredText 的表格。
于是我也照猫画虎实现了一个 ditaa 的 <ruby><rb>指示符</rb><rp>(</rp><rt>directive</rt><rp>)</rp></ruby> ,用起来类似这样:</p>
<div class="highlight"><pre><span class="code-line"><span></span><span class="p">..</span> <span class="ow">ditaa</span><span class="p">::</span></span>
<span class="code-line"></span>
<span class="code-line"> +-------------+</span>
<span class="code-line"> <span class="o">|</span> ditaa |-------+</span>
<span class="code-line"> <span class="o">|</span> Diagram | |</span>
<span class="code-line"> +-------------+ | PNG out</span>
<span class="code-line"> ^ |</span>
<span class="code-line"> <span class="o">|</span> ditaa in |</span>
<span class="code-line"> <span class="o">|</span> v</span>
<span class="code-line"> +--------+ +--------+----+ /----------------\</span>
<span class="code-line"> <span class="o">|</span> | --+ Pelican +--> | |</span>
<span class="code-line"> <span class="o">|</span> Text | +-------------+ | Beautiful Blog |</span>
<span class="code-line"> |Document| | !magic! | | |</span>
<span class="code-line"> <span class="o">|</span> {d}| | | | |</span>
<span class="code-line"> +---+----+ +-------------+ \----------------/</span>
<span class="code-line"> : ^</span>
<span class="code-line"> <span class="o">|</span> Lots of work |</span>
<span class="code-line"> +-----------------------------------+</span>
</pre></div>
</div>
<div class="section" id="render-math">
<h3><a class="toc-backref" href="#id53">render-math</a></h3>
<div class="panel panel-default">
<div class="panel-heading">
嵌入公式的示例</div>
<div class="panel-body">
<p>示范行内公式 <span class="math">\(A_\text{c} = (\pi/4) d^2\)</span>.</p>
<p>整行公式</p>
<div class="math">
\begin{equation*}
\alpha{}_t(i) = P(O_1, O_2, \ldots O_t, q_t = S_i \lambda{})
\end{equation*}
</div>
</div>
</div>
<p>这个插件提供在 reStructuredText 中用 LaTeX 语法插入数学公式的能力,定义了
<code class="code">
:math:</code>
<ruby><rb>行内角色</rb><rp>(</rp><rt>role</rt><rp>)</rp></ruby> 和 <code class="code">
.. math::</code>
<ruby><rb>指示符</rb><rp>(</rp><rt>directive</rt><rp>)</rp></ruby> 。
实际工作的渲染库当然是大名鼎鼎的 <a class="reference external" href="http://www.mathjax.org/">MathJax</a> ,这个插件
会用 MathJax 的 CDN 载入,所以也没有额外的依赖文件。(只是不知道是否会被国内墙掉,
如果公式显示不正常请 <strong>务必</strong> 告诉我。)</p>
</div>
<div class="section" id="youtube-youku">
<h3><a class="toc-backref" href="#id54">youtube 和 youku</a></h3>
<p>顾名思义,这两个插件分别实现嵌入 youtube 和 youku 视频。其中 youtube 是原本就有的插件,
youku 是我照猫画虎抄的。
之前写了一篇
<a class="reference external" href="//farseerfc.me/zhs/jumping-kde5-plasma-activities-button.html">KDE5 Plasma 之跳动卖萌的活动按钮</a>
用到了这两个插件。</p>
</div>
<div class="section" id="tipue-search">
<h3><a class="toc-backref" href="#id55">tipue_search</a></h3>
<p><a class="reference external" href="http://www.tipue.com/search/">Tipue search</a> 是一个非常有意思也很强大的搜索工具,
通过 jQuery 实现静态博客的站内搜索功能。实现方式是,它需要你写一个 json 文件,包含
整个网站的 <strong>全部</strong> 文章的标题和文字内容,然后在搜索的时候读入这个 json 做搜索(是不是有点耍赖)。
虽然听起来会有性能问题,但是应用在小型的静态博客上效果意外很不错,比如本站的所有文章内容
放在一起的 json 也只有 300KiB 左右。</p>
<p>这个插件就是自动在 pelican 输出完全部静态网页之后,调用 beautifulsoup4 从所有网页中抽取出
纯文本,产生这个 json 给 Tipue 用。</p>
</div>
<div class="section" id="neighbors-series">
<h3><a class="toc-backref" href="#id56">neighbors 和 series</a></h3>
<p>这两个插件比较类似也都比较简单, neighbors 提供一篇文章的前后文章信息,
在主题模板里可以用来制作 <strong>上一篇</strong> 和 <strong>下一篇</strong> 按钮。
series 提供将多篇文章归类为一个 <strong>系列</strong> 的支持,当然也需要在
主题模板中定义显示「文章系列」的列表。这两个插件的效果都能在本文末尾,评论区上方的部分看到。</p>
</div>
<div class="section" id="bootstrapify-twitter-bootstrap-rst-directives">
<h3><a class="toc-backref" href="#id57">bootstrapify 和 twitter_bootstrap_rst_directives</a></h3>
<p>这两个插件让文章的 <strong>正文</strong> 套用上 Bootstrap 的样式。</p>
<p>bootstrapify 这个插件实现得比较简单,用 beautifulsoup4 在静态网页的结果里面过滤元素,
对 <code class="code">
table</code>
, <code class="code">
img</code>
, <code class="code">
embed</code>
, <code class="code">
iframe</code>
,
<code class="code">
video</code>
, <code class="code">
object</code>
这几个标签套用上
<a class="reference external" href="http://getbootstrap.com/components/#responsive-embed">响应式嵌入对象的类</a>
让他们更美观。</p>
<p>twitter_bootstrap_rst_directives 这个插件则是增加了几个 reStructuredText 的
<ruby><rb>行内角色</rb><rp>(</rp><rt>role</rt><rp>)</rp></ruby> 和 <ruby><rb>指示符</rb><rp>(</rp><rt>directive</rt><rp>)</rp></ruby> 。
它实现的 <ruby><rb>行内角色</rb><rp>(</rp><rt>role</rt><rp>)</rp></ruby> 包括:
用 <code class="code">
:kbd:</code>
实现如 <kbd class="kbd">
Ctrl+C</kbd>
这样的键盘快捷键,
用 <code class="code">
:code:</code>
嵌入代码片段,用 <code class="code">
:glyph:</code>
嵌入字符图标。
它实现的 <ruby><rb>指示符</rb><rp>(</rp><rt>directive</rt><rp>)</rp></ruby> 包括:
<a class="reference external" href="http://getbootstrap.com/components/#labels">labels 行内标签</a> ,
<a class="reference external" href="http://getbootstrap.com/components/#alerts">alerts 提示段落</a> ,
<a class="reference external" href="http://getbootstrap.com/components/#panels">panels 嵌入面板</a> ,
以及还有一个 <a class="reference external" href="http://getbootstrap.com/components/#media">media 混排图标</a> 。</p>
<p>对其中的 <code class="code">
panel</code>
我改写了它在文章正文中的样式,在 <code class="code">
lg</code>
或者 <code class="code">
xl</code>
的屏幕宽度下,分别用 <span class="math">\(\frac{1}{2}\)</span> 和 <span class="math">\(\frac{1}{3}\)</span> 大小的嵌入面板,
简单实现和正文文字的图文混排。</p>
<p>除此以外我还在 twitter_bootstrap_rst_directives 这个插件里套用它的框架实现了两个额外
的 <ruby><rb>行内角色</rb><rp>(</rp><rt>role</rt><rp>)</rp></ruby> , 分别是 <code class="code">
:ruby:</code>
:通过 html5 的 <code class="code">
<ruby></code>
标签实现文字上方的注音(firefox下
<a class="reference external" href="https://bugzilla.mozilla.org/show_bug.cgi?id=33339">不支持</a>
,会使用文字后的括号显示), 以及 <code class="code">
:html:</code>
:在
行内插入 <ruby><rb>裸</rb><rp>(</rp><rt>raw</rt><rp>)</rp></ruby> html 标签(这属于 Markdown 的基本功能,在 reStructuredText
这边由于要考虑多种输出格式于是就比较麻烦了)。这两个 <ruby><rb>行内角色</rb><rp>(</rp><rt>role</rt><rp>)</rp></ruby> 的
<a class="reference external" href="https://github.com/farseerfc/pelican-plugins/blob/master/twitter_bootstrap_rst_directives/bootstrap_rst_directives.py#L140">实现代码在这里</a> 。</p>
<div class="label label-warning">
<strong>2015年2月3日更新</strong></div>
<p>今天又在 twitter_bootstrap_rst_directives 里增加了两个 <ruby><rb>行内角色</rb><rp>(</rp><rt>role</rt><rp>)</rp></ruby> 。
一个是 <code class="code">
:twi:</code>
用来写 twitter 用户的链接,比如 <a class="reference external" href="//twitter.com/farseerfc">@farseerfc</a> ,另一个是
<code class="code">
:irc:</code>
用来指向 freenode 的 channel ,比如 <a class="reference external" href="//webchat.freenode.net/?channels=yssyd3">#yssyd3</a> 。</p>
<div class="label label-warning">
<strong>2015年2月14日更新</strong></div>
<p>今天增加了 <code class="code">
.. friend::</code>
用来写好友链接,以及 <code class="code">
fref</code>
用来引用好友,
比如 <a class="reference external" href="/links.html#lqymgt">LQYMGT</a> 这样。</p>
</div>
<div class="section" id="extract-toc-summary">
<h3><a class="toc-backref" href="#id58">extract_toc 和 summary</a></h3>
<p>最后是这两个有点「名不副实」的插件。</p>
<p>reStructuredText 原本就有自动生成
<ruby><rb>目录</rb><rp>(</rp><rt>toc</rt><rp>)</rp></ruby> 的功能,用起来也非常简单,只需要在想要插入目录的地方写一行
<code class="code">
.. contents::</code>
,剩下的都由 docutils 自动生成了。
只是当然这样生成的目录肯定会插入在文章的正文里,而 extract_toc 这个插件的作用就是简单地
把这个目录抽取出来,让模板能在别的地方放置这个目录。比如我这里就把目录放在了一个
<code class="code">
panel</code>
里。</p>
<p>然后 Pelican 也原本就有从文章中抽取 <ruby><rb>总结</rb><rp>(</rp><rt>summary</rt><rp>)</rp></ruby> 显示在文章列表的功能。
Pelican 原始的实现似乎是按照文字数抽取前半段,不总是适合作为总结。 于是这个 summary
插件的作用其实是允许在正文中以特殊的注释的方式标注哪些部分应该被抽出来作为总结。
summary 这个插件原本的实现只允许抽取一段文字,我又对它的实现做了少许扩充,允许标注多段
文字合并起来作为总结。</p>
<div class="label label-warning">
<strong>2015年1月29日更新</strong></div>
<p>今天在 extract_toc 插件的帮助下,在侧边栏里放了一个 Bootstrap affix 的目录,
它保持在页面的右侧位置不变,方便导航到文章的各个地方。具体实现方法除了 Bootstrap 3 的
<a class="reference external" href="http://getbootstrap.com/javascript/#affix">Affix 文档</a> ,还参考了
<a class="reference external" href="http://tutsme-webdesign.info/bootstrap-3-affix/">这篇更详细的说明</a> 。</p>
</div>
</div>
<div class="section" id="id36">
<h2><a class="toc-backref" href="#id59">结语</a></h2>
<p>这个博客的配置都可以在
<a class="reference external" href="https://github.com/farseerfc/farseerfc/blob/master/pelicanconf.py">github 上找到</a>
,包括用来
<a class="reference external" href="https://github.com/farseerfc/farseerfc/blob/master/Makefile">自动生成整个博客的 Makefile</a>
,由于比较长,这里就不再贴了。</p>
<p>折腾这个主题前后历时两个月,期间学会了不少东西,也算是不错的收获吧。
现在既然基础打好了,接下来就要开始多写博客了。(希望拖延症不会再犯……)</p>
<p>最近发现除了我的博客之外还有一个网站
<a class="reference external" href="http://www.kansaslinuxfest.us/">Kansas Linux Fest</a> fork
了我的主题,不过他们用了我修改的早期版本,还是原本的 Bootstrap 3 和
bootstrap-material-design 样式。自己草草修改的东西被别人用到果然还是有点小激动呢,
以及接下来不能马马虎虎地写 commit 消息了。</p>
<table border="0" class="docutils table footnote" frame="void" id="id37" rules="none">
<colgroup><col class="label"/><col/></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#id1">[1]</a></td><td>赛65:17「看哪!我造新天新地」启21:5「我将一切都更新了。」</td></tr>
</tbody>
</table>
</div>
<script type='text/javascript'>if (!document.getElementById('mathjaxscript_pelican_#%@#$@#')) {
var align = "center",
indent = "0em",
linebreak = "false";
if (false) {
align = (screen.width < 768) ? "left" : align;
indent = (screen.width < 768) ? "0em" : indent;
linebreak = (screen.width < 768) ? 'true' : linebreak;
}
var mathjaxscript = document.createElement('script');
var location_protocol = (false) ? 'https' : document.location.protocol;
if (location_protocol !== 'http' && location_protocol !== 'https') location_protocol = 'https:';
mathjaxscript.id = 'mathjaxscript_pelican_#%@#$@#';
mathjaxscript.type = 'text/javascript';
mathjaxscript.src = location_protocol + '//cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML';
mathjaxscript[(window.opera ? "innerHTML" : "text")] =
"MathJax.Hub.Config({" +
" config: ['MMLorHTML.js']," +
" TeX: { extensions: ['AMSmath.js','AMSsymbols.js','noErrors.js','noUndefined.js'], equationNumbers: { autoNumber: 'AMS' } }," +
" jax: ['input/TeX','input/MathML','output/HTML-CSS']," +
" extensions: ['tex2jax.js','mml2jax.js','MathMenu.js','MathZoom.js']," +
" displayAlign: '"+ align +"'," +
" displayIndent: '"+ indent +"'," +
" showMathMenu: true," +
" messageStyle: 'normal'," +
" tex2jax: { " +
" inlineMath: [ ['\\\\(','\\\\)'] ], " +
" displayMath: [ ['$$','$$'] ]," +
" processEscapes: true," +
" preview: 'TeX'," +
" }, " +
" 'HTML-CSS': { " +
" styles: { '.MathJax_Display, .MathJax .mo, .MathJax .mi, .MathJax .mn': {color: 'inherit ! important'} }," +
" linebreaks: { automatic: "+ linebreak +", width: '90% container' }," +
" }, " +
"}); " +
"if ('default' !== 'default') {" +
"MathJax.Hub.Register.StartupHook('HTML-CSS Jax Ready',function () {" +
"var VARIANT = MathJax.OutputJax['HTML-CSS'].FONTDATA.VARIANT;" +
"VARIANT['normal'].fonts.unshift('MathJax_default');" +
"VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
"VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
"VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
"});" +
"MathJax.Hub.Register.StartupHook('SVG Jax Ready',function () {" +
"var VARIANT = MathJax.OutputJax.SVG.FONTDATA.VARIANT;" +
"VARIANT['normal'].fonts.unshift('MathJax_default');" +
"VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
"VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
"VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
"});" +
"}";
(document.body || document.getElementsByTagName('head')[0]).appendChild(mathjaxscript);
}
</script>总结一下 Material Design 的 CSS 框架2015-01-16T03:27:00+09:002015-01-16T03:27:00+09:00farseerfctag:farseerfc.me,2015-01-16:/zhs/summarize-material-design-css-framework.html<!-- PELICAN_BEGIN_SUMMARY -->
<p>现在这里的界面风格要从 Google 在 <a class="reference external" href="https://www.google.com/events/io">I/O 2014 大会</a>
上公布Android L 也即 后来的 Lollipop 说起。 他们在谈论界面设计的时候公布了他们的
设计准则: <a class="reference external" href="http://www.google.com/design/spec/material-design/introduction.html">Material Design</a> (<a class="reference external" href="http://wcc723.gitbooks.io/google_design_translate/">中文非官方翻译</a> )。
当然这只是一些准则,总结并描述了之前在 Web 设计和移动端 App 界面设计方面的一些规范,
并且用材料的类比来形象化的比喻这个准则。关于 Material Design 的更多中文资料可
<a class="reference external" href="http://www.ui.cn/Material/">参考这里</a> 。</p>
<p>看到 Material Design 之后就觉得这个设计风格非常符合直觉,于是想在这边也用上
Material Design。 但是我在 Web 前端科技树上没点多少技能点,所以想找找别人实现好的模板
或者框架直接套用上。在网络上搜索数日找到了这几个:</p>
<div class="section" id="polymer-paper-elements">
<h2>Polymer Paper Elements</h2>
<!-- PELICAN_END_SUMMARY -->
<div class="panel panel-default">
<div class="panel-heading">
Polymer</div>
<div class="panel-body">
<object class="embed-responsive-item" data="https://www.polymer-project.org/images/logos/p-logo.svg" type="image/svg+xml">
Polymer logo</object>
</div>
</div>
<!-- PELICAN_BEGIN_SUMMARY -->
<p>Google …</p></div><!-- PELICAN_BEGIN_SUMMARY -->
<p>现在这里的界面风格要从 Google 在 <a class="reference external" href="https://www.google.com/events/io">I/O 2014 大会</a>
上公布Android L 也即 后来的 Lollipop 说起。 他们在谈论界面设计的时候公布了他们的
设计准则: <a class="reference external" href="http://www.google.com/design/spec/material-design/introduction.html">Material Design</a> (<a class="reference external" href="http://wcc723.gitbooks.io/google_design_translate/">中文非官方翻译</a> )。
当然这只是一些准则,总结并描述了之前在 Web 设计和移动端 App 界面设计方面的一些规范,
并且用材料的类比来形象化的比喻这个准则。关于 Material Design 的更多中文资料可
<a class="reference external" href="http://www.ui.cn/Material/">参考这里</a> 。</p>
<p>看到 Material Design 之后就觉得这个设计风格非常符合直觉,于是想在这边也用上
Material Design。 但是我在 Web 前端科技树上没点多少技能点,所以想找找别人实现好的模板
或者框架直接套用上。在网络上搜索数日找到了这几个:</p>
<div class="section" id="polymer-paper-elements">
<h2>Polymer Paper Elements</h2>
<!-- PELICAN_END_SUMMARY -->
<div class="panel panel-default">
<div class="panel-heading">
Polymer</div>
<div class="panel-body">
<object class="embed-responsive-item" data="https://www.polymer-project.org/images/logos/p-logo.svg" type="image/svg+xml">
Polymer logo</object>
</div>
</div>
<!-- PELICAN_BEGIN_SUMMARY -->
<p>Google 官方提供的参考实现应该是 <a class="reference external" href="https://www.polymer-project.org/">Polymer</a> 中的
<a class="reference external" href="https://www.polymer-project.org/docs/elements/paper-elements.html">Paper Elements</a> 。</p>
<!-- PELICAN_END_SUMMARY -->
<p>由于是 <strong>官方参考实现</strong> ,这个框架的确非常忠实地实现了 Material Design 的设计,但是同时
由于它基于 <a class="reference external" href="http://webcomponents.org/">HTML5 Web Components</a> 构建,相关技术我还
不太懂,浏览器兼容性和其余 HTML 技术的兼容性也还不太完善的样子……</p>
<p>并且对于我这个 Web 开发的半吊子来说,Polymer 只是提供了一组设计组建,没有完善的
<strong>响应式</strong> (responsive) 布局支持,也没有 Navbar 这种常见的框架组建,真的要用起来的话还
需要手工实现不少东西。于是口水了半天之后只好放弃……以后可能真的会换用这个,只是目前需要学
的东西太多了。</p>
</div>
<div class="section" id="angular-material-design">
<h2>Angular Material Design</h2>
<div class="panel panel-default">
<div class="panel-heading">
AngularJS</div>
<div class="panel-body">
<img alt="AngularJS logo" class="img-responsive" src="https://angularjs.org/img/AngularJS-large.png"/>
</div>
</div>
<p><a class="reference external" href="https://angularjs.org/">AngularJS</a> 是 Google 对 Web Components 技术的另一个
尝试。而这额 <a class="reference external" href="https://material.angularjs.org/">Angular Material Design</a> 项目
就是基于 AngularJS 构建的Material Design 库啦,同样是 Google 出品所以应该算得上半个
官方实现吧。 相比于 Polymer, AngularJS 算是实用了很多,提供了基于
<a class="reference external" href="http://www.w3.org/TR/css3-flexbox/">CSS Flexbox</a> 的布局。有人对这两者的评价是,
如果说 Polymer 代表了 <strong>未来趋势</strong> ,那么 AngularJS 就是 <strong>眼下可用</strong> 的 Web
Components 实现了。</p>
<p>只不过同样是因为它是 Components 的框架,对 WebApp 的支持很丰富,大量采用 Ajax 等
JavaScript 技术, 对于我这个静态博客来说仍然稍显高级了……非常担心还不支持 HTML5 的浏览器
比如 w3m 甚至 cURL 对它的支持程度。 于是最终也没有使用它。</p>
</div>
<div class="section" id="materialize">
<h2>Materialize</h2>
<div class="panel panel-default">
<div class="panel-heading">
Materialize</div>
<div class="panel-body">
<img alt="Materialize logo" class="img-responsive" src="https://raw.githubusercontent.com/Dogfalo/materialize/master/images/materialize.gif"/>
</div>
</div>
<p><a class="reference external" href="http://materializecss.com/">Materialize</a> 这是一批(自称?)熟悉 Android 上
Material Design 的设计师们新近出炉的框架,试图提供一个接近 Bootstrap 的方案。
最早是在 <a class="reference external" href="http://www.reddit.com/r/web_design/comments/2lt4qy/what_do_you_think_of_materialize_a_responsive/">Reddit</a> 上看到对它的讨论的,立刻觉得这个想法不错。</p>
<p>体验一下官网的设计就可以看出,他们的动画效果非常接近 Polymer 的感觉,响应式设计的布局
也还不错。 只是同样体验一下他们现在的官网就可以看出,他们目前的
<a class="reference external" href="https://github.com/Dogfalo/materialize/issues">bug 还比较多</a> ,甚至一些 bug
在他们自己的主页上也有显现。 虽然不想给这个新出炉的项目泼凉水,不过看来要达到他们声称的接近
Bootstrap 的易用度还任重而道远……</p>
</div>
<div class="section" id="bootstrap-material-design-bootstrap3">
<h2>bootstrap-material-design + bootstrap3</h2>
<p>这是我最终选择的方案。这个方案将三个项目组合在了一起,分别是
<a class="reference external" href="http://fezvrasta.github.io/bootstrap-material-design/">bootstrap-material-design</a>
, <a class="reference external" href="https://github.com/DandyDev/pelican-bootstrap3">pelican-bootstrap3</a>
和 <a class="reference external" href="http://getbootstrap.com/">Bootstrap 3</a> 。
Bootstrap 3 想必不用再介绍了,很多网站都在使用这套框架,定制性很高。
bootstrap-material-design 是在 Bootstrap 3 的基础上套用 Material Design 风格
制作的一套 CSS 库,当然也不是很完善并且在不断改进中,一些细节其实并不是很符合我的要求。
最后 pelican-bootstrap3 是用 Bootstrap 3 做的 pelican 模板。
这三个项目或多或少都有点不合我的口味,于是嘛就把 pelican-bootstrap3 fork了一套放在
<a class="reference external" href="https://github.com/farseerfc/pelican-bootstrap3">这里</a> ,其中还包括我自己改
过的 <a class="reference external" href="https://github.com/farseerfc/pelican-bootstrap3/tree/master/static/bootstrap">Bootstrap3 样式</a>
和 <a class="reference external" href="https://github.com/farseerfc/pelican-bootstrap3/tree/master/static/material">Material 样式</a>
,需要的可以自取。</p>
<p>至于细节上我定制了哪些地方,敬请听下回分解……</p>
</div>