Tag Archives: python

Emacs打开python文件时加载ropemacs

用Emacs作为日常的编辑器有些日子了,各种爽,只是之前的配置会让Emacs在启动的时候自动加载ropemacs,这个东西只有在编辑python文件时才有用,启动时加载会让Emacs的整个启动速度变慢。于是对此作了一下微调,使用eval-after-load宏,在python-mode完成加载后(即打开一个python文件后)才开始加载ropemacs。 我的init.el里面,关于python的配置修改如下: BTW:因为感冒才有借口不务正业一番,又重温了一下lisp。lisp太美了,决定以后就拿学习lisp当休闲,虽然短时间内工作中用不上lisp,但我已经相信熟悉lisp能让自己的编程水平更上一层楼,至少在视野上。

Posted in 技术 | Tagged , | 2 Comments

使用VitrualEnvWrapper隔离python项目的库依赖

是什么 VirtualEnv用于在一台机器上创建多个独立的python运行环境,VirtualEnvWrapper为前者提供了一些便利的命令行上的封装。 为什么要用 – 隔离项目之间的第三方包依赖,如A项目依赖django1.2.5,B项目依赖django1.3。 – 为部署应用提供方便,把开发环境的虚拟环境打包到生产环境即可,不需要在服务器上再折腾一翻。 怎么用 安装 – pip install virtualenvwrapper – 把下面这句加到~/.bash_profile里面,如不嫌麻烦,也可以每次都手动执行。 source /usr/local/bin/virtualenvwrapper.sh 常用命令 创新的虚拟环境 – mkvirtualenv [env1] 该命令会帮我们创建一个新环境,默认情况下,环境的目录是.virtualenv/en1,创建过程中它会自动帮我们安装pip,以后我们要安装新依赖时可直接使用pip命令。 创建完之后,自动切换到该环境下工作,可看到提示符变为: (env1)$ 在这个环境下安装的依赖不会影响到其他的环境 – lssitepackages 显示该环境中所安装的包 切换环境 – workon [env] 随时使用“workon 环境名”可以进行环境切换,如果不带环境名参数,则显示当前使用的环境 – deactivate 在某个环境中使用,切换到系统的python环境 其他命令 – … Continue reading

Posted in 技术 | Tagged , | 2 Comments

Autoforms使用指南

Autoforms是Jeff开源的一个基于Django的自定义表单引擎,可用于调查、投票、信息收集甚至是整合至工作流程引擎和PAAS平台当中。目前AutoForms主要用于支持珠三角地区几个技术社区的线下活动报名、反馈收集等。jeff在本站上也搭建了一个autoforms的实例,可以免费为大家提供简单的在线表单服务,有兴趣者,可联系我开通帐号。最近对AutoForms的使用反馈越来越多,所以更新会相对频繁一些,嗯,有人使用就有动力呀! AutoForms(今天下午发布最新版本为0.4)的主要特性: 支持14种字段类型13种html输入控件(包括日期选择组件),可以快速定制大部份常见的表单。 保存用户提交的表单数据,并向表单作者展示,同时提供数据导出功能。 支持表单继承,需要周期性地使用相同的表单时,一点也不费力。 用户填写表单后,邮件通知表单作者。 提供了丰富的API,容易与其他应用程序作整合。 关于AutoForms的安装请参考github上面的说明,本文主要的内容是指导表单用户如何使用Autoforms。 登录 首先登录至管理界面(http://f.jeffkit.info/admin/ 帐号为 form/form),会看到Autoforms的应用,该应用有两个模型可供管理: 表单管理提供快速创建、修改表单;预览表单,查看表单数据以及生成某入式表单代表等功能。 表单域管理则提供对某些表单域的高级设置功能。 创建表单 下面我通过创建一个“AutoForm用户反馈表单”为例,示范一下如何使用AutoForms来创建表单。 首先,我们点击表单管理的增加按钮开始,打开增加表单的页面,表单上半部份是表单的基本信息,下半部分是定义该表单所包括的字段(表单域)。下图是填写AutoForm用户反馈表单的示例数据: 补充说明一下上面页面一些容易迷惑的地方: 父表单:如果指定某个表单为父表单,那么所创建的表单将自动获得父表单的所有字段。 启用:如果处于勾选状态,则表单可供填写,否则表单只能查看而不能提交。 表单域里的组件:组件是指在页面上展示表单时使用的HTML控件,如你的字段是密码类的,你最好选择“密码输入框”组件。一般情况下,使用默认的组件已经足够。 接下来,点击”保存并继续编辑”按钮,这时在页面的面上角出现了一些快捷按钮: 预览,让您预览所创建的表单的展示效果。 数据,用户通过表单提交数据后,表单作者可以在此看到所有提交的数据并可将数据导出为CSV格式。 嵌入,autoforms允许用户通过嵌入页面的方式展现在第三方网站上面,点击该按钮可获得嵌入的HTML代码。 历史,Django的内置的数据为更记录。 在网站上查看,点击后打开填写表单页面。 预览表单 我们先点击预览按钮,看看刚才创建的表单的效果如何!结果有点意外,“评分”和“在哪了解到autoforms”两个字段光秃秃的! 其实并不意外,我们在表单是创建了两个选项/多选值类型的字段,而我们还没有为这两个字段提供选项数据,所以它们看上去是光秃秃的,那么下一步,我们就是要为选项类型的字段加上选项数据。 编辑字段 返回管理首页,点击表单域进入表单域列表页面,在这里可以找到刚在才创建表单时生成的几个字段,点击“在哪了解到autoforms”进入该字段的编辑页面,页面由一个展开区域和(字段基础信息),三个隐藏区域(高级设置、选项、错误信息)组成。高级设置暂略过不理,选项区就是我们要为选项类型的字段提供数据的地方,而错误信息则允许我们自定议错误提示内容。 下面我要为“在哪了解到autoforms”字段提供一些选项数据,如下图这般添加一些数据: 保存字段的修改,再依法泡制一下“评分”字段,一个表单就完成了。最终结果就是下面的表单了,各位使用过autoforms的同学,来这里给我一些建议吧。 收集数据 表单定义好了,是时候发出去给大家填写了,收集上一段时间后,可以通过“数据”页面来查看已经收集好的数据,如果你愿意,可以点击右上角的导出按钮,以CVS的格式导出数据: 好了,AutoForms的基本使用就这么一些,如果你是开发人员,对API感兴趣,欢迎阅读代码,如果你有些空闲时间,希望掺和一些开源项目,AutoForms也欢迎你加入到开发者行列。

Posted in 技术 | Tagged , , , | 7 Comments

python调用shell脚本的两种方法

python调用Shell脚本,有两种方法:os.system(cmd)或os.popen(cmd),前者返回值是脚本的退出状态码,后者的返回值是脚本执行过程中的输出内容。实际使用时视需求情况而选择。 现假定有一个shell脚本test.sh: #!/bin/bash echo "hello world!" exit 3 os.system(cmd): 该方法在调用完shell脚本后,返回一个16位的二进制数,低位为杀死所调用脚本的信号号码,高位为脚本的退出状态码,即脚本中“exit 1”的代码执行后,os.system函数返回值的高位数则是1,如果低位数是0的情况下,则函数的返回值是0×100,换算为10进制得到256。 如果我们需要获得os.system的正确返回值,那使用位移运算可以还原返回值: >>>  n = os.system(test.sh) >>> n >> 8 >>> 3 os.popen(cmd): 这种调用方式是通过管道的方式来实现,函数返回一个file-like的对象,里面的内容是脚本输出的内容(可简单理解为echo输出的内容)。使用os.popen调用test.sh的情况: python调用Shell脚本,有两种方法:os.system(cmd)或os.popen(cmd),前者返回值是脚本的退出状态码,后者的返回值是脚本执行过程中的输出内容。实际使用时视需求情况而选择。 明显地,像调用”ls”这样的shell命令,应该使用popen的方法来获得内容。

Posted in 技术 | Tagged , , | Leave a comment

Pinax的意义

某天在研究pypy的时候无意中看到了pinax,了解之下,觉得pinax真的很聪明,跟我正打算做的事情很像!她是一个基于Django的基础应用–我这里讲基础应用的意思是她既不是开发框架,又不是一开箱即用的成熟应用(当然你不介意那简陋的界面的话,它是开箱即用的),而是介于两者之间的东西。她集成了很多第三方的Django app,这使得她自己内置了很多SNS网站、公司内部网站所需要的基础功能,你要做一个SNS网站,拿来改改界面就好,你要做公司内网应用,拿来改改界面也行了。 初次接触时,还没有安装来研究,就屁颠屁颠地跟老潘说这是个好东西(我对云和企业内部办公系统有些想法,经常和老潘交流),老潘一看说颇有Plone的影子了。后来安装下来看了看,离plone所谓的应用服务器那个级别还差远了,pinax可以看作是一系列的Project template(项目模板)。接下来给出几种模板的应用运行时的截图,大家看看就明白了。至于更深入的探究不是今天要说的,有兴趣的同学直接试一试更有意义。 图一:basic_project,最简单的应用模板。   图二:内部应用的模板,提供了几种内部应用用到的功能,如任务、wiki等。   图三:Pinax提供的最复杂的一个应用模板,SNS应用,不少SNS网站是基于这个来开发的。 Pinax给开发者带来什么?一、没有技术上的转变,该用Django还是使用Django那套东西。二、提供了一套基础网页模板和Tab布局。这个虽然简单,但十分实用,要换套皮肤,把现成的扔给美工MM略作修改即可,无需从0开始。三、Pinax提供的最复杂的应用模板是一个SNS应用,实际上是一个完全可以马上投入使用的产品。Pinax说,我们已经为您提供所有需要的,你要做的只是让你的网站看起来与众不同。 题外话:一、Django变得越来越强大的同时也变得复杂,要全部掌握Django的内容门槛不低,但这不妨碍初学者快速上手。二、有人说,django变得越来越像zope,但实际上django的门槛恐怕没有zope的20%吧,虽然django渐渐肥胖,但新增的很多东西都是可选的,并且是在web开发过程中必需去解决的问题。大家看到新出一个web framework很清爽简单,不过走着瞧吧,到最后,他不是整合其他第三方的基础模块就是自己继续砌砖,直到又有ORM、Template、Form、中间件、UrlRoute、I18N,I10N等等等等,大家殊途同归,区别不过是OEM或Fullstack而已。三、Django社区很活跃,看看第三方的app就知道,以至于有人可以全使用第三方的应用(没有自己的Model)搭起一个博客,以及现在这个pinax。 四、web应用开发领域,可重用的东西太多,于是有了框架,而技术之上的业务层面,可重用的东西也有很多,例如用户、权限、流程引擎等,Django首先把这业务层面可重用的东西做了一套参考标准并放到开发框架里面来了,大善!太实用了!这也是我几年前希望为公司内部的开发框架做的事(后来遇上Django后,没太多激情在java的webframework上折腾这些了)。 

Posted in 技术 | Tagged , , | 2 Comments

让R与Python共舞

R(又称R语言)是一款开源的跨平台的数值统计和数值图形化展现工具。通俗点说,R是用来做统计和画图的。R拥有自己的脚本语言和大量的统计、图形库(得益于开源社区),这让她看起来既美又实用。与其他同类软件(如SPSS)相比,R的特点是纯命令行的,这倒也好,我们更应该把注意力放在数据本身,而非统计工具的UI。 R虽说有一套自己的语言,还挺完备,但她最专业的还是做统计和画图,而像连接数据库、文本处理、文件操作等这些脏活可不能委屈R来干哪,这些得有其他语言来负责,我的选择是咱最熟悉的、做这些脏活最棒的Python。那接下来的问题很清楚了,R和Python如何一起工作?拍拍脑袋,想到可能有下面几种办法: 1. R和Python只共享文件,Python把源数据处理干净,生成格式化的文件放在预定的目录下,做个定时器让R去读文件,最终输出统计结果和图表。    这种做法一定程度上可行,除了做定时器外,还可以让Python即时执行”rscript”命令调用R脚本来工作,只是这种办法限制太大,只能够交换文件,Python不能对R进行精确的控制。 2. 让Python直接调用R的函数,R是开源项目,肯定会有一些第三方库实现Python与R互通。    果然,我找到了rpy2,可以实现使用python读取R的对象、调用R的方法以及Python与R数据结构转换等。实际上除了Python,其他语言与R互通的第三方包也大大的有。 最后我选择第2种方法,来让R与Python共舞。 模块 rpy2.robjects 是rpy2对R的一个高级封装,该模块里包含了一个r对象和一系列的R数据结构。使用rpy2的大多数情况,只需要跟这个模块打交道即可。rpy2的安装在此不多讲了,有兴趣的同学看文档去,直接体验一下R如何与Python无缝整合吧。 了解r实例 r实例是指rpy2.robjects.r,它是在Python中的嵌入式R进程,把r当作从python走向R的通道来看就可以了。通过r实例,我们可以读取R的内置变量、调用R的函数、甚至,直接把它当作R的解析器来用。 访问R的对象 在R的命令行中,我们直接输入对象名来访问R的内置对象,如pi、letters: 在R控制台中访问R对象 而使用r实例,python访问R对象也很简单,而且方法很多: 在python中访问R对象 在这段代码中,我们用了三种方式来访问R对象,把r实例当作字典,把r实例当作方法,把r实例当作一个类对象(真是神喻呀~)。在实际中,使用哪一种方式要因习惯而异,我喜欢的方法是使用第三种,把r实例当作自己人,直接使用”.”来访问R对象。但这种方法有一个缺陷,就是不能访问带名字空间的R对象或函数,而其他两种方式是可以的,这点将在随后说明。 调用R函数 通过r实例,我们可以轻易地实现用Python调用R的函数。下面我们分别在R控制台和python命令行下读一个数据文件并画一张点图。 R控制台读取文件画点图 代码解读: data.csv 的内容就是上面代码的3到7的内容。 data = read.table(‘data.csv’) :把文件读进一个数据框变量data中。 mtx = data.matrix(data):把data转变成矩阵。 dotchart(mtx)用矩阵的数据画点图。 结果如下: 接下来用python来做一遍同样的事情,我们之前了解到,使用r实例可以直接访问R对象,还可以直接调用R的函数,其实在Python看来,对象和函数是相同的东西,函数也是一种对象罢了。现在来试一下调用”read.table()”函数读入一个数据文件data.csv: 出错了!怎么回事?在上面我提到过了,使用“.”引用的方式不能访问带有名字空间的R对象和函数,read.table 是表示在read包下面的table函数,通过”.”的形式调用失败,必须要用字典的方式或参数的方式来获得: 这段代码得到的结果与在R控制台下画点图的效果是一样的。最后一行r.dotchart(mtx)是直接通过”.”来调用R的函数dotchart的,在没有名实空间的情况下,是正常的。如果你为了避免太多不可控制的出错机会,你可以统一地使用字典的方式来访问R对象和方法,这是最保险的方法,虽然我个人认为看起来有点别扭。 r实例就是一R控制台 … Continue reading

Posted in 技术, 软件 | Tagged , , | 6 Comments

ubuntu9.10下python访问Sql server的解决方案

在Linux/Unix/Mac下面通过程序来访问M$的Sql Server是一件很折腾的事情,赖总说,linux遇上windows就是杯具啊。最近不幸自己也遇上了,折腾了好一段时间,参考过不下于100+的网页,给过两个老外写邮件,终于还是没有搞定snow leopard上的,但总算搞定了linux上的。 纵观网上的一些参考材料,中文偏少,以赖总一年之前那篇被转载居多,而且大多数语焉不详,只道How,不道Why,当linux发行版本换或软件一升级就套不上了;英文很多,但各有千秋,参考起来也很头大。今天,咱在授人与鱼(如果你的系统配置和我的一样)之余顺便授人与渔,希望自己这次折腾的经验可以给以后需要的同学们带来点方便或启示什么的。 在开始之前,请问一下自己,真的有必要这样折腾吗?现在放弃还来得及,如果点头就继续往下看吧。 其实也没那么恐怖,我自己像个盲头苍蝇乱撞才会踫到一脸灰,如果一开始把原理搞清楚,做起来就快了。 首先,再确定一下我们的目标是:在linux下通过python访问Sql Server!关键字是linux、sqlserver、python。我的系统配置:ubuntu9.10 desktop 64bit、python2.5、SqlServer2005,配置不同的同学在理解原理之余应该也可以自行解决了。  基本原理 一、Linux下应用程序是一般怎样访问数据库的? 目前比较流行的方法是应用程序通过ODBC(Open DataBase Connectivity)来访问数据库。 在ODBC诞生之前,如果要开发数据库应用程序,则必须要使用数据库厂商随数据库产品一同发布的一些工具集来访问数据库,或者在程序中使用嵌入式SQL来访问数据库。当时,对于访问数据库的方法,缺乏一个基于C语言的统一编程接口。ODBC(Open Database Connectivity,开放数据库互连)提供了一种标准的API(应用程序编程接口)方法来访问DBMS(Database Management System)。这些API利用SQL来完成其大部分任务。 见ODBC的架构图,ODBC的驱动管理器自动处理各种数据库驱动与数据源(如各种数据库,甚至Excel)的关系,应用程序只需要使用ODBC的API即可,底层的细节对于应用程序来说是透明的。熟悉Java的同学回想一下JDBC,与ODBC的思路是一个道理,各种数据库有各自对应的JDBC驱动,同时也会有与之对应的ODBC驱动。 那么,要达到linux下应用程序访问数据库的目的,我们需要安装Linux下的ODBC库:unixODBC,目前ODBC在各种操作系统上均有实现,如windows的MS ODBC,还有Mac下的iODBC。 需要注意一点就是,要在Linux下让应用程序访问数据库,使用ODBC不是唯一的方法,只是本解决方案的方法。 二、怎样通过程序访问Sqlsever? 众所周知,程序访问数据库通常需要用到数据库的驱动程序(Database Driver)。Sqlserver(及SyBase)使用TDS(Tabular_Data_Stream)作为它的数据库现客户端传输的协议。关于TDS:  TDS(Tabular_Data_Stream)是一个应用层协议,用于数据库服务器与客户端传递数据,于1984年由Sybase公司发起并开发,用在它们的Sybase Sql Server关系数据库引擎,后来被微软的Sql Server所用。 所以不难理解,SqlServer的Java 驱动包 JTDS,就是TDS的一个Java实现(同时是JDBC的实现)。而For linux,开源社区有一个叫freetds的实现。Linux的程序可以直接通过它来访问SqlServer,是的,可以跳过ODBC。使用ODBC只不过是希望使得更多的方言(不同的编程语言)可以以一致的方式来访问数据库。 三、当Linux遇上SqlServer? unixODBC使得linux上的程序可以以一统一的方式来访问数据源(这里叫以linux的方式),freetds是专为SqlServer而实现的数据库驱动。那么如果我们要以linux的方式去访问SqlServer呢?那就把两者两者连接起来吧!tdsodbc做这个的,在它的帮助下,linux上的应用程序完全可以不用关心freetds,只要以odbc的方式去访问数据源即可。 四、再加一个Python如何? pyodbc是ODBC的一个python封装,它允许任何平台上的python具有使用ODBC API的能力。那意味着,pyodbc是python语言与ODBC的一条桥梁。 … Continue reading

Posted in 技术, 软件 | Tagged , , , | Leave a comment

webfaction上一键部署Django应用

Webfaction是一款聪明体贴的虚拟主机(除了hosting应用外,我每天都拿来Fuck G/F/W),对程序员友好是她的一大卖点。本文以部署Django应用为例,看看Webfaction是如何工作的。 在开始之前,先简单介绍一下Webfaction对网络应用所做的一些定义:域名(Domain)、应用程序(Application)、站点(Site)。 域名(Domain):指常规的域名,一个域名只可以对应一个站点(Site),但一个站点(site)可以绑定N个域名。webfaction同时可提供域名托管服务,只要把域名的NameServer指向webfaction的名字服务器即可,webfaction提供无限多个子域名哦。 应用程序(Application) :应用程序表示一个Web应用,如一个使用Django写的Blog,或是一个php的bbs。应用程序必须成为网站才可以被访问,所以建立完应用后,webfaction并不会马上运行。一个Web应用,可以用于多个站点。 站点(Site) :站点就是网站,可以通过域名表现出来的,如www.fallever.com就是一个站点,iloveu.fallever.com又是一个站点。 其实这些概念的关系很简单, 只是上面可能讲复杂了,看不懂不要紧,继续看就是了。 建立一个Django应用程序 通过https://panel.webfaction.com登录到控制台,点击 “Domains / websites -> Applications”进入应用程序列表。 进入应用程序列表后,在列表的右下角,有个新增应用程序的小图标,点击开始新建一个应用程序。 接下来会来到创建应用程序页面,我们需要填写一个表单,表单有几个项: Name:填入应用的名称,如example。 App type:嘿,这里是魔术发生的地方,webfaction为我们准备了近百种内置应用程序模板,我们创建应用程序所要做的仅仅是选择应用的模板,然后点击创建即可。 App doc:这是对所选择应用类型的说明文档。 Extra Info:附加信息,依所选的应用类型而定。 我们现在要创建一个名叫example的Django应用。那么,我们输入应用名字,接着,点击App type展开应用类型列表。OMG! 当Django就占满了一页!你想要使用任何版本的Django都可以,webfaction提供的Django部署方式有包含但不限两种:Django + mod_wsgi和Django + mod_python。 当然,除了Django以外,webfaction提供大量python和python以外的web应用框架和应用程序,如CherryPy,TurboGear,Rails,PHP,WordPress,Joomla,Durpal,甚至Plone,Zope全系列。除此之外,还可以一键安装Trac,subversion,AWStats等协合工具,源码控制系统和网页统计应用。更重要的是,webfaction不仅能做这些,你自己可以在上面跑列表里面没有的应用,如写一段代码监听端口,或者是跑Java虚拟机!这,正是webfaction吸引我的一个重要原因。 有图有真相: 最后,我选择了使用Django最新版本的代码与mod_python来架设新应用。现在点击Create来创建吧! 千真万确,创建一个Django应用并让它跑起来就那么简单:填个名字,选个模板,点个Create。想起以前在其他主机上面部署个Django应用累得够呛,版本稍有与服务器的不一样的话,麻烦更大。而在webfaction,这一切都不用我担心。 创建一个子域名 应用是建立起来了,怎么样访问呢?那得有个域名!没错。得配个域名。 webfaction会给每一位用户一个二级域名,那就是“用户ID.webfactional.com”,比如我的二级域名就是“jeffjie.webfactional.com”,我们可以在此基础上建立三级域名来访问我们刚才建立的应用。 … Continue reading

Posted in 技术, 软件 | Tagged , , | Leave a comment

给博客增加文章归档功能

博客怎能没有归档功能,长假后的第一个短假,我为自己的博客加上了归档的功能。本来用Django嘛,博客归档使用Generiv View来实现是最简单不过了,不过我这个是多用户博客系统,Generic View在这时没能帮上忙,只有自己动手了。 最终博客归档的效图果如下(左图),参考了blogger的归档风格(右图),可折叠查看博客内所有文章,归档粒度去到月份。    关于TreeView的组件,我开始想用Jquery的官方插件Treeview,但后来弃用了,使用国人的lightTreeview 。原因是Treeview长年不更新,文档少,而lightTreeview更小巧,可订制性强,有详细的使用文档,严重推荐之。 PS。Django的内置Filter真全,今天才知道有一个unordered_list的过滤器,Django想的好周到!尽管我这次没用上。 PS2。Drobox用来做博客图片存储空间很方便。

Posted in 技术 | Tagged , , , | Leave a comment

Django学习笔记之模板

模板是一个文本文件.可以是HTML,XML,CSV甚至其他任意格式的文本. 模板有自己的元素: 一.Variables(变量): 变量的写法是:{{variable}}或{{book.name}},使用”.”来获得对象的属性.与Freemarker等流行模板类似. 二.filters(过滤): 我们可以通过过滤器来改变变量的显示,用法: {{name|lower}}效果是将名字全部变成小写. 过滤器可以联用,只要在后面跟着写上就OK了. 过滤器还可以加参数:{{ bio|truncatewords:30 }},如果Filter的参数带有空格,那个这个参数必须括起来: {{ list|join:”, ” }} 三、tags(标签): 标签看起来是这样的:{% tag %},与Jsp Tag一样,有单一Tag,也有组合Tag,即有开始Tag及结束Tag。 四、Comments(注释): 注释是这样写的{# 这里是注释 #} 五、模板继承: 这是Django模板最强,也是最复杂的部分。利用模板继承机制,你可以创建一个骨架模板,里面包含一些公用内容。而那些个性内容则通过定义block(块)来允许子模板去重载。(像极了Java的类继承!) 块是使用block标签来实现的。下面来看一个例子就完全明白了: 1,这是基础模板,传说中的骨架。命名为base.html <!DOCTYPE html PUBLIC ”-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”> <html xmlns=”http://www.w3.org/1999/xhtml” xml:lang=”en” lang=”en”> <head> <link rel=”stylesheet” href=”style.css” /> <title>{% block title %}My amazing site{% endblock %}</title> </head> <body> <div id=”sidebar”> {% block sidebar %} <ul> <li><a href=”/”>Home</a></li> <li><a href=”/blog/”>Blog</a></li> </ul> {% endblock %} </div> <div id=”content”> {% block content %}{% endblock %} </div> … Continue reading

Posted in 技术 | Tagged , | Leave a comment