跳转到内容

Karrigell/主页

来自维基教科书,为开放世界提供开放书籍

目前,我们将忽略 CD 并开始编写主页

创建一个新文件夹mycds在您的 Karrigell 发行版中,位于www文件夹下。使用您喜欢的文本编辑器,将此文本保存到名为index.ks

def index():
    print "<h1>My CD collection</h1>"

在您的浏览器中,访问localhost/mycds/index.ks/index

扩展名 "ks" (Karrigell 服务) 表示该脚本是 Python 脚本,其中函数与 URL 匹配:这里,index.ks/index表示该函数index()将把数据发送回浏览器

事实上

  • 如果您没有指定函数名,则脚本中的index()函数将被运行,因此您可以访问localhost/mycds/index.ks
  • 而且,如果您在一个文件夹中甚至没有指定脚本名,则名为index的脚本将被运行。所以您实际上只需要输入localhost/mycds

请注意print语句在index()函数中。在 Karrigell 脚本中,print语句将内容发送到浏览器;默认情况下,此内容应该是 HTML 代码

添加页面计数器

[编辑 | 编辑源代码]

页面计数器将打印页面被访问的次数。我们将使用一个文件,counter.txt,来存储访问次数并为每次访问递增。

def index():
    print "<h1>My CD collection</h1>"
    try:
        visits = int(open('counter.txt').read())
    except IOError:
        # first visit : the file does not exist
        visits = 0
    visits += 1
    out = open('counter.txt','w')
    out.write(str(visits))
    out.close()
    print "%s visits" %visits

每次页面重新加载时,您都会看到访问次数增加 1。

请注意,该文件通过通常的open()函数打开;相对路径相对于脚本目录转换为绝对路径。

一个更好的页面计数器

[编辑 | 编辑源代码]

如果同一个用户反复重新加载同一个页面,页面计数器不应递增。这需要一种识别发送请求的浏览器的方法。为了完成此任务,网页编程提供了会话管理,而 Karrigell 对此概念有非常简单的实现。

使用内置的Session()函数

Karrigell 脚本在由框架准备的命名空间中运行:在脚本中可用的名称中,您拥有此Session()函数,它返回特定于每个单个客户端的对象(它使用 cookie)。此对象是一个普通的 Python 对象,您可以为其设置任何您喜欢的属性。

这里,对于新客户端,我们将为会话对象创建一个名为 user 的属性。如果客户端请求主页,并且他的会话对象已经拥有此属性,则计数器将不会递增。

def index():
    print "<h1>My CD collection</h1>"
    try:
        visits = int(open('counter.txt').read())
    except IOError:
        # first visit : the file does not exist
        visits = 0
    if not hasattr(Session(),"user"):
        visits += 1
        out = open('counter.txt','w')
        out.write(str(visits))
        out.close()
        Session().user = None    # create attribute user
    print "%s visits" %visits

包含脚本

[编辑 | 编辑源代码]

此页面计数器可以在应用程序的其他部分使用,因此最好将其放在单独的文件中:将脚本的这一部分保存到counter.py

try:
    visits = int(open('counter.txt').read())
except IOError:
    # first visit : the file does not exist
    visits = 0
    if not hasattr(Session(),"user"):
    visits += 1
    out = open('counter.txt','w')
    out.write(str(visits))
    out.close()
    Session().user = None   # create attribute user
print "%s visits" %visits

中。index.ks要将此脚本包含在主页中,请更改脚本

def index():
    print "<h1>My CD collection>/h1>"
    Include('counter.py')

为以下内容:Include() 是另一个 Karrigell 内置函数:它接受一个脚本 URL 作为参数,并将此脚本执行的结果插入页面。

为了使counter.py更加模块化,文件名可以作为参数传递给为以下内容:

def index():
    print "<h1>My CD collection>/h1>"
    Include('counter.py',counter_file='counter.txt')

为以下内容:的关键字参数将在counter.py运行时位于执行命名空间中。用以下参数改写counter.py

try:
    visits = int(open(counter_file).read())
except IOError:
    # first visit : the file does not exist
    visits = 0
if not hasattr(Session(),"user"):
    visits += 1
    out = open(counter_file,'w')
    out.write(str(visits))
    out.close()
    Session().user = None   # create attribute user
print "%s visits" %visits

登录/退出

[编辑 | 编辑源代码]

让我们添加一个链接供用户登录应用程序。

def index():
    print "<h1>My CD collection</h1>"
    print '<a href="login">Login</a><br>'
    Include('../counter.py',counter_file='counter.txt')

该链接指向引用"login"。它是一个相对于基本 URL 的相对 URL,host/records/index.ks/index,因此它解析为host/records/index.ks/login,这意味着该链接将调用脚本中login()函数的执行。index.ks

此函数将生成一个 HTML 表单,要求用户输入登录名和密码,并将这些值提交给身份验证测试。

def login():
    print '<h1>Login</h1>'
    print '<form action="check_login" method="post">'
    print 'Login <input name="login"><br>'
    print 'Password <input type="password" name="passwd"><br>'
    print '<input type="submit" value="Ok">'
    print '</form>'

表单的属性"action"check_login。同样,这意味着check_login()函数将在index.ks中运行。

index()login()不同,此函数将接受参数:提交的登录名和密码。参数必须与表单的输入字段中使用的名称相同:loginpasswd。目前,我们将使用一个非常简单的测试来查看用户是否被允许登录。

def check_login(login,passwd):
    if login=="john" and passwd=="doe":
        Session().user = login
        print "logged in"
    else:
        print "try again"

在此函数内部,如果测试成功,则会话对象的属性user将设置为用户的登录名。

目前,我们只有测试结果。测试后,我们应该自动返回主页。HTTP 协议提供了重定向功能,而 Karrigell 的实现再次非常简单:一个名为HTTP_REDIRECTION

的内置异常。check_login()将函数更改为以下内容:

def check_login(login,passwd):
    if login=="john" and passwd=="doe":
        Session().user = login
    raise HTTP_REDIRECTION,"index"

这意味着在函数运行后,浏览器将重定向到指定的 URL,这里是指与函数index()函数的执行。

匹配的 URL。

def index():
    print "<h1>My CD collection</h1>"
    logged = hasattr(Session(),"user") and Session().user is not None
    if logged:
        print 'Logged in as %s<br>' %Session().user
        print '<a href="logout">Logout</a><br>'
    else:
        print '<a href="login">Login</a><br>'
    Include('../counter.py',counter_file='counter.txt')

我们现在可以更改主页,以使用用户的姓名欢迎经过身份验证的用户,并允许他注销。注销函数将只设置Session().userNone

def logout():
    del Session().user
    raise HTTP_REDIRECTION,"index"

并重定向到主页。

总结

[编辑 | 编辑源代码]Session()Karrigell 使用的编程风格基于命名空间:在脚本中,不导入模块或使用环境变量,而是提供了一些内置名称供最常见的任务使用。到目前为止,我们已经涵盖了使用内置名称为以下内容:的会话管理,使用HTTP_REDIRECTION

包含脚本,以及使用内置异常

进行 HTTP 重定向。这使得使用 Karrigell 进行编程非常简单,因此易于编码和维护。

虽然有其他格式可用(有关纯 Python 脚本、CGI、Python Inside HTML、HTML Inside Python 的文档,请参阅文档),但我建议使用 "Karrigell 服务" 将大部分应用程序逻辑组合在一个脚本中;外围模块可以被导入或包含。

下一节中,我们将编写用于管理 CD 数据库的代码。
华夏公益教科书