Fork me on GitHub

Programming Design Notes

在 Windows 設定 Octopress

| Comments

因為公司的電腦是 Windows,又想閒來沒事時可以寫寫文章,所以需要在 Windows 上設定 Octopress。 在 Windows 上要設定好 Octopress 是比在 Mac 上麻煩得多。

Install Ruby

首先要安裝 Ruby,Windows 上使用 RubyInstaller 安裝 Ruby, RubyInstaller 已經包括了 Gem

RubyInstaller 在這裡下載: http://rubyinstaller.org/downloads/

我安裝的版本是 Ruby 1.9.3-p125

順便下載 Ruby 的 Development Kit: DevKit-tdm-32-4.5.2-20111229-1559-sfx.exe

安裝好 Ruby 後解壓 Development Kit,再到 Development Kit 資料夾內執行以下指令:

ruby dk.rb init
ruby dk.rb install

由 Blogspot 搬家到 Octopress Github Page

| Comments

由於在 Blogspot 的 Blog 頁面引入太多的 Javascript、CSS 和圖片,令到瀏覽速度援慢。反正要來一個大修改,倒不如連平台亦一起換掉。

現在這個 Blog 是使用 Octopress Blogging Framework 管理文章並放到 Github page 上,速度算不錯,順便將廣告和一些不必要的功能全部移除掉,令整個版面更簡潔,閱讀起來比較舒服。


Shacial 的資料庫設計

| Comments

Shacial 上線時間差不多有 4 星期了,雖然使用的人並不多,但仍然想再將這個服務做得更加好。
在這裡我先公開資料庫設計給大家看看。以後可能會再公開程式碼。(Open Source Project ?)

以下就是 Shacial 的 ERD:



已經設計好支援檔案版本控制。下一步應該要想想如何支援 News Feed,即時的信息傳遞。

自行開發的檔案分享應用程式 - Shacial

| Comments

用了 3 個多月時間,終於完成了這個應用程式。

這個應用程式是一個網路硬碟,但不像一般網路硬碟只是拿來備份東西或發放某些東西,Shacial 著重於分享的功能,雖然現在還有很大部份功能仍然開發中,但基本的功能如: 共同協作、傳送檔案、圖片空間或公開檔案等等已經完成。

背後儲存檔案的是 Amazon S3 加上 EC2 作為 Web Server,速度有一定保證。

希望各位網友能夠試用這個應用程式並給小弟一點點意見。

現時測試為每一個用戶提供 2GB 的空間,並不設類型限制和單一檔案容量上限 (只要不超過配額就可以上載)。

http://www.shacial.com/

如有任何問題可用電子郵件聯絡我。

2012-03-11: 提供 Facebook 和 Google account 登入

測試貼圖:
193 KB

介紹一款 CSS 模組化工具 - LESS

| Comments



網站需要一個漂亮的介面來將資訊帶給用戶,開發這個介面除了要使用 HTML Tag 外,亦需要使用 Cascading Style Sheets (CSS) 去令這個介面更美觀。有人說: 你只要複製一次程式碼其實亦是複製了一個 Bug,所以我們在設計程式時也盡量不要將相同的程式碼複製到不同地方,在 Java 可以將一些程式碼包裝成 Object 以便不同地方也使用同一組程式碼,但在 CSS 又怎麼辦? 使用外部的 CSS 檔案其實已經很大程度地減少重複的外觀設置程式碼,但這仍然不足夠。

今次介紹的工具能夠在 CSS 設置一些常用參數,外觀設置程式碼的組合,簡單的算法和使用 Javascript 功能等等。這款工具就是 LESS 了。

以下例子可以對比普通 CSSLESS CSS 的不同。

參數:

普通 CSS:
.header{
background-color: #777;
color: #f5f5f5;
}

a{
color: #777;
}

p.desc{
border: solid 1px #777;
color: #777;
}

以上的 CSS 出現了好幾次 #777 這個顏色設置,如果網頁樣式改變了,需要將灰色設置為淺一點的灰色,只好一個一個 #777 找出來加以修改。

使用 LESS 可以:
@gray: #777;
@smoke-white: #f5f5f5;
.header{
background-color: @gray;
color: @smoke-white;
}

a{
color: @gray;
}

p.desc{
border: solid 1px @gray;
color: @gray;
}

這樣只需將 @gray 參數改變就可以一次轉換所有灰色了。

除了參數還可以組合外觀設置程式碼:

普通 CSS:
.header{
border-radius: 5px;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
}

ul.stack li{
border-radius: 3px;
-moz-border-radius: 3px;
-webkit-border-radius: 3px;
}

LESS CSS:
.border-radius (@radius 5px) {
border-radius: @radius;
-moz-border-radius: @radius;
-webkit-border-radius: @radius;
}

.header{
.border-radius;
}

ul.stack li{
.border-radius(3px);
}

因為不同的瀏覽器設置圓角的程式碼也不同,如果以後又有一款新瀏覽器提供圓角的樣式,就可以加一句到 .border-radius 就完成所有設置,方便得多。
LESS 的組合外觀設置程式碼提供了傳入參數和默認參數。

LESS 可以令 CSS 程式碼更直觀:

普通 CSS:
.header p{
background-color: #777;
}

.header p span{
font-size: 18px;
}

.header p span.brand a{
color: #ccc;
}

.header p span.brand a:hover{
color: #f5f5f5;
}

LESS CSS:
.header{
p{
background-color: #777;

span{
font-size: 18px;

&.brand{
a{
color: #ccc;

&:hover{
color: #f5f5f5;
}
}
}
}
}
}

這樣可以更加清楚知道 .header 內的所有風格。

如要使用 LESS2 種方法:
  • 使用 less.js 在瀏覽器將 LESS CSS 轉換為普通 CSS
  • 下載 Node.js 然後使用 npm 去下載 LESS 並使用 CommandLESS CSS 轉換為普通 CSS

第一個方法在開發環境使用還好,在真實環境建議使用第 2 種方法。

我弄了一個 Node.jsscript 以方便大量轉換 CSS,有興趣可拿去用:
#!/usr/bin/env node

var sys = require('util')
var fs = require('fs');
var less = require('less');

var targetDir = 'public';
var currentDir = 'source';

convertResource(currentDir);

function convertResource(dirName){
fs.readdir(dirName, function(err, files){
if (err){
console.log(err);
return;
}
for (var i = 0; i < files.length; i++){
(function(){
var sourceFile = dirName + "/" + files[i];
var targetFile = sourceFile.replace(currentDir, targetDir);
fs.lstat(sourceFile, function(e, stats){
if (stats.isDirectory()){
if (!isFileExist(targetFile)){
fs.mkdirSync(targetFile);
}
convertResource(sourceFile);
}else{
if (sourceFile.match(/^(.*)(\.css|\.less)$/i)){
complieCss(sourceFile, targetFile.replace(/^(.*)(\.css|\.less)$/i, "$1.css"));
}else{
var is = fs.createReadStream(sourceFile)
var os = fs.createWriteStream(targetFile);
sys.pump(is, os);
}
}
});
})();
}
});
}

function complieCss(sourceFile, targetFile){
fs.readFile(sourceFile, "utf-8", function(e, data){
new(less.Parser)({
paths: [".", sourceFile.substring(0, sourceFile.lastIndexOf('/'))],
filename: sourceFile
}).parse(data, function (err, tree) {
if (err) {
console.log(err);
} else {
try {
css = tree.toCSS({
yuicompress: true
});
if (targetFile) {
if (isFileExist(targetFile)){
fs.unlinkSync(targetFile);
}
var fd = fs.openSync(targetFile, "w");
fs.writeSync(fd, css, 0, "utf8");
}else{
sys.print(css);
}
} catch (e) {
console.log("CSS file complie error. Ignore file: " + sourceFile);
}
}
});
});
}

function isFileExist (path) {
try {
fs.statSync(path);
return true;
} catch (e) {
return false;
}
}

更多的用法可在 LESS 官網找到:
官網: http://lesscss.org/