蠎周刊 - Chaoshttps://weekly.pychina.org/2016-04-07T07:10:30+08:00How to from Jekyll jump into Pelican2013-12-19T10:42:00+08:002016-04-07T07:10:30+08:00Zoom.Quiettag:weekly.pychina.org,2013-12-19:/chaos/jekyll-to-pelican.html<p>[TOC]</p>
<h1>如何从 Jekyll 转进入 Pelican</h1>
<p>简述静态网站从 Jekyll 环境中迁移为 纯 Python
<a href="http://getpelican.com/">Pelican</a>...</p>
<p><img alt=";" src="https://0.gravatar.com/avatar/0cb9d9d7e6b152d24d2b78c6464502a6?d=https%3A%2F%2Fidenticons.github.com%2Fc0b8694f59232c6681a92c4c9fec3e18.png&r=x&s=440"></p>
<h2>为毛</h2>
<p>社区在发展, 原先的 蠎周刊,为方便,使用了 gitcafe 内置的 Jekyll …</p><p>[TOC]</p>
<h1>如何从 Jekyll 转进入 Pelican</h1>
<p>简述静态网站从 Jekyll 环境中迁移为 纯 Python
<a href="http://getpelican.com/">Pelican</a>...</p>
<p><img alt=";" src="https://0.gravatar.com/avatar/0cb9d9d7e6b152d24d2b78c6464502a6?d=https%3A%2F%2Fidenticons.github.com%2Fc0b8694f59232c6681a92c4c9fec3e18.png&r=x&s=440"></p>
<h2>为毛</h2>
<p>社区在发展, 原先的 蠎周刊,为方便,使用了 gitcafe 内置的 Jekyll 服务,
所以,其实在使用 Ruby 自动编译和发布.</p>
<p>总是感觉不够纯粹 Pythonic ...</p>
<p>故而, 下决心完成迁移</p>
<h1>整体</h1>
<p>忽然发现,俺感觉很直觉的事儿,也写了文档,
但是,其它人真正首次上手全然一头雾水...</p>
<p>所以
<a href="http://xiaolai.github.io/alpha/on-learning/">学习学习再学习 - xiaolai</a>
提出的,俺实在无法同意更多..</p>
<p><img alt="Impossible_staircase" src="http://upload.wikimedia.org/wikipedia/commons/3/34/Impossible_staircase.svg"></p>
<p>这是最难的知识结构——它往往看起来跟线性结构没什么区别,但,最终令人迷惑,甚至懊恼。
用最直白的话来描述,就是:</p>
<div class="highlight"><pre><span></span><code>初级的知识需要对高级知识深入了解才能真正深入了解
</code></pre></div>
<p>——你看看这句话多拗口就多少有点概念了。</p>
<p>所以,还是按照 easy 模式来,
先简单的说,再往死里说折腾的技术细节...</p>
<h2>已知条件</h2>
<p><a href="https://help.github.com/articles/user-organization-and-project-pages">User, Organization and Project Pages</a></p>
<p>github 的 所谓 <code>pages</code> 服务的本质:</p>
<ul>
<li>云端的 Jekell 服务</li>
<li>对约定的仓库,感知变化时,就尝试进行编译</li>
<li>并自动完成发布(现在是到 github.io)</li>
</ul>
<p>这里的约定仓库,只有两种情况:</p>
<ol>
<li>用户/组织: <ul>
<li>比如, 注册成的用户/组织 为 https://github.com/foo</li>
<li>则, github 尝试进行 <code>pages</code> 发布的仓库为:</li>
<li>https://github.com/foo/foo.github.io</li>
<li>发布到: https://foo.github.io</li>
</ul>
</li>
<li>项目<ul>
<li>任意一个项目仓库,比如, https://github.com/foo/foobar</li>
<li>则, githuba 支持自动对此仓库的 <code>gh-pages</code> 分支进行 <code>pages</code> 编译</li>
<li>而发布为: https://foo.github.io/foobar</li>
</ul>
</li>
</ol>
<h2>Pelican行为</h2>
<p><a href="http://getpelican.com/">Pelican</a> 呢其实也只是
Python 世界中大堆静态网站发布工具中的一个,
为毛选中这个?
只是因为 42分钟里,大妈将其折腾起来了,
而且官方的文档/案例/样式,的确足够丰富,
给人信心...</p>
<p>而其本身对网站的约定非常简单:</p>
<ul>
<li>配置好 <code>pelicanconf.py</code></li>
<li>在 <code>content</code> 目录中写作</li>
<li>一键命令编译完成静态网络的生成,组织到 <code>output</code></li>
</ul>
<h2>所以?方案!</h2>
<p>基于以上的整体理解, 就可以决策怎么基于 github 的 <code>pages</code> 服务,
来进行免费的网站发布了;</p>
<p>目测也就两招:</p>
<ol>
<li>在用户/组织 的 <code>pages</code> 仓库中直接部署 Pelican 工程<ul>
<li>只是要在根目录部署一个自动跳转到 <code>output</code> 子目录的 <code>index.html</code> 页面</li>
<li>以便发布后可以略过根目录来访问编译结果的内容</li>
<li>发布成 https://foo.github.io/output</li>
</ul>
</li>
<li>用两个仓库, 将用户/组织 的 <code>pages</code> 仓库部署为 <code>output</code> 子目录<ul>
<li>这样就能自动发布为 https://foo.github.io</li>
</ul>
</li>
</ol>
<p>很明显,第二种逼格较髙,所以,就这样办了!</p>
<h2>宏观流程</h2>
<ol>
<li>首次建立本地撰写环境:<ol>
<li>安装好 <a href="http://getpelican.com/">Pelican</a></li>
<li>分别clone 出两个仓库:<ul>
<li>qpython-android.pelican </li>
<li>qpython-android.github.io </li>
</ul>
</li>
<li>先在 <code>qpython-android.pelican</code> 中测试确认好 pelical 工程可用,并尝试编译</li>
<li>一切正确的话,将 <code>qpython-android.github.io</code> 复制覆盖为 <code>qpython-android.pelican/output</code></li>
</ol>
</li>
<li>以后,日常的维护就再也不需要 <code>qpython-android.github.io</code> 了!<ol>
<li>进入 <code>qpython-android.pelican/content</code> 创建/增补/修订 文章</li>
<li>回到 <code>qpython-android.pelican</code> 执行 <code>fab build</code></li>
<li>本地到 <code>output</code> 打开对应页面检查效果</li>
<li>还是在 <code>qpython-android.pelican</code> 执行 <code>fab pub2hub</code> <ul>
<li>完成对 <code>qpython-android.github.io</code> 仓库实际的 push </li>
<li>即, 发布成网站: http://qpython-android.github.io</li>
</ul>
</li>
<li>最后,在 <code>qpython-android.pelican</code> 进行正常的 <code>git add->ci->pu</code><ul>
<li>对文章源文本完成到 <code>qpython-android.pelican</code> 仓库的提交</li>
</ul>
</li>
</ol>
</li>
</ol>
<p>收功!</p>
<h1>细节</h1>
<p>然后, 再分享俺的折腾过程...</p>
<h2>过程</h2>
<p>整体上,其实就三步:</p>
<ol>
<li>选择一个 theme ,完成本地 demo 整明白怎么使用 Pelican</li>
<li>将原先 Jekyll 格式的文章声明部分文本, 批量转化为 Pelican 的</li>
<li>改进发布流程,自动化</li>
</ol>
<h3>theme</h3>
<p>综合对比了官网收集的一堆样式,选择了 <a href="https://github.com/DandyDev/pelican-bootstrap3">DandyDev</a> 的,根据说明,立即就完成了编译,本地检阅 ;-)</p>
<h3>meta</h3>
<p>果断使用 Python 脚本,快速完成转换
<a href="https://gitcafe.com/CPyUG/weekly/blob/master/_plugins/jekyll2pelican.py">jekyll2pelican.py</a></p>
<h3>fab</h3>
<p>果断使用 <code>fabric</code> 进行自动化处理!</p>
<ul>
<li>参考: <a href="https://gitcafe.com/CPyUG/weekly/blob/master/fabfile.py">fabfile.py</a></li>
<li>定制了 <code>pub2cafe</code> 完成自动化发布</li>
</ul>
<p>因为 <code>gitcafe</code> 只有用户同名-pages 服务,所以,对于当前 <code>蠎周刊</code> 的 Pelican 工程,
用两个仓库,配合完成:</p>
<div class="highlight"><pre><span></span><code>https://github.com/qpython-android/qpython-android.pelican.git
+- ..
+- pelicanconf.py 主配置文件
+- content 内容目录
+- output 编译输出目录
| `- https://github.com/qpython-android/qpython-android.github.io.git
| |
| \-- 即合法的
+- .gitignore 配置忽略 output 目录
+- ...
</code></pre></div>
<p>这样一来,目录,就不用进入 <code>output</code> 目录进行 git 操作了
平时的发布流程就是:</p>
<ol>
<li>在 <code>content</code> 目录对应分类子目录中创建 <code>*.md</code> 文本,组织文章</li>
<li><code>fab build</code> 完成编译,本地检阅文章效果</li>
<li><code>git add . && git ci && git pu</code> 将增补提交</li>
<li><code>fab pub2cafe</code> 自动完成进入 <code>output</code> 后的一系列 git 操作</li>
</ol>
<p>对应的 配置中:</p>
<div class="highlight"><pre><span></span><code><span class="c1">#DELETE_OUTPUT_DIRECTORY = True</span>
</code></pre></div>
<p>就绝对不能打开注释
不然 <code>output</code> 目录清除,就没有了 <code>.git</code> 也就无法发布了...</p>
<h2>坑</h2>
<p>整个过程中,遇到没有找到文档的小麻烦,自个儿解决了的....</p>
<h3>DISQUS</h3>
<p>果断遇到了 DISQUS 配置了,不生效的问题,上下折腾, 才发现很多人都遇到了这个问题,
追踪到代码:</p>
<div class="highlight"><pre><span></span><code><span class="c1">//... pelican-themes/pelican-bootstrap3/templates/includes/comments.html</span>
<span class="c1">//...</span>
<span class="kd">var</span><span class="w"> </span><span class="nx">disqus_shortname</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s1">'{{ DISQUS_SITENAME }}'</span><span class="p">;</span><span class="w"> </span><span class="c1">// required: replace example with your forum shortname</span>
<span class="kd">var</span><span class="w"> </span><span class="nx">disqus_identifier</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s1">'{{ article.slug }}'</span><span class="p">;</span>
<span class="kd">var</span><span class="w"> </span><span class="nx">disqus_url</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s1">'{{ SITEURL }}/{{ article.url }}'</span><span class="p">;</span>
</code></pre></div>
<p>才发现 <code>SITEURL</code> 的配置是决定性的,
一定要同 <code>DISQUS</code> 申请时的一致;
本地编译后, 看一眼源代码,就知道是否靠谱了...</p>
<h3>pages</h3>
<p>突然发现 <code>content/pages</code> 目录中的文本,是种特殊文章,不但可以出现在导航,而且使用专用的模板,
所以,默认是没有 <code>DISQUS</code> 槽接的!</p>
<ul>
<li>参考,俺的<a href="https://gitcafe.com/CPyUG/weekly/blob/master/_themes/pelican-bootstrap3/templates/page.html">page.html</a> </li>
<li>追加了仿制的: <a href="https://gitcafe.com/CPyUG/weekly/blob/master/_themes/pelican-bootstrap3/templates/includes/page_comments.html">includes/page_comments.html</a></li>
</ul>
<p>fixed!</p>
<h3>CATEGORY_FEED_ATOM</h3>
<p>一时手賎,打开了:</p>
<div class="highlight"><pre><span></span><code><span class="na">CATEGORY_FEED_ATOM</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">'feeds/%s.atom.xml'</span>
</code></pre></div>
<p>结果,发现不能在模板里简单的完成分类子 RSS 的链接!</p>
<div class="highlight"><pre><span></span><code> <span class="p"><</span><span class="nt">i</span> <span class="na">class</span><span class="o">=</span><span class="s">"icon-th icon-large"</span><span class="p">></</span><span class="nt">i</span><span class="p">></span>Categories<span class="p"></</span><span class="nt">h4</span><span class="p">></</span><span class="nt">li</span><span class="p">></span>
{% for cat, null in categories %}
<span class="p"><</span><span class="nt">li</span> <span class="na">class</span><span class="o">=</span><span class="s">"list-group-item"</span><span class="p">></span>
<span class="p"><</span><span class="nt">a</span> <span class="na">href</span><span class="o">=</span><span class="s">"{{ SITEURL }}/{{ cat.url }}"</span><span class="p">></span>
<span class="p"><</span><span class="nt">i</span> <span class="na">class</span><span class="o">=</span><span class="s">"icon-folder-open icon-large"</span><span class="p">></</span><span class="nt">i</span><span class="p">></span>{{ cat }}
<span class="p"></</span><span class="nt">a</span><span class="p">></span>
<span class="p"><</span><span class="nt">a</span> <span class="na">href</span><span class="o">=</span><span class="s">"{{ SITEURL }}/feeds/{{ cat }}.atom.xml"</span><span class="p">></span>
<span class="p"><</span><span class="nt">i</span> <span class="na">class</span><span class="o">=</span><span class="s">"icon-rss-sign"</span><span class="p">></</span><span class="nt">i</span><span class="p">></span>
<span class="p"></</span><span class="nt">a</span><span class="p">></span>
<span class="p"></</span><span class="nt">li</span><span class="p">></span>
{% endfor %}
</code></pre></div>
<p>因为这儿的 <code>{{ cat }}</code> 是分类的名称,可能包含大小写字母,
而配置指导下生成的 RSS 文件是全小写的...</p>
<p>纠结了一会儿,也没有查到对应的文档,突然想到各种内置对象都有的 <code>sulg</code> 属性!</p>
<p>于是就猜对了...
参考:
<a href="https://gitcafe.com/CPyUG/weekly/blob/master/_themes/pelican-bootstrap3/templates/includes/sidebar.html#L22">includes/sidebar.html#22</a></p>
<h3>author</h3>
<p>原样式作者因为是个人网站,所以,无所谓 <code>Author</code> 的信息,
但是,作为社区用共笔环境,就必须有所体现,
在 <a href="https://gitcafe.com/CPyUG/weekly/blob/master/_themes/pelican-bootstrap3/templates/includes/article_info.html">includes / article_info.html</a>
先打开作者的属性输出,</p>
<p>然后,从别的 theme 工程中抄一个模板:
<a href="https://gitcafe.com/CPyUG/weekly/blob/master/_themes/pelican-bootstrap3/templates/author.html">author.html</a></p>
<p>即好!</p>
<h3>TOC</h3>
<p>是的,以往 rST/t2t 时,甚至于 Word 时都有的 </p>
<div class="highlight"><pre><span></span><code>TOC ~ 章节索引
</code></pre></div>
<p>肿么可以没有?!</p>
<p>果断: <a href="https://github.com/getpelican/pelican-plugins/tree/master/extract_toc">pelican-plugins/extract_toc at master · getpelican/pelican-plugins</a> </p>
<p>只是这货竟然是依赖 <code>beautifulsoup4</code> 的! 对于非 <code>UNIX/Linux/MAC</code> 用户而言,
人艰不拆哪!!!</p>
<h2>参考:</h2>
<ul>
<li><a href="http://riku.gitcafe.com/pelican-gitcafe.html">使用 Pelican + GitCafe Page 创建 Blog</a></li>
<li><a href="http://blog.imley.net/2013/01/03/disqus-thread-url-issue/#content">吐槽一下DISQUS的thread链接错误问题 | Ley's blog</a></li>
<li><a href="http://raichev.net/blohg-to-pelican.html">Alex Raichev - Blog - Blohg to Pelican</a></li>
</ul>
<h2>Changelog</h2>
<ul>
<li>160401 ZoomQuiet 迁移发布到 github as gh_pages</li>
<li>140127 ZoomQuiet 增补宏观理解</li>
<li>140120 ZoomQuiet 复制到 QPython 的 Pelican 工程</li>
<li>131219 ZoomQuiet 为 <a href="https://gitcafe.com/CPyUG/weekly/blob/master/README.md">CPyUG/weekly - GitCafe</a> 创建</li>
</ul>