天天看點

dancer cookbook 小議1

Dancer::Cookbook - a quick-start guide to the Dancer web framework

DESCRIPTION

A quick-start guide with examples to get you up and running with the Dancer web framework.

BEGINNER'S DANCE

Your first Dancer web app

Dancer has been designed to be easy to work with - it's trivial to write a simple web app, but still has the power to work with larger projects. To start with, let's make an incredibly simple "Hello World" example:

#!/usr/bin/perl

use Dancer; 

get '/hello/:name' => sub {

    return "Why, hello there " . params->{name};

}; 

dance; 

Yes - the above is a fully-functioning web app; running that script will launch a webserver listening on the default port (3000); now you can make a request

# curl http://localhost:3000/hello/Bob

Why, hello there Bob 

在dancer -- introduction文章中提及到"params"的功能是讓路由行為中的函數來通路傳遞給函數的參數。并且"params"傳回的是一個hashref,然後在code段中對hashref中的name元素進行了解引用,通路其值,于是就得到了你輸入的那個參數。

當然,參數也可以是空,如果是空,為了能給出更加明确的資訊,我們可以使用dancer--introduction中講解到的"标志(參數)可選性"來解決該問題,如使用dancer --introduction中的例子:

get '/hello/:name?' => sub {

    "Why, hello there " . (params->{name} || "whoever you are!");

# curl http://localhost:3000/hello/

Why, hello there whoever you are!

當通路時,有無參數的傳回結果是不一樣的。

(or the name of the machine you ran it on, if it's not your local system), and it will say hello. The :name part is a named parameter within the route specification, whose value is made available through params - more on that later.

Note that you don't need to use the strict and warnings pragma, they are already loaded by Dancer. (If you don't want the warnings pragma (which can lead to undesired warnings about use of undef values, for example), then set the import_warnings setting to a false value.

在dancer --introduction中也提到了當使用dancer的時候,自動引入了warnings和strict指令,但是如果你想取消warnings指令(比如:防止在使用一個未定義的變量而出現不希望的看到警告資訊時,你可以參考Dancer::Config中的介紹通過設定import_warnings:false來禁用warnings指令)。

Starting a Dancer project

The first simple example is fine for trivial projects, but for anything more complex, you'll want a more maintainable solution - enter the dancer helper script, which will build the framework of your application with a single command:

# dancer -a mywebapp

+ mywebapp

+ mywebapp/config.yml+ mywebapp/environments

+ mywebapp/environments/development.yml

+ mywebapp/environments/production.yml

+ mywebapp/views+ mywebapp/views/index.tt

+ mywebapp/views/layouts

+ mywebapp/views/layouts/main.tt

+ mywebapp/mywebapp.pl+ mywebapp/lib

+ mywebapp/lib/mywebapp.pm

+ mywebapp/public+ mywebapp/public/css

+ mywebapp/public/css/style.css

+ mywebapp/public/css/error.css

+ mywebapp/public/p_w_picpaths

+ mywebapp/public/404.html

+ mywebapp/public/dispatch.fcgi

+ mywebapp/public/dispatch.cgi

+ mywebapp/public/500.html

+ mywebapp/Makefile.PL+ mywebapp/t

+ mywebapp/t/002_index_route.t

+ mywebapp/t/001_base.t 

As you can see, it creates a directory named after the name of the app, along with a configuration file, a views directory (where your templates and layouts will live), an environments directory (where environment-specific settings live), a module containing the actual guts of your application, a script to start it - or to run your web app via Plack/PSGI - more on that later.

DANCE ROUTINES: ROUTES

Declaring routes------>聲明路由

To control what happens when a web request is received by your webapp, you'll need to declare routes. A route declaration indicates which HTTP method(s) it is valid for, the path it matches (e.g. /foo/bar), and a coderef to execute, which returns the response。

當有請求通路你的webapp時,為了能控制你webapp的響應,你需要聲明一些路由,一個路由聲明暗示了什麼樣的HTTP 方式時有效的,該HTTP 請求能比對webapp路由中的哪一條,然後哪個相應的代碼引用會被執行,最後會傳回什麼樣的響應。

    return "Hi there " . params->{name};

The above route specifies that, for GET requests to '/hello/...', the code block provided should be executed.

上述路由執行處理到/hello/下的GET HTTP方法,其餘的HTTP 方式不能觸發該路由。

Handling multiple HTTP request methods------->處理複合的HTTP請求方法

Routes can use any to match all, or a specified list of HTTP methods.

在路由行為中可使用關鍵字any來比對所有的HTTP 方法或者比對指定的多個HTTP方法。

The following will match any HTTP request to the path /myaction:

any '/myaction' => sub {

    # code

上述代碼比對了目的地是/myaction的所有的HTTP方法的路由。

The following will match GET or POST requests to /myaction:

any ['get', 'post'] => '/myaction' => sub {

上述方法比對了目的地是/myaction的GET/POST HTTP方法。

For convenience, any route which matches GET requests will also match HEAD requests.

為了友善,任何一條比對GET請求的路由都會比對HEAD請求(即,對于相應的HEAD 請求也是通過該路由來執行的)。每條比對GET請求的路由都會去比對HEAD請求,該操作是dancer自動完成的,為什麼非得去比對HEAD請求,然後再去執行GET請求,是與HTTP協定相關。

Retrieving request parameters-------->檢索請求參數

The params keyword returns a hashref of request parameters; these will be parameters supplied on the query string, within the path itself (with named placeholders), and, for HTTP POST requests, the content of the POST body.

關鍵字"params"傳回請求參數的一個hashref,這些參數由請求字元串中提供,包含在named占位符中,對于HTTP POST請求,傳回的内容是POST的本身。

Named parameters in route path declarations-------->路由路徑中的命名參數的聲明

As seen above, you can use :somename in a route's path to capture part of the path; this will become available by calling params.

So, for a web app where you want to display information on a company, you might use something like:

通過上面的例子我們能夠了解到我們可以使用use :somename來捕捉路由路徑的一部分,然後捕捉到的内容有params來操作。

get '/company/view/:companyid' => sub {

    my $company_id = params->{companyid};

    # Look up the company and return appropriate page

Wildcard path matching and splat-------->通配符路徑比對和splat關鍵

You can also declare wildcards in a path, and retrieve the values they matched with the splat keyword:

在dancer --introduction中提及到在路由路徑中使用通配符,對于通配符比對的資料被傳回到一個arrayref中,然後後續使用splat來操作該arrayref。

get '/*/*' => sub {

    my ($action, $id) = splat;

    if (my $action eq 'view') {

return display_item($id);

} elsif ($action eq 'delete') {

return delete_item($id);    

} else {

status 'not_found'; 

return "What?";    

}

Before hooks - processed before a request------>前過濾(在處理請求前執行)

A before hook declares code which should be handled before a request is passed to the appropriate route.

繼續閱讀