Karrigell 中文版官方文档 P03

8. Python scripts 

在Karrigell中运行Python脚本是非常简单的。打开我们喜欢的Python代码编辑器创建下面的脚本:

print "Hello Karrigell !"
然后把它保存在Root Directory下面的hello.py里。然后访问http://localhost/hello.py,我们就可以在浏览器里看到信息
Python脚本在Karrigell里是以普通的脚本方式运行的,它接受print语句发送数据到客户端浏览器而不是控制台窗口。
因此我们需要以适当的格式书写HTML代码;一个简单的表格我们可以这样写:
print "<TABLE>"
print "<TR>"
print "<TD>Name</TD>"
print "<TD>Address</TD>"
print "</TR>"
print "</TABLE>"
或者使用Python多行语法:
print """<TABLE>
      <TR>
        <TD>Name</TD>
        <TD>Address</TD>
      </TR>
    </TABLE>"""
或者我们使用HTMLTags模块:
from HTMLTags import *
print TABLE(TR(TD("Name")+TD("Address")))
如果我们不想把脚本在karrigell里运行我们可以在脚本的最顶端包含这段代码:
try:
    SCRIPT_END
except NameError:
    pass
else:
    print "This script can't be executed by Karrigell"
    raise SCRIPT_END
   
(... rest of your script here ...)
如果SCRIPT_END在Python脚本的运行名字空间里那就是运行在Karrigell里,在这个情况下就会结束执行;如果从命令行执行就会触发NameError异常并且会忽略异常处理的脚本

9. CGI scripts

New in version 2.3.1

如果我们要在另一个环境上开发CGI脚本,我们可以不经过修改就能运行在Karrigell上。

提醒:在Karrigell 2.3.1里CGI脚本只能运行在异步服务器里,将会在以后添加其它服务器的支持

我们需要把CGI脚本放在一个特定的目录里。默认的是webapps/cgi-bin目录, 我们也可以设置配置文件里Directories下的cgi选项来指定其它的路径  

10. Karrigell Services 

10.1 Syntax

"Karrigell Services"也是一种Python脚本它可以处理一些URL,因此由不同的HTML页面组成的一个完整的服务可以创建在一个脚本文件里。

为了达到这样的目的,在Karrigell Service中的一个函数就映射着一个URL:在脚本dump.ks中的函数foo()可以调用dummy.ks/foo。

要调用方法foo(arg1,arg2),URL必须要像这样dummy.ks/foo?arg1=val1&arg2=val2或者通过一个带有字段arg1和arg2的表单来调用。

如果函数没有被指定,Karrigell会查找一个不带参数的index()函数。

为了安全和可读性的理由,函数只能清楚的定义在ks脚本里,并且它的定义在源代码中要以第一列开始才能够被调用。

如果我们需要在脚本里定义一个函数但又不想它通过一个url来被调用,可以在函数名字前加上一个下划线。

def _private(value):
   """Private function - can't be called from the outside"""
   return value+1

为了从一个函数跳转到另外一个函数,可以为一个链接或一个表单的action属性指定一个函数名:

def index():
   print '<a href="foo?name=bar">go to foo</a>'
def foo(name):
   print '<IMG SRC="../picture.jpg">'
   print name

注意foo()函数的第一行:因为这个URL决定的这个方法与文件或脚本相关连的URL同ks脚本是在同一个目录下,所以必须加上前缀"../"。
所有的HTTP环境变量,表单字段,自定义异常,身份认证函数,session控制等都在Python脚本中以相同的方式处于理。
下面是一个简单的Karrigell Service例子:
so = Session()
if not hasattr(so, 'x'):
    so.x = 0
def index():
    print "x = %s" %so.x
    print '<br><a href="increment">Increment</a>'
    print '<br><a href="decrement">Decrement</a>'
    print '<br><a href="reset">Reset</a>'
   
def increment():
    so.x = _private(so.x)
    raise HTTP_REDIRECTION,"index"
def decrement():
    so.x -= 1
    raise HTTP_REDIRECTION,"index"
def reset():
    so.x = 0
    raise HTTP_REDIRECTION,"index"
def _private(x):
    """The function name begins with _ : internal function,
    can't be call by a url"""
    return x+1
10.2 Smart urls
在访问Karrigell Services时url上带有附加的参数有的时候是非常有用的。例如,地址htpp://path/service.ks/function/foo/bar?name=smith 
将会使用'foo'和'bar'作为参数来调用function.
它们可以在脚本中调用THIS的subpath属性。在下面的例子中将会列出['foo','bar']
def function(name):
   print 'subpath ',THIS.subpath
   print name
"smart urls"的一个问题是当我们要写一个链接或使用Include()或重定向到一个相关的url,我们就需要给出一个正确的url,
是的,要预先考虑好在目标url前有几个'../'。
有几个'../'可以由subpath属性的长度来决定,如果我们想在下面的一个函数里写一个链接就需要这样写:
 def function(name):
   print 'subpath ',THIS.subpath
   print name
   print '<a href=%slogin>Login</a>' %('../'*len(THIS.subpath))
或者使用THIS的up属性:
def function(name):
   print 'subpath ',THIS.subpath
   print name
   print '<a href=%slogin>Login</a>' %THIS.up
 

11. Python Inside HTML

Python Inside HTML很像微软的ASP及Sun的JSP和PHP;它们基本上是HTML文档,使用编程语言在其中插入部分代码,当然了在这里指的是Python。

在Python Inside HTML中,HTML代码使用特殊的标签<%和%>来分开Python代码。

假设我们想显示当前日期,我们将像这样混合Python和HTML代码:

The current date is
<% import time
print time.strftime("%d:%m:%y",time.localtime(time.time()))
%>

使用文本编辑器,输入上面的代码并且把它保存到Root Directory下的time.pih里。在浏览中输入http://localhost/time.pih然后看发生了什么。

我们会注意到在<%和%>中的代码是普通的Python代码,在其中我们可以导入模块,创建和实例化类,使用变量,读写文件系统等。可以像在Python脚本中一样访问HTTP变量,表单字段,及Karrigell定义的异常。

11.1 Python variables

当我们只需要打印变量的值时,可以使用<%=var%>来代替<%print var%>:

Current directory <%= os.getcwd() %>

在这个例子中我们会注意到我们不需要显示地导入os模块:为了方便,在我们执行这个脚本的时候它已经在当前名字空间里了。还有string和Cookie模块也被导入了,因为它们可能会被大多数的脚本使用(当然,如果我们显式的使用import string我们的脚本也会正常的工作).。

11.2 Strings for translation

一直以来在Karrigell中国际化都是非常重要的部分,当我们想根据用户的参数选择来翻译字符串时可以使用<%_string%>

  <% import time %>
  <%_ "Current directory is " %> <%= os.getcwd() %>
  <%_ "Current day " %> <%_ time.strftime("%a",time.localtime()) %>

如果我们已经为字符串Current directory is准备好了译文,当用户调用这个脚本时并且它的语言选择的是法语,那么他的浏览器将会显示Le répertoire courant est。

参见Karrigell support for internationalization

11.3 Indentation

因为PIH文件里有Python代码的导致这些代码必须缩进。因为PIH脚本混合了HTML,为了更好的可读性并且把Python代码分块所以要使用缩进,使用恰当的缩进可以使提取代码与可读性变得不是很困难。

11.3.1 Basics

Python Inside HTML遵循以下简单的规则:

  • 在脚本的开始处缩进为0
  • 每一部分的缩进都要根据当前缩排
  • 当前缩排可以两种意思:
    1. 当Python代码以冒号结束时,下一行的缩进将自增1
    2. 为了结束缩排要使用<%end%>

一个简单的条件例子:

 
# indentation
<% if hour<12: %>
    Good morning
    <% end>
<% elif hour<18: %>
    Good afternoon
    <% end>
<% else: %>
    Good evening
<% end>
 Ladies and Gentlemen
# 0 - next one : 1
# 1
# 1 - next one : 0
# 0 - next one : 1
# 1
# 1 - next one : 0
# 0 - next one : 1
# 1
# 1 - next one : 0
# 0

一个for循环的例子:

 
# indentation
<table border=1>
  <tr>
    <th>Number</th>
    <th>Square</th>
  </tr>
  <% for i in range(10): %>
    <tr>
      <td><% print i %></td>
      <td><% print i**2 %></td>
    </tr>
  <% end %>
</table>
# 0
# 0
# 0
# 0
# 0
# 0 - next one : 1
# 1
# 1
# 1
# 1
# 1 - next one 0
# 0

如果没有<%end%>标签,</table>标签将会被插入到当前循环中

最后一个是有两个级别缩排的例子:

 
# indentation
<% for i in range(10): %>
    <% if i % 2: %>
        <td class="odd"><%= i %></td>
        <% end %>
    <% else: %>
        <td class="even"><%= i %></td>
        <% end %>
    <% end %>
End of table
# 0 - next one : 1
# 1 - next one : 2
# 2
# 2 - next one : 1
# 1 - next one : 2
# 2
# 2 - next one : 1
# 1 - next one : 0
# 0

 注意在第一行必须使用%>关闭标签,否则在第二行时缩排仍是1。

11.3.3 The <indent> tag

在比较长的或更复杂的代码中重复使用<%end%>将会使代码变得冗长。如果想让PIH中的一些代码像在Python中一样缩进的话,可以嵌入<indent>标签。

第一个例子:

 
# indentation
<indent>
<% if hour<12: %>
    Good morning
<% elif hour<18: %>
    Good afternoon
<% else: %>
    Good evening
Ladies and Gentlemen
</indent>
# 0
# 0
# 1
# 0
# 1
# 0
# 1
# 0
 

 第二个例子:

 
# indentation
<table border=1>
  <tr>
    <th>Number</th>
    <th>Square</th>
  </tr>
  <indent>
  <% for i in range(10): %>
    <tr>
    <td><% print i %></td>
    <td><% print i**2 %></td>
    </tr>
  </indent>
</table>
# 0
# 0
# 0
# 0
# 0
# 0
# 0 (A)
# 1
# 1
# 1
# 1
# next one : 0
# 0

在注意事项(A)那一行上面我们看到了使用了<indent>标签来表示开始缩排

我们也注意到了在缩进部分结束的时候缩排返回了0

这是一个嵌套循环的例子:

<indent>
<table border=1>
<% for i in ['h']+range(10): %>
    <tr>
    <% for j in ['h']+range(10): %>
        <% if i!='h' and j!='h': %>
            <td><%= i*j %></td>
        <% elif i!='h': %>
            <th><%= i %></th>
        <% elif j!='h': %>
            <th><%= j %></th>
        <% else: %>
            <td>*</td>
    </tr>
</table>
</indent>

11.4 PIH as a templating system

PIH脚本可以在Karrigell server外用于创建HTML文件,把它当作"模板系统"。

例如,下面的这个HTML文档是一个PIH脚本。chapter号码不是固定的但是可以像这样插入到HTML中:

<h1><%= chapter %>. Python Inside HTML</h1>

为了从一个PIH脚本中处理HTML,可以使用Template模块,可以使用getScript(fileName)函数创建一个脚本的实例,然后应用它的render(nameSpace)方法,传递当前名字空间(通常是globals()或locals())它将会发现需要的变量。render方法返回一个Output实例,它的value属性就是返回的HTML结果:

import Template
pihIn=Template.getScript("pythoninsidehtml.pih")
chapter=5
htmlOutput=pihIn.render(globals()).value

11.5 Debugging

为了调试可以启动PIHapp.py脚本。这是一个小型的GUI应用程序它展示PIH文件如何转换成Python脚本。结果可以被保存成一个HTML文件并且显示在浏览器上,如果没有使用变量调用它的语法是高亮显示的。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值