在Django中使用LESS

openkk 12年前發布 | 29K 次閱讀 Django Web框架

LESS一種動態樣式語言,簡單來說就是對CSS語言的擴展,可以類比于coffeescript對javascript提煉。我因為 javascript寫習慣了,轉到coffeescript效率不升反降。但用LESS重寫了幾個CSS文件,絕對是快了很多。因為LESS沒有改變 CSS的寫法(唯一變化的是注釋可以用//了),所以沒有轉換障礙。LESS擁有語言的特征,例如變量、函數、命名空間等,和只是樣式表的CSS比起來靈 活了許多。

在前臺使用LESS的方式和coffeescript很像,也是載入一個js文件用來處理less后綴的文件,將其轉換成CSS。

<link rel="stylesheet/less" type="text/css" href="/static/css/styles.less">
<script src="/static/js/less.js" type="text/javascript"></script>

當然如果真這么處理,就和Django沒什么關系了,我一般是在模板里直接用{%block style%}寫CSS樣式,所以如果能自定義一個templatetag,直接在里面寫LESS那是最順手的。

Install

大致的思路是在Django中制作一個模板標簽,調用lessc命令處理其中的語句。所以先裝上nodejs,用nodejs的npm工具安裝less,完成后建立一個軟鏈接以便直接使用lessc命令。

wget http://nodejs.org/dist/v0.6.5/node-v0.6.5.tar.gz
tar xzvf node-v0.6.5.tar.gz
cd node-v0.6.5/
./configure
make
make install
npm install less
ln -s ~/node-v0.6.5/node_modules/less/bin/lessc /usr/local/bin/lessc 

Django Template Tag

思路很簡單,用Python的NamedTemporaryFile和shlex,把自定義tag中的LESS代碼寫入一個臨時文件,用shlex執行lessc來解析,獲得返回的內容輸出到模板就可以了。

from tempfile import NamedTemporaryFile
from django import template
import subprocess, shlex, os

register = template.Library()

class LessNode(template.Node):
    def __init__(self, nodelist):
        self.nodelist = nodelist

    def lessc(self, source):
        #創建臨時文件, delete=False這樣close的時候不會刪除
        less_file = NamedTemporaryFile(delete=False)
        less_file.write(source)
        less_file.close()
        #用lessc執行創建的臨時文件
        cmd = shlex.split("lessc %s" % ( less_file.name))
        run = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        #獲得解析完成的css
        css, error = run.communicate()
        os.remove(less_file.name)
        if error:
            print error
        else:
            return css.decode("utf-8")

    def render(self, context):
        output = self.nodelist.render(context)
        return self.lessc(output)

def do_less(parser, token):
    nodelist = parser.parse(("endless",))
    parser.delete_first_token()
    return LessNode(nodelist)

register.tag('less', do_less)

除了lessc是執行業務邏輯的代碼以外,其他的都是定義template tag用的固定代碼,所以也就沒必要寫注釋了,詳細解釋可以參考官方文檔

Usage

把以上代碼存為less.py文件,放到應用下的templatetag目錄中,然后載入它,例如:

{% load i18n less %}

{% less %}
.corners (@radius: 5px) {
  border-radius: @radius;
  -webkit-border-radius: @radius;
  -moz-border-radius: @radius;
}
form { 
    #id_username {.corners}
    #id_password {.corners(10px)}
}
{% endless %}

實際輸出的CSS:

<style>
form #id_username {
  border-radius: 5px;
  -webkit-border-radius: 5px;
  -moz-border-radius: 5px;
}
form #id_password1 {
  border-radius: 10px;
  -webkit-border-radius: 10px;
  -moz-border-radius: 10px;
}
</style>

Afterword

寫完以后準備提交到github,發現已經有一個名為django-less的 項目了,不止有template tag,還可以直接解析.less文件,從它的安裝說明推斷,應該也是直接用lessc命令來實現的,所以如果像我一樣只需要tag就沒必要裝了,順便以 同樣的方法寫了coffeescript的tag,沒準以后用得上。如果對靜態文件處理的需求比較復雜,還可以用django-assets來進行處理。LESS還有很多有趣的特性,以后寫CSS又多了很多簡單的寫法,不會那么無聊,只能一段一段的復制粘貼了。

文章出處:http://dmyz.org/archives/336

 本文由用戶 openkk 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!