org-mode是極佳的個人事務記錄工具,但在目前org-mode中集成的org-publish功能在實現發布功能主要針對每一個獨立的ORG文件進行。使用org-mode來組織個人blog或wiki顯得相對離散。然而org-mode中提供的各種書寫鏈接的語法,也讓手工組織blog或wiki存在那么一種可能性。通過恰當的CSS,可以塑造優美而易於閱讀的網站。因此,增強org-mode的發布功能成為我近一段時間關注的一個問題。
要解決這個問題通常來說有一下兩個途徑:
- 自己寫emacs-lisp腳本
這種方式對於已經了解甚至精通了emacs-lisp的朋友來說可能不是什么大事,但是對於現階段的我來說,還只能混亂的閱讀一些代碼,距離自己編寫代碼差的還很遠。此外,難道這個問題世界上沒有其他人想到嗎?還是應該盡可能的避免“重新發明輪子”吧。
- 尋找已經發明了的“輪子”
泡在stackoverflow幾天之后,我找到了三只輪子:
- 使用org與ruby的結合體
目前org可以喝Octopress等相結合實現blog功能。對於我來說,由於我日常使用的操作系統在Windows上,而在Windows上搭建Ruby環境是一件讓人痛苦的事情,此外要使用好這種結合體,不可避免要多少了解一些Ruby的概念,短期內我還不想考慮這種技術組合。
- o-blog
o-blog1是一套emacs-lisp開發的將org-mode發布為靜態HTML文件的Emacs擴展功能。emacs通過簡單配置可以實現將org文件發布為一套完整的博客。從o-blog的官方網站可以看到,o-blog支持大多數現代瀏覽器技術,包括:
- Bootstrap 2
- Font-Awesome support
- LESS CSS support
- jQuery support
- HTML5 / CSS3 ready
- Custom Google web fonts support
- Responsive design for many devices
在博客功能方面,也支持生成Tag雲、歸檔等。o-blog的功能全面,看上去很美——哦,這就是我想要的!
- 自組織org文件實現功能
自己組織org文件,手工實現各個頁面的鏈接關系的組織,在一些情況下(特別是在內容比較少的時候)會讓人獲得更大的控制力。有人通過組織org文件,利用org-publish功能實現了搭建個人網站的目標2。通過他貢獻的org文件,我看到了另一種可能——通過組織org文件以及相應的css文件構建完整個人網站的目標。由於很多內容需要手工處理,因此可以說是一種“刀耕火種”的方法,但也透露着一分“原始的”粗獷美。
- 使用org與ruby的結合體
1 功能完備的o-blog不是我的菜
看完o-blog的功能特性列表,感覺真的很好。下載1了源代碼后,按照手冊很快就完成了配置。emacs這時可以使用新的命令“org-publish-blog”來生成頁面。使用Example目錄中的simple.org文件生成了一個完整的意義上的網站。生成的頁面很華麗,但我很快發現了問題:
- o-blog使用單一org文件生成blog網站
o-blog沒有利用org-mode的Publish機制,僅針對單一文件進行處理。那這樣的話,當存儲的blog多了該怎么辦?使用單一文件組織整個網站,在我看來不是一個很好的方式。是不是我還有什么問題沒有弄清楚呢?
- o-blog對我有進一步的web開發技能要求
o-blog引入了bootstrap、LESS等較新的WEB開發技術。要充分利用o-blog的功能,設計一套全新的頁面模板,需要了解Bootstrap、LESS等技術,這對於我來說門檻有些高。如果拋棄這些特性重頭書寫頁面,也讓我感覺浪費。也許,過不了多久,當我充分了解了Bootstrap和LESS后,重新再看o-blog會有完全不一樣的感覺。
- o-blog增加了頁面生成控制屬性
o-blog為能夠實現blog中諸如獨立頁面(Page)、Bootstrap的柵格控制、Blog記錄等在org文檔中增加了很多的控制屬性。從樣例中可以看出來,文檔內容和控制屬性混雜在一起。沒有實現內容與表現的區隔。這種實現讓我感覺到了一種“bad smell”,o-blog的這種設計我不喜歡。
- o-blog的文檔還有待進一步增強
目前o-blog的文檔還不是很全面。現有的樣例和文檔可以解決簡單的使用問題,但是如果想進行深入的調整和使用將不得不閱讀emacs-lisp代碼。這無形中提升了使用o-blog的使用門檻。
o-blog在最初看見的一剎那,給了我一種“驚艷”的感覺,但是我覺得她不是我的菜。也許當我有了更多的知識積淀,重新審視這段文字的時候,會有新的認識。
2 自組織org文件更自由,但需要按照自己的需求調整
其實org-mode已經含有了一套相對完整的發布指令。充分使用org-mode內置的功能,應該可以生成一個完整的網站。所需要的就是一套經過良好設計的“網站組織結構”。一些使用org-mode的Fans共享了自己的一些解決方案,其中就有一套網站組織結構模板2可供借鑒。
在這個模板中,包含如下內容(具體內容請參看本文附錄):
- Makefile
- 用於簡化org發布流程,提升發布速度
- CSS文件
- 用於控制生成的網站顯示
- header.org
- 生成通用的頭文件,此文件可以用於生成網頁的導航菜單、固定顯示的網頁標題等。
- publish-config.el
- 利用org-mode的內置org-publish-project-alist變量控制生成網站。
這套模板讓我有了一個新的思路,利用這套組織結構,完成一個網站是非常有可能的。從org-mode的官方網站,我們可以看到由全世界諸多org-mode的粉絲共同創造書寫的worg就是采用類似這種方式來實現的。
通過訪問org-mode的Git repo,可以得到worg的org源文件。目前worg的org源文件已經達到了驚人的26MB大小,這足以顯示這種組織方式的在支持大量數據顯示上的優越性。研究這些源文件,就可以了解別人是如何通過組織org文件,並生成一個組織良好的網站的。
3 結論
自組織org文件能夠給人更多的控制空間。通過將內容組織進入不同的org文件,可以在大數據量的情況下保持網站整體的有效維護。因此,o-blog暫時還是小微型項目的可選發布方案。對於我希望使用HTML格式組織自己的知識庫來說,自組織org文件應該更加符合我的需求。
4 附錄
- Makefile源代碼
EMACS=emacs ORG_CONFIG_FILE=publish_config.el EMACS_OPTS=--batch --eval "(load-file \"$(ORG_CONFIG_FILE)\")" -f myweb-publish DEST_HOST='myhost.com:public_html/' OUTPUT_DIR=output all: html upload html: @echo "Generating HTML..." @mkdir -p $(OUTPUT_DIR) @$(EMACS) $(EMACS_OPTS) @echo "HTML generation done" upload: clean_bak @cd $(OUTPUT_DIR) && scp -r . $(DEST_HOST) && cd .. clean: clean_output clean_bak clean_output: @rm -rf $(OUTPUT_DIR) clean_bak: @find . | grep ~$$ | while read l; do rm $$l; done
- header.org
Main | Add here more links or any other stuff #+BEGIN_HTML <p>Write here whatever HTML code you need to include in every page. For instance, Javascript stuff to count visits.</p> #+END_HTML
- publish-config.el
(add-to-list 'load-path "~/.emacs.d/utils") (add-to-list 'custom-theme-load-path "~/.emacs.d/themes") (require 'org-publish) (require 'htmlize) (setq org-publish-project-alist '( ;; These are the main web files ("org-notes" :base-directory "/cygdrive/d/HOME/web/" ;; Change this to your local dir :base-extension "org" :publishing-directory "output" :recursive t :publishing-function org-publish-org-to-html :headline-levels 4 ; Just the default for this project. :auto-preamble t :section-numbers nil :headline-levels 3 :table-of-contents nil :style "<link rel='stylesheet' type='text/css' href='css/style.css' />" :style-include-default nil ) ;; These are static files (images, pdf, etc) ("org-static" :base-directory "/cygdrive/d/HOME//web/" ;; Change this to your local dir :base-extension "css\\|js\\|png\\|jpg\\|gif\\|pdf\\|mp3\\|ogg\\|swf\\|txt\\|asc" :publishing-directory "output" :recursive t :publishing-function org-publish-attachment ) ("org" :components ("org-notes" "org-static")) ) ) (defun myweb-publish nil "Publish myweb." (interactive) (org-publish-all))
