# SOME DESCRIPTIVE TITLE.
# Copyright (C) 2009-2012, Marcel Hellkamp
# This file is distributed under the same license as the Bottle package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
msgid ""
msgstr ""
"Project-Id-Version: Bottle 0.12-dev\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-08-09 18:12\n"
"PO-Revision-Date: 2013-08-09 17:27+0800\n"
"Last-Translator: \n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Poedit 1.5.7\n"

# 2cfce930fec043468539792502c72326
#: ../../tutorial.rst:24
msgid "Tutorial"
msgstr "教程"

# 0c236f89c90b4a3a9a21281e710524c0
#: ../../tutorial.rst:26
msgid ""
"This tutorial introduces you to the concepts and features of the Bottle web "
"framework and covers basic and advanced topics alike. You can read it from "
"start to end, or use it as a reference later on. The automatically "
"generated :doc:`api` may be interesting for you, too. It covers more "
"details, but explains less than this tutorial. Solutions for the most common "
"questions can be found in our :doc:`recipes` collection or on the :doc:`faq` "
"page. If you need any help, join our `mailing list <mailto:"
"bottlepy@googlegroups.com>`_ or visit us in our `IRC channel <http://webchat."
"freenode.net/?channels=bottlepy>`_."
msgstr ""
"这份教程将向你介绍Bottle的开发理念和功能特性。既介绍Bottle的基本用法，也包含"
"了进阶用法。你可以从头到尾通读一遍，也可当做开发时的参考。你也许对自动生成"
"的 :doc:`api` 感兴趣。它包含了更多的细节，但解释没有这份教程详细。在 :doc:"
"`recipes` 或 :doc:`faq` 可找到常见问题的解决办法。如果需要任何帮助，可加入我"
"们的 `邮件列表 <mailto:bottlepy@googlegroups.com>`_ 或在 `IRC频道 <http://"
"webchat.freenode.net/?channels=bottlepy>`_ 和我们交流。"

# 0ec6fe51620140ad9382936c9de05314
#: ../../tutorial.rst:31
msgid "Installation"
msgstr "安装"

# 568892e9dee44a7e9037426bf4d0aee0
#: ../../tutorial.rst:33
msgid ""
"Bottle does not depend on any external libraries. You can just download "
"`bottle.py </bottle.py>`_ into your project directory and start coding:"
msgstr ""
"Bottle不依赖其他库，你需要做的仅是下载 `bottle.py </bottle.py>`_ (开发版)到你"
"的项目文件夹，然后开始写代码。"

# 00ba13db53314514a6c6f6af77210c46
#: ../../tutorial.rst:39
msgid ""
"This will get you the latest development snapshot that includes all the new "
"features. If you prefer a more stable environment, you should stick with the "
"stable releases. These are available on `PyPI <http://pypi.python.org/pypi/"
"bottle>`_ and can be installed via :command:`pip` (recommended), :command:"
"`easy_install` or your package manager:"
msgstr ""
"在终端运行以上命令，即可下载到Bottle的最新开发版，包含了所有新功能特性。如果"
"更需要稳定性，你应该坚持使用Bottle的稳定版本。可在 `PyPI <http://pypi.python."
"org/pypi/bottle>`_ 下载稳定版本，然后通过 :command:`pip` (推荐), :command:"
"`easy_install` 或你的包管理软件安装。"

# b99a73f45a24406dbde64204f2ceb385
#: ../../tutorial.rst:47
msgid ""
"Either way, you'll need Python 2.5 or newer (including 3.x) to run bottle "
"applications. If you do not have permissions to install packages system-wide "
"or simply don't want to, create a `virtualenv <http://pypi.python.org/pypi/"
"virtualenv>`_ first:"
msgstr ""
"你需要Python 2.5或以上版本（包括3.x）来运行bottle应用。如果你没有管理员权限或"
"你不想将Bottle安装为整个系统范围内可用，可先创建一个 `virtualenv <http://"
"pypi.python.org/pypi/virtualenv>`_ :"

# 36a9cfdae7c3425ea112e9b4f4340db3
#: ../../tutorial.rst:55
msgid "Or, if virtualenv is not installed on your system:"
msgstr "如果还未安装virtualenv:"

# 28ef5dd33f0f42da9dcbb4b808ff8ef6
#: ../../tutorial.rst:67
msgid "Quickstart: \"Hello World\""
msgstr ""

# 63ae84f2a3ec45ae994f1ad1fd3dca8b
#: ../../tutorial.rst:69
msgid ""
"This tutorial assumes you have Bottle either :ref:`installed <installation>` "
"or copied into your project directory. Let's start with a very basic \"Hello "
"World\" example::"
msgstr ""
"到目前为止，我假设你已经 :ref:`安装 <installation>` 好了bottle或已将bottle.py"
"拷贝到你的项目文件夹。接下来我们就可以写一个非常简单的\"Hello World\"了::"

# 56a3e1b859df44d8838a1f879dc6edef
#: ../../tutorial.rst:79
msgid ""
"This is it. Run this script, visit http://localhost:8080/hello and you will "
"see \"Hello World!\" in your browser. Here is how it works:"
msgstr ""
"就这么简单！保存为py文件并执行，用浏览器访问 http://localhost:8080/hello 就可"
"以看到\"Hello World!\"。它的执行流程大致如下:"

# 9de9930646be4df7ab8a12f9759574db
#: ../../tutorial.rst:81
msgid ""
"The :func:`route` decorator binds a piece of code to an URL path. In this "
"case, we link the ``/hello`` path to the ``hello()`` function. This is "
"called a `route` (hence the decorator name) and is the most important "
"concept of this framework. You can define as many routes as you want. "
"Whenever a browser requests an URL, the associated function is called and "
"the return value is sent back to the browser. Its as simple as that."
msgstr ""
":func:`route` 函数将一段代码绑定到一个URL，在这个例子中, 我们将 ``hello()`` "
"函数绑定给了 ``/hello`` 。我们称之为 `route` (也是该修饰器的函数名) ，这是"
"Bottle框架最重要的开发理念。你可以根据需要定义任意多的 `route` 。在浏览器请求"
"一个URL的时候，框架自动调用与之相应的函数，接着将函数的返回值发送给浏览器。就"
"这么简单！"

# 66de45a278fd457e9f68b2847b841118
#: ../../tutorial.rst:83
msgid ""
"The :func:`run` call in the last line starts a built-in development server. "
"It runs on ``localhost`` port ``8080`` and serves requests until you hit :"
"kbd:`Control-c`. You can switch the server backend later, but for now a "
"development server is all we need. It requires no setup at all and is an "
"incredibly painless way to get your application up and running for local "
"tests."
msgstr ""
"最后一行调用的 :func:`run` 函数启动了内置的开发服务器。它监听 `localhost` 的"
"8080端口并响应请求， :kbd:`Control-c` 可将其关闭。到目前为止，这个内置的开发"
"服务器已经足够用于日常的开发测试了。它根本不需要安装，就可以让你的应用跑起"
"来。在教程的后面，你将学会如何让你的应用跑在其他服务器上面（译者注：内置服务"
"器不能满足生产环境的要求）"

# 58b30c8abcee451e80f9fc3d0b79d180
#: ../../tutorial.rst:85
msgid ""
"The :ref:`tutorial-debugging` is very helpful during early development, but "
"should be switched off for public applications. Keep that in mind."
msgstr ""
":ref:`tutorial-debugging` 在早期开发的时候非常有用，但请务必记得，在生产环境"
"中将其关闭。"

# 717a9032a00a46b8b4845025571cafb4
#: ../../tutorial.rst:87
msgid ""
"Of course this is a very simple example, but it shows the basic concept of "
"how applications are built with Bottle. Continue reading and you'll see what "
"else is possible."
msgstr ""
"毫无疑问，这是一个十分简单例子，但它展示了用Bottle做应用开发的基本理念。接下"
"来你将了解到其他开发方式。"

# 7c5ad76ca2ab4a3fbf06a891d59fc47b
#: ../../tutorial.rst:92
msgid "The Default Application"
msgstr "`默认应用`"

# ec04f7c314a04d51a1f5a5d7fa1585d0
#: ../../tutorial.rst:94
msgid ""
"For the sake of simplicity, most examples in this tutorial use a module-"
"level :func:`route` decorator to define routes. This adds routes to a global "
"\"default application\", an instance of :class:`Bottle` that is "
"automatically created the first time you call :func:`route`. Several other "
"module-level decorators and functions relate to this default application, "
"but if you prefer a more object oriented approach and don't mind the extra "
"typing, you can create a separate application object and use that instead of "
"the global one::"
msgstr ""
"基于简单性考虑，这份教程中的大部分例子都使用一个模块层面的 :func:`route` 修饰"
"器函数来定义route。这样的话，所有route都添加到了一个全局的“默认应用”里面，即"
"是在第一次调用 :func:`route` 函数时，创建的一个 :class:`Bottle` 类的实例。其"
"他几个模块层面的修饰器函数都与这个“默认应用”有关，如果你偏向于面向对象的做法"
"且不介意多打点字，你可以创建一个独立的应用对象，这样就可避免使用全局范围的“默"
"认应用”。"

# b3de36e15f504e4099b98ad3421a8a3d
#: ../../tutorial.rst:106
msgid ""
"The object-oriented approach is further described in the :ref:`default-app` "
"section. Just keep in mind that you have a choice."
msgstr ""
"接下来的 :ref:`default-app` 章节中将更详细地介绍这种做法。现在，你只需知道不"
"止有一种选择就好了。"

# 3c4ef0c7652d427db62949755a6c40b3
#: ../../tutorial.rst:114
msgid "Request Routing"
msgstr "URL映射"

# def96408b0aa4043965308a19be3984c
#: ../../tutorial.rst:116
msgid ""
"In the last chapter we built a very simple web application with only a "
"single route. Here is the routing part of the \"Hello World\" example again::"
msgstr ""
"在上一章中，我们实现了一个十分简单的web应用，只有一个URL映射(route)。让我们再"
"来看一下“Hello World”中与routing有关的部分::"

# 349b072faacd4906b20c28de17c17b2c
#: ../../tutorial.rst:122
msgid ""
"The :func:`route` decorator links an URL path to a callback function, and "
"adds a new route to the :ref:`default application <tutorial-default>`. An "
"application with just one route is kind of boring, though. Let's add some "
"more::"
msgstr ""
":func:`route` 函数将一个URL路径与一个回调函数关联了起来，然后在 :ref:"
"`default application <tutorial-default>` 中添加了一个URL映射(route)。但只有一"
"个route的应用未免太无聊了，让我们试着再添加几个route吧。::"

# e0fcfc8632d74f1c829909f7ec493047
#: ../../tutorial.rst:129
msgid ""
"This example demonstrates two things: You can bind more than one route to a "
"single callback, and you can add wildcards to URLs and access them via "
"keyword arguments."
msgstr ""
"这个例子说明了两件事情，一个回调函数可绑定多个route，你也可以在URL中添加通配"
"符，然后在回调函数中使用它们。"

# dabaff12e29b40abbd26c784abd18696
#: ../../tutorial.rst:136
msgid "Dynamic Routes"
msgstr "动态URL映射"

# 988f03163d7b4112863628e580d3ec24
#: ../../tutorial.rst:138
msgid ""
"Routes that contain wildcards are called `dynamic routes` (as opposed to "
"`static routes`) and match more than one URL at the same time. A simple "
"wildcard consists of a name enclosed in angle brackets (e.g. ``<name>``) and "
"accepts one or more characters up to the next slash (``/``). For example, "
"the route ``/hello/<name>`` accepts requests for ``/hello/alice`` as well as "
"``/hello/bob``, but not for ``/hello``, ``/hello/`` or ``/hello/mr/smith``."
msgstr ""
"包含通配符的route，我们称之为动态route(与之对应的是静态route)，它能匹配多个"
"URL地址。一个通配符包含在一对尖括号里面(像这样 ``<name>`` )，通配符之间用\"/"
"\"分隔开来。如果我们将URL定义为 ``/hello/<name>`` 这样，那么它就能匹配 ``/"
"hello/alice`` 和 ``/hello/bob`` 这样的浏览器请求，但不能匹配 ``/hello`` , ``/"
"hello/`` 和 ``/hello/mr/smith`` 。"

# 3d1bccff797843218d755217b1a64025
#: ../../tutorial.rst:140
msgid ""
"Each wildcard passes the covered part of the URL as a keyword argument to "
"the request callback. You can use them right away and implement RESTful, "
"nice-looking and meaningful URLs with ease. Here are some other examples "
"along with the URLs they'd match::"
msgstr ""
"URL中的通配符都会当作参数传给回调函数，直接在回调函数中使用。这样可以漂亮地实"
"现RESTful形式的URL。例子如下::"

# 39b80f89f2e24b88a48f4fde1f066d5f
#: ../../tutorial.rst:152
msgid ""
"Filters are used to define more specific wildcards, and/or transform the "
"covered part of the URL before it is passed to the callback. A filtered "
"wildcard is declared as ``<name:filter>`` or ``<name:filter:config>``. The "
"syntax for the optional config part depends on the filter used."
msgstr ""
"过滤器(Filter)可被用来定义特殊类型的通配符，在传通配符给回调函数之前，先自动"
"转换通配符类型。包含过滤器的通配符定义一般像 ``<name:filter>`` 或 ``<name:"
"filter:config>`` 这样。config部分是可选的，其语法由你使用的过滤器决定。"

# f0f981dd9d6c485c88ceffbb7145caab
#: ../../tutorial.rst:154
msgid "The following filters are implemented by default and more may be added:"
msgstr "已实现下面几种形式的过滤器，后续可能会继续添加:"

# ea5726150090430fb51657407ba183c3
#: ../../tutorial.rst:156
msgid ""
"**:int** matches (signed) digits only and converts the value to integer."
msgstr "**:int** 匹配一个数字，自动将其转换为int类型。"

# d6b0d5f1a9c241a6b29dec4e65e890d6
#: ../../tutorial.rst:157
msgid "**:float** similar to :int but for decimal numbers."
msgstr "**:float** 与:int类似，用于浮点数。"

# b6a7efae1777408299795041cd226806
#: ../../tutorial.rst:158
msgid ""
"**:path** matches all characters including the slash character in a non-"
"greedy way and can be used to match more than one path segment."
msgstr "**:path** 匹配一个路径(包含\"/\")"

# e84964d6d43f4fe1afae7ba6bc7032a0
#: ../../tutorial.rst:159
msgid ""
"**:re** allows you to specify a custom regular expression in the config "
"field. The matched value is not modified."
msgstr "**:re** 匹配config部分的一个正则表达式，不更改被匹配到的值"

# 69650355e34d4716a450d9f712b88fd8
#: ../../tutorial.rst:161
msgid "Let's have a look at some practical examples::"
msgstr "让我们来看看具体的使用例子::"

# f2d03c373c8a4ada93e344985fb6cee7
#: ../../tutorial.rst:175
msgid "You can add your own filters as well. See :doc:`Routing` for details."
msgstr "你可以添加自己的过滤器。详见 :doc:`routing` 。"

# ce116c2df52344fc8ef6ab0dc85198fd
#: ../../tutorial.rst:179
msgid ""
"The new rule syntax was introduced in **Bottle 0.10** to simplify some "
"common use cases, but the old syntax still works and you can find a lot of "
"code examples still using it. The differences are best described by example:"
msgstr ""
"从 **Bottle 0.10** 版本开始，可以用新的语法来在URL中定义通配符，更简单了。新"
"旧语法之间的对比如下:"

# 4f170d5d120f4cb0a5576bcc352b6e81
#: ../../tutorial.rst:182
msgid "Old Syntax"
msgstr "旧语法"

# d98e5579e3c7481aacf83ee066cfa826
#: ../../tutorial.rst:182
msgid "New Syntax"
msgstr "新语法"

# 3ef58345079544b8a954099b097d5583
#: ../../tutorial.rst:184
msgid "``:name``"
msgstr ""

# ca2dfc00260445eba77bacd64e89f4e2
#: ../../tutorial.rst:184
msgid "``<name>``"
msgstr ""

# 24034e67d3194c6ea694d522ff118743
#: ../../tutorial.rst:185
msgid "``:name#regexp#``"
msgstr ""

# 9b40ae713f9a4c2182ab7666bd77e4fe
#: ../../tutorial.rst:185
msgid "``<name:re:regexp>``"
msgstr ""

# 47f26059d42b48ae8372c47a9c1cff3c
#: ../../tutorial.rst:186
msgid "``:#regexp#``"
msgstr ""

# 831629c77fb5421e8857371ed9b28751
#: ../../tutorial.rst:186
msgid "``<:re:regexp>``"
msgstr ""

# 2c0f1748c68a42829971f32f109f95a9
#: ../../tutorial.rst:187
msgid "``:##``"
msgstr ""

# 1191242878fd4759988a1717eeaa8d4f
#: ../../tutorial.rst:187
msgid "``<:re>``"
msgstr ""

# d866a2106ce5412795d39e31231da875
#: ../../tutorial.rst:190
msgid ""
"Try to avoid the old syntax in future projects if you can. It is not "
"currently deprecated, but will be eventually."
msgstr ""
"请尽可能在新项目中使用新的语法。虽然现在依然兼容旧语法，但终究会将其废弃的。"

# facb8eac8d394a2595b3745e4c2a67b4
#: ../../tutorial.rst:194
msgid "HTTP Request Methods"
msgstr "HTTP请求方法"

# 5cdb148bc56047629b19cac6c211ccba
#: ../../tutorial.rst:198
msgid ""
"The HTTP protocol defines several `request methods`__ (sometimes referred to "
"as \"verbs\") for different tasks. GET is the default for all routes with no "
"other method specified. These routes will match GET requests only. To handle "
"other methods such as POST, PUT or DELETE, add a ``method`` keyword argument "
"to the :func:`route` decorator or use one of the four alternative "
"decorators: :func:`get`, :func:`post`, :func:`put` or :func:`delete`."
msgstr ""
"HTTP协议定义了多个 `request methods`__ （请求方法）来满足不同的需求。所有"
"route默认使用GET方法，只响应GET请求。可给 :func:`route` 函数指定 ``method`` "
"参数。或用  :func:`get` ， :func:`post` ， :func:`put`  或 :func:`delete` 等"
"函数来代替 :func:`route` 函数。"

# 7278fe2bf62a4b3fb8abc0d391fd50e5
#: ../../tutorial.rst:200
msgid ""
"The POST method is commonly used for HTML form submission. This example "
"shows how to handle a login form using POST::"
msgstr ""
"POST方法一般用于HTML表单的提交。下面是一个使用POST来实现用户登录的例子::"

# d24dc377bdd6407eb5caaa912bf71dcb
#: ../../tutorial.rst:223
msgid ""
"In this example the ``/login`` URL is linked to two distinct callbacks, one "
"for GET requests and another for POST requests. The first one displays a "
"HTML form to the user. The second callback is invoked on a form submission "
"and checks the login credentials the user entered into the form. The use of :"
"attr:`Request.forms` is further described in the :ref:`tutorial-request` "
"section."
msgstr ""
"在这个例子中， ``/login`` 绑定了两个回调函数，一个回调函数响应GET请求，一个回"
"调函数响应POST请求。如果浏览器使用GET请求访问 ``/login`` ，则调用login_form()"
"函数来返回登录页面，浏览器使用POST方法提交表单后，调用login_submit()函数来检"
"查用户有效性，并返回登录结果。接下来的 :ref:`tutorial-request` 章节中，会详细"
"介绍 :attr:`Request.forms` 的用法。"

# 9a3d93e1646a48779d3cc9bef9713c21
#: ../../tutorial.rst:226
msgid "Special Methods: HEAD and ANY"
msgstr "特殊请求方法: HEAD 和 ANY"

# 78e1a7741c96447f912f8dd10cbc3aa4
#: ../../tutorial.rst:227
msgid ""
"The HEAD method is used to ask for the response identical to the one that "
"would correspond to a GET request, but without the response body. This is "
"useful for retrieving meta-information about a resource without having to "
"download the entire document. Bottle handles these requests automatically by "
"falling back to the corresponding GET route and cutting off the request "
"body, if present. You don't have to specify any HEAD routes yourself."
msgstr ""
"HEAD方法类似于GET方法，但服务器不会返回HTTP响应正文，一般用于获取HTTP原数据而"
"不用下载整个页面。Bottle像处理GET请求那样处理HEAD请求，但是会自动去掉HTTP响应"
"正文。你无需亲自处理HEAD请求。"

# 3628c8206bcb4b229d4e875e41a44e6b
#: ../../tutorial.rst:229
msgid ""
"Additionally, the non-standard ANY method works as a low priority fallback: "
"Routes that listen to ANY will match requests regardless of their HTTP "
"method but only if no other more specific route is defined. This is helpful "
"for *proxy-routes* that redirect requests to more specific sub-applications."
msgstr ""
"另外，非标准的ANY方法做为一个低优先级的fallback：在没有其它route的时候，监听"
"ANY方法的route会匹配所有请求，而不管请求的方法是什么。这对于用做代理的route很"
"有用，可将所有请求都重定向给子应用。"

# 1f0764c8a13a457bb5673ab0bfae1bf8
#: ../../tutorial.rst:231
msgid ""
"To sum it up: HEAD requests fall back to GET routes and all requests fall "
"back to ANY routes, but only if there is no matching route for the original "
"request method. It's as simple as that."
msgstr ""
"总而言之：HEAD请求被响应GET请求的route来处理，响应ANY请求的route处理所有请"
"求，但仅限于没有其它route来匹配原先的请求的情况。就这么简单。"

# 680955ebae544b4189d61a3ec93b13de
#: ../../tutorial.rst:236
msgid "Routing Static Files"
msgstr "静态文件映射"

# be9beea7a5c54379ae3b73c2f21b16e2
#: ../../tutorial.rst:238
msgid ""
"Static files such as images or CSS files are not served automatically. You "
"have to add a route and a callback to control which files get served and "
"where to find them::"
msgstr ""
"Bottle不会处理像图片或CSS文件的静态文件请求。你需要给静态文件提供一个route，"
"一个回调函数(用于查找和控制静态文件的访问)。"

# e174df21a55d4aaf9f92b14124f03538
#: ../../tutorial.rst:245
msgid ""
"The :func:`static_file` function is a helper to serve files in a safe and "
"convenient way (see :ref:`tutorial-static-files`). This example is limited "
"to files directly within the ``/path/to/your/static/files`` directory "
"because the ``<filename>`` wildcard won't match a path with a slash in it. "
"To serve files in subdirectories, change the wildcard to use the `path` "
"filter::"
msgstr ""
":func:`static_file` 函数用于响应静态文件的请求。 (详见 :ref:`tutorial-static-"
"files` )这个例子只能响应在 ``/path/to/your/static/files`` 目录下的文件请求，"
"因为 ``<filename>`` 这样的通配符定义不能匹配一个路径(路径中包含\"/\")。 为了"
"响应子目录下的文件请求，我们需要更改 `path` 过滤器的定义::"

# a42ae34a52d64603ad51dd2ac3e65ad1
#: ../../tutorial.rst:251
msgid ""
"Be careful when specifying a relative root-path such as ``root='./static/"
"files'``. The working directory (``./``) and the project directory are not "
"always the same."
msgstr ""
"使用 ``root='./static/files'`` 这样的相对路径的时候，请注意当前工作目录 (``./"
"``) 不一定是项目文件夹。"

# 22950a221ee24d8bb93f2202e7f5a843
#: ../../tutorial.rst:259
msgid "Error Pages"
msgstr "错误页面"

# e84b29f5921f42c487cd7409490d5026
#: ../../tutorial.rst:261
msgid ""
"If anything goes wrong, Bottle displays an informative but fairly plain "
"error page. You can override the default for a specific HTTP status code "
"with the :func:`error` decorator::"
msgstr ""
"如果出错了，Bottle会显示一个默认的错误页面，提供足够的debug信息。你也可以使"
"用 :func:`error` 函数来自定义你的错误页面::"

# 4bf4e85c95bd4b56b431ca5191f8f08d
#: ../../tutorial.rst:268
msgid ""
"From now on, `404 File not Found` errors will display a custom error page to "
"the user. The only parameter passed to the error-handler is an instance of :"
"exc:`HTTPError`. Apart from that, an error-handler is quite similar to a "
"regular request callback. You can read from :data:`request`, write to :data:"
"`response` and return any supported data-type except for :exc:`HTTPError` "
"instances."
msgstr ""
"从现在开始，在遇到404错误的时候，将会返回你在上面自定义的页面。传给error404函"
"数的唯一参数，是一个 :exc:`HTTPError` 对象的实例。除此之外，这个回调函数与我"
"们用来响应普通请求的回调函数没有任何不同。你可以从 :data:`request` 中读取数"
"据， 往 :data:`response` 中写入数据和返回所有支持的数据类型，除了 :exc:"
"`HTTPError` 的实例。"

# f3020bad30b147e9a86f81a825a379e9
#: ../../tutorial.rst:270
msgid ""
"Error handlers are used only if your application returns or raises an :exc:"
"`HTTPError` exception (:func:`abort` does just that). Changing :attr:"
"`Request.status` or returning :exc:`HTTPResponse` won't trigger the error "
"handler."
msgstr ""
"只有在你的应用返回或raise一个 :exc:`HTTPError` 异常的时候(就像 :func:`abort` "
"函数那样)，处理Error的函数才会被调用。更改 :attr:`Request.status` 或返回 :"
"exc:`HTTPResponse` 不会触发错误处理函数。"

# 9112d2478be94ef8a880cea1dabce53a
#: ../../tutorial.rst:280
msgid "Generating content"
msgstr "生成内容"

# 8415bb3259f54aceab2160438457d486
#: ../../tutorial.rst:282
msgid ""
"In pure WSGI, the range of types you may return from your application is "
"very limited. Applications must return an iterable yielding byte strings. "
"You may return a string (because strings are iterable) but this causes most "
"servers to transmit your content char by char. Unicode strings are not "
"allowed at all. This is not very practical."
msgstr ""
"在纯WSGI环境里，你的应用能返回的内容类型相当有限。应用必须返回一个iterable的"
"字节型字符串。你可以返回一个字符串(因为字符串是iterable的)，但这会导致服务器"
"按字符来传输你的内容。Unicode字符串根本不允许。这不是很实用。"

# 0c5e8549b2c14b10b64c1030888a9f11
#: ../../tutorial.rst:284
msgid ""
"Bottle is much more flexible and supports a wide range of types. It even "
"adds a ``Content-Length`` header if possible and encodes unicode "
"automatically, so you don't have to. What follows is a list of data types "
"you may return from your application callbacks and a short description of "
"how these are handled by the framework:"
msgstr ""
"Bottle支持返回更多的内容类型，更具弹性。它甚至能在合适的情况下，在HTTP头中添"
"加 `Content-Length` 字段和自动转换unicode编码。下面列出了所有你能返回的内容类"
"型，以及框架处理方式的一个简述。"

# cd50167d8d094ecf947bb272905d75b7
#: ../../tutorial.rst:287
msgid "Dictionaries"
msgstr ""

# 05aa98461f2e434f81e050cbcc756f6a
#: ../../tutorial.rst:287
msgid ""
"As mentioned above, Python dictionaries (or subclasses thereof) are "
"automatically transformed into JSON strings and returned to the browser with "
"the ``Content-Type`` header set to ``application/json``. This makes it easy "
"to implement json-based APIs. Data formats other than json are supported "
"too. See the :ref:`tutorial-output-filter` to learn more."
msgstr ""
"上面已经提及，Python中的字典类型(或其子类)会被自动转换为JSON字符串。返回给浏"
"览器的时候，HTTP头的 ``Content-Type`` 字段被自动设置为 `` application/"
"json`` 。可十分简单地实现基于JSON的API。Bottle同时支持json之外的数据类型，详"
"见 :ref:`tutorial-output-filter` 。"

# fef9f9cdcf174200a8c9d34fe40ec6a8
#: ../../tutorial.rst:290
msgid "Empty Strings, ``False``, ``None`` or other non-true values:"
msgstr ""

# 947fe77a24c4436f92b3de6ac018bfb8
#: ../../tutorial.rst:290
msgid ""
"These produce an empty output with the ``Content-Length`` header set to 0."
msgstr "输出为空， ``Content-Length`` 设为0。"

# 53831a3d134a4bcc8b1553ff0e8ef190
#: ../../tutorial.rst:293
msgid "Unicode strings"
msgstr "Unicode的问题"

# 6b454d4e4ee04af1809c42870727aeab
#: ../../tutorial.rst:293
msgid ""
"Unicode strings (or iterables yielding unicode strings) are automatically "
"encoded with the codec specified in the ``Content-Type`` header (utf8 by "
"default) and then treated as normal byte strings (see below)."
msgstr ""
"Unicode字符串 (or iterables yielding unicode strings) 被自动转码， ``Content-"
"Type`` 被默认设置为utf8，接着视之为普通字符串(见下文)。"

# e8ae5fa61f0942cd9fe48e03fa9351e9
#: ../../tutorial.rst:296
msgid "Byte strings"
msgstr ""

# e20b8cfb4e7a434c9a95dc125561a7f0
#: ../../tutorial.rst:296
msgid ""
"Bottle returns strings as a whole (instead of iterating over each char) and "
"adds a ``Content-Length`` header based on the string length. Lists of byte "
"strings are joined first. Other iterables yielding byte strings are not "
"joined because they may grow too big to fit into memory. The ``Content-"
"Length`` header is not set in this case."
msgstr ""
"Bottle将字符串当作一个整体来返回(而不是按字符来遍历)，并根据字符串长度添加 "
"``Content-Length`` 字段。包含字节型字符串的列表先被合并。其它iterable的字节型"
"字符串不会被合并，因为它们也许太大来，耗内存。在这种情况下， ``Content-"
"Length`` 字段不会被设置。"

# c0b5bc13bd1f456ea06c9ec8c0ae332e
#: ../../tutorial.rst:299
msgid "Instances of :exc:`HTTPError` or :exc:`HTTPResponse`"
msgstr ""

# 4b231556398548d6804429d660fe8f90
#: ../../tutorial.rst:299
msgid ""
"Returning these has the same effect as when raising them as an exception. In "
"case of an :exc:`HTTPError`, the error handler is applied. See :ref:"
"`tutorial-errorhandling` for details."
msgstr ""
"返回它们和直接raise出来有一样的效果。对于 :exc:`HTTPError` 来说，会调用错误处"
"理程序。详见 :ref:`tutorial-errorhandling` 。"

# 8ec78edc24634cb19d9d3fe68fff214f
#: ../../tutorial.rst:302
msgid "File objects"
msgstr ""

# 84bf9373fcf148a0b17af9a22e9473d7
#: ../../tutorial.rst:302
msgid ""
"Everything that has a ``.read()`` method is treated as a file or file-like "
"object and passed to the ``wsgi.file_wrapper`` callable defined by the WSGI "
"server framework. Some WSGI server implementations can make use of optimized "
"system calls (sendfile) to transmit files more efficiently. In other cases "
"this just iterates over chunks that fit into memory. Optional headers such "
"as ``Content-Length`` or ``Content-Type`` are *not* set automatically. Use :"
"func:`send_file` if possible. See :ref:`tutorial-static-files` for details."
msgstr ""
"任何有 ``.read()`` 方法的对象都被当成一个file-like对象来对待，会被传给 WSGI "
"Server 框架定义的 ``wsgi.file_wrapper`` callable对象来处理。一些WSGI Server实"
"现会利用优化过的系统调用(sendfile)来更有效地传输文件，另外就是分块遍历。可选"
"的HTTP头，例如 ``Content-Length`` 和 ``Content-Type`` 不会被自动设置。尽可能"
"使用 :func:`send_file` 。详见 :ref:`tutorial-static-files` 。"

# 5a4011401e1b4adfa5dc9114b1491c26
#: ../../tutorial.rst:305
msgid "Iterables and generators"
msgstr ""

# 134e34ab7165436b8232fe79d85d695e
#: ../../tutorial.rst:305
msgid ""
"You are allowed to use ``yield`` within your callbacks or return an "
"iterable, as long as the iterable yields byte strings, unicode strings, :exc:"
"`HTTPError` or :exc:`HTTPResponse` instances. Nested iterables are not "
"supported, sorry. Please note that the HTTP status code and the headers are "
"sent to the browser as soon as the iterable yields its first non-empty "
"value. Changing these later has no effect."
msgstr ""
"你可以在回调函数中使用 ``yield`` 语句，或返回一个iterable的对象，只要该对象返"
"回的是字节型字符串，unicode字符串， :exc:`HTTPError` 或 :exc:`HTTPResponse` "
"实例。不支持嵌套iterable对象，不好意思。注意，在iterable对象返回第一个非空值"
"的时候，就会把HTTP状态码和HTTP头发送给浏览器。稍后再更改它们就起不到什么作用"
"了。"

# 465e3afd48064a6aa286d3b5428b038b
#: ../../tutorial.rst:307
msgid ""
"The ordering of this list is significant. You may for example return a "
"subclass of :class:`str` with a ``read()`` method. It is still treated as a "
"string instead of a file, because strings are handled first."
msgstr ""
"以上列表的顺序非常重要。在你返回一个 :class:`str` 类的子类的时候，即使它有 "
"``.read()`` 方法，它依然会被当成一个字符串对待，而不是文件，因为字符串先被处"
"理。"

# 2fc6610bcc9f406f8b368ef74e8b26f9
#: ../../tutorial.rst:310
msgid "Changing the Default Encoding"
msgstr "改变默认编码"

# 23b6daa9751f4ba5920edfff5246fbc0
#: ../../tutorial.rst:311
msgid ""
"Bottle uses the `charset` parameter of the ``Content-Type`` header to decide "
"how to encode unicode strings. This header defaults to ``text/html; "
"charset=UTF8`` and can be changed using the :attr:`Response.content_type` "
"attribute or by setting the :attr:`Response.charset` attribute directly. "
"(The :class:`Response` object is described in the section :ref:`tutorial-"
"response`.)"
msgstr ""
"Bottle使用 ``Content-Type`` 的 `charset` 参数来决定编码unicode字符串的方式。"
"默认的 ``Content-Type`` 是 ``text/html;charset=UTF8`` ，可在 :attr:`Response."
"content_type` 属性中修改，或直接设置 :attr:`Response.charset` 的值。关于 :"
"class:`Response` 对象的介绍，详见 :ref:`tutorial-response` 。"

# 2bd0c5aa83bb43b1ad029c4a8f8a19d9
#: ../../tutorial.rst:326
msgid ""
"In some rare cases the Python encoding names differ from the names supported "
"by the HTTP specification. Then, you have to do both: first set the :attr:"
"`Response.content_type` header (which is sent to the client unchanged) and "
"then set the :attr:`Response.charset` attribute (which is used to encode "
"unicode)."
msgstr ""
"在极少情况下，Python中定义的编码名字和HTTP标准中的定义不一样。这样，你就必须"
"同时修改 :attr:`Response.content_type`` (发送给客户端的)和设置 :attr:"
"`Response.charset` 属性 (用于编码unicode)。"

# e3e2fb4d1ee847ca84245ed5a5729071
#: ../../tutorial.rst:331
msgid "Static Files"
msgstr "静态文件"

# 4a4c82922fbf4478886571051b910204
#: ../../tutorial.rst:333
msgid ""
"You can directly return file objects, but :func:`static_file` is the "
"recommended way to serve static files. It automatically guesses a mime-type, "
"adds a ``Last-Modified`` header, restricts paths to a ``root`` directory for "
"security reasons and generates appropriate error responses (401 on "
"permission errors, 404 on missing files). It even supports the ``If-Modified-"
"Since`` header and eventually generates a ``304 Not Modified`` response. You "
"can pass a custom MIME type to disable guessing."
msgstr ""
"你可直接返回文件对象。但我们更建议你使用 :func:`static_file` 来提供静态文件服"
"务。它会自动猜测文件的mime-type，添加 ``Last-Modified`` 头，将文件路径限制在"
"一个root文件夹下面来保证安全，且返回合适的HTTP状态码(由于权限不足导致的401错"
"误，由于文件不存在导致的404错误)。它甚至支持 ``If-Modified-Since`` 头，如果文"
"件未被修改，则直接返回 ``304 Not Modified`` 。你可指定MIME类型来避免其自动猜"
"测。"

# 3d6989c4599c4f9d9fcdd6cba03e29aa
#: ../../tutorial.rst:346
msgid ""
"You can raise the return value of :func:`static_file` as an exception if you "
"really need to."
msgstr "如果确实需要，你可将 :func:`static_file` 的返回值当作异常raise出来。"

# 8d57af8994bd44cd8dd00013b3a71231
#: ../../tutorial.rst:349
msgid "Forced Download"
msgstr "强制下载"

# 23ef7011528a4bf9a2b181d2427f0b21
#: ../../tutorial.rst:350
msgid ""
"Most browsers try to open downloaded files if the MIME type is known and "
"assigned to an application (e.g. PDF files). If this is not what you want, "
"you can force a download dialog and even suggest a filename to the user::"
msgstr ""
"大多数浏览器在知道MIME类型的时候，会尝试直接调用相关程序来打开文件(例如PDF文"
"件)。如果你不想这样，你可强制浏览器只是下载该文件，甚至提供文件名。::"

# 2b57ebda0b8b47c09d4cebcc702835e3
#: ../../tutorial.rst:356
msgid ""
"If the ``download`` parameter is just ``True``, the original filename is "
"used."
msgstr "如果 ``download`` 参数的值为 ``True`` ，会使用原始的文件名。"

# 3abd91e08f5c439481852f8eced8b1de
#: ../../tutorial.rst:361
msgid "HTTP Errors and Redirects"
msgstr "HTTP错误和重定向"

# 4ef454163f78497fa8f0c3b112e02a6c
#: ../../tutorial.rst:363
msgid ""
"The :func:`abort` function is a shortcut for generating HTTP error pages."
msgstr ":func:`abort` 函数是生成HTTP错误页面的一个捷径。"

# 65a2e1ed20634574932f8c39c8ac2d13
#: ../../tutorial.rst:372
msgid ""
"To redirect a client to a different URL, you can send a ``303 See Other`` "
"response with the ``Location`` header set to the new URL. :func:`redirect` "
"does that for you::"
msgstr ""
"为了将用户访问重定向到其他URL，你在 ``Location`` 中设置新的URL，接着返回一个 "
"``303 See Other`` 。 :func:`redirect` 函数可以帮你做这件事情。"

# 50ab2a7b353a41c39c7fdcb9456630e3
#: ../../tutorial.rst:379
msgid "You may provide a different HTTP status code as a second parameter."
msgstr "你可以在第二个参数中提供另外的HTTP状态码。"

# 757d4047c42d4e71a774a63b020fbb42
#: ../../tutorial.rst:382
msgid ""
"Both functions will interrupt your callback code by raising an :exc:"
"`HTTPError` exception."
msgstr "这两个函数都会抛出 :exc:`HTTPError` 异常，终止回调函数的执行。"

# 2ee3e09d1528432294fcead9239e99b6
#: ../../tutorial.rst:385
msgid "Other Exceptions"
msgstr "其他异常"

# 72ce4695e46c40d0a2f4aad019108612
#: ../../tutorial.rst:386
msgid ""
"All exceptions other than :exc:`HTTPResponse` or :exc:`HTTPError` will "
"result in a ``500 Internal Server Error`` response, so they won't crash your "
"WSGI server. You can turn off this behavior to handle exceptions in your "
"middleware by setting ``bottle.app().catchall`` to ``False``."
msgstr ""
"除了 :exc:`HTTPResponse` 或 :exc:`HTTPError` 以外的其他异常，都会导致500错"
"误，所以不会造成WSGI服务器崩溃。你将 ``bottle.app().catchall`` 的值设为 "
"``False`` 来关闭这种行为，以便在你的中间件中处理异常。"

# 49ba8af1eacf4ca6b5eef9f290d09a94
#: ../../tutorial.rst:392
msgid "The :class:`Response` Object"
msgstr ":class:`Response` 对象"

# 8ff2b5057b384d199aa9e15374ca37d4
#: ../../tutorial.rst:394
msgid ""
"Response metadata such as the HTTP status code, response headers and cookies "
"are stored in an object called :data:`response` up to the point where they "
"are transmitted to the browser. You can manipulate these metadata directly "
"or use the predefined helper methods to do so. The full API and feature list "
"is described in the API section (see :class:`Response`), but the most common "
"use cases and features are covered here, too."
msgstr ""
"诸如HTTP状态码，HTTP响应头，用户cookie等元数据都保存在一个名字为 :data:"
"`response` 的对象里面，接着被传输给浏览器。你可直接操作这些元数据或使用一些更"
"方便的函数。在API章节可查到所有相关API(详见 :class:`Response` )，这里主要介绍"
"一些常用方法。"

# a4837fc6a70147fa9abce539af78cda0
#: ../../tutorial.rst:397
msgid "Status Code"
msgstr "状态码"

# 16869c8c17d54323ab7486f66efdc860
#: ../../tutorial.rst:398
msgid ""
"The `HTTP status code <http_code>`_ controls the behavior of the browser and "
"defaults to ``200 OK``. In most scenarios you won't need to set the :attr:"
"`Response.status` attribute manually, but use the :func:`abort` helper or "
"return an :exc:`HTTPResponse` instance with the appropriate status code. Any "
"integer is allowed, but codes other than the ones defined by the `HTTP "
"specification <http_code>`_ will only confuse the browser and break "
"standards."
msgstr ""
"`HTTP状态码 <http_code>`_ 控制着浏览器的行为，默认为 ``200 OK`` 。多数情况"
"下，你不必手动修改 :attr:`Response.status` 的值，可使用 :func:`abort` 函数或"
"return一个 :exc:`HTTPResponse` 实例(带有合适的状态码)。虽然所有整数都可当作状"
"态码返回，但浏览器不知道如何处理 `HTTP标准 <http_code>`_ 中定义的那些状态码之"
"外的数字，你也破坏了大家约定的标准。"

# fad4d415e6b34d8da4915371819dad0b
#: ../../tutorial.rst:401
msgid "Response Header"
msgstr "响应头"

# 6837d7afd10c499e84b15229465f8a3a
#: ../../tutorial.rst:402
msgid ""
"Response headers such as ``Cache-Control`` or ``Location`` are defined via :"
"meth:`Response.set_header`. This method takes two parameters, a header name "
"and a value. The name part is case-insensitive::"
msgstr ""
"``Cache-Control`` 和 ``Location`` 之类的响应头通过 :meth:`Response."
"set_header` 来定义。这个方法接受两个参数，一个是响应头的名字，一个是它的值，"
"名字是大小写敏感的。"

# 6414dd7a448b45f998147a61ce167933
#: ../../tutorial.rst:409
msgid ""
"Most headers are unique, meaning that only one header per name is send to "
"the client. Some special headers however are allowed to appear more than "
"once in a response. To add an additional header, use :meth:`Response."
"add_header` instead of :meth:`Response.set_header`::"
msgstr ""
"大多数的响应头是唯一的，meaning that only one header per name is send to the "
"client。一些特殊的响应头在一次response中允许出现多次。使用 :meth:`Response."
"add_header` 来添加一个额外的响应头，而不是 :meth:`Response.set_header` ::"

# cc64c4d2b8f541728562d60b69e95246
#: ../../tutorial.rst:414
msgid ""
"Please note that this is just an example. If you want to work with cookies, "
"read :ref:`ahead <tutorial-cookies>`."
msgstr ""
"请注意，这只是一个例子。如果你想使用cookie，详见 :ref:`ahead <tutorial-"
"cookies>` 。"

# 1ffb76e4eada4039b6633e13cdb49c6a
# 35303652d16f422bacde561fb6912852
#: ../../tutorial.rst:420 ../../tutorial.rst:549
msgid "Cookies"
msgstr ""

# 6b9e5c6de2f0499b9483fc1f2e666aa4
#: ../../tutorial.rst:422
msgid ""
"A cookie is a named piece of text stored in the user's browser profile. You "
"can access previously defined cookies via :meth:`Request.get_cookie` and set "
"new cookies with :meth:`Response.set_cookie`::"
msgstr ""
"Cookie是储存在浏览器配置文件里面的一小段文本。你可通过 :meth:`Request."
"get_cookie` 来访问已存在的Cookie，或通过 :meth:`Response.set_cookie` 来设置新"
"的Cookie。"

# 89a73e9549444c0ba012c873a5f82ad5
#: ../../tutorial.rst:432
msgid ""
"The :meth:`Response.set_cookie` method accepts a number of additional "
"keyword arguments that control the cookies lifetime and behavior. Some of "
"the most common settings are described here:"
msgstr ""
":meth:`Response.set_cookie` 方法接受一系列额外的参数，来控制Cookie的生命周期"
"及行为。一些常用的设置如下:"

# f4b185b380fd44129a1c9e606627d9cd
#: ../../tutorial.rst:434
msgid "**max_age:**    Maximum age in seconds. (default: ``None``)"
msgstr "**max_age:**    最大有效时间，以秒为单位 (默认: ``None``)"

# 5f7ec5d053de45c1b7f018e4a77a5100
#: ../../tutorial.rst:435
msgid ""
"**expires:**    A datetime object or UNIX timestamp. (default: ``None``)"
msgstr "**expires:**    一个datetime对象或一个UNIX timestamp (默认: ``None``)"

# 93366621f0de4592872fbbd675ccfe9b
#: ../../tutorial.rst:436
msgid ""
"**domain:**     The domain that is allowed to read the cookie. (default: "
"current domain)"
msgstr "**domain:**     可访问该Cookie的域名 (默认: 当前域名)"

# 6011fc5e6dfa4c70a3fb228d7632dbe7
#: ../../tutorial.rst:437
msgid "**path:**       Limit the cookie to a given path (default: ``/``)"
msgstr "**path:**       限制cookie的访问路径 (默认: ``/``)"

# 54a3f9e2aabb4fcf8f9fe532ed8c5ea4
#: ../../tutorial.rst:438
msgid "**secure:**     Limit the cookie to HTTPS connections (default: off)."
msgstr "**secure:**     只允许在HTTPS链接中访问cookie (默认: off)"

# 52488fc9830349e0ad2a586ef39ce369
#: ../../tutorial.rst:439
msgid ""
"**httponly:**   Prevent client-side javascript to read this cookie (default: "
"off, requires Python 2.6 or newer)."
msgstr ""
"**httponly:**   防止客户端的javascript读取cookie (默认: off, 要求python 2.6或"
"以上版本)"

# 01244742811543388b079c56b8927022
#: ../../tutorial.rst:441
msgid ""
"If neither `expires` nor `max_age` is set, the cookie expires at the end of "
"the browser session or as soon as the browser window is closed. There are "
"some other gotchas you should consider when using cookies:"
msgstr ""
"如果 `expires` 和 `max_age` 两个值都没设置，cookie会在当前的浏览器session失效"
"或浏览器窗口关闭后失效。在使用cookie的时候，应该注意一下几个陷阱。"

# 6cbd22399dd348bea70e2e80ee49110c
#: ../../tutorial.rst:443
msgid "Cookies are limited to 4 KB of text in most browsers."
msgstr "在大多数浏览器中，cookie的最大容量为4KB。"

# 14572986849c49978df7a87343a71ab3
#: ../../tutorial.rst:444
msgid ""
"Some users configure their browsers to not accept cookies at all. Most "
"search engines ignore cookies too. Make sure that your application still "
"works without cookies."
msgstr ""
"一些用户将浏览器设置为不接受任何cookie。大多数搜索引擎也忽略cookie。确保你的"
"应用在无cookie的时候也能工作。"

# 5dca7f9d829541ddbe8d5e168938dffa
#: ../../tutorial.rst:445
msgid ""
"Cookies are stored at client side and are not encrypted in any way. Whatever "
"you store in a cookie, the user can read it. Worse than that, an attacker "
"might be able to steal a user's cookies through `XSS <http://en.wikipedia."
"org/wiki/HTTP_cookie#Cookie_theft_and_session_hijacking>`_ vulnerabilities "
"on your side. Some viruses are known to read the browser cookies, too. Thus, "
"never store confidential information in cookies."
msgstr ""
"cookie被储存在客户端，也没被加密。你在cookie中储存的任何数据，用户都可以读"
"取。更坏的情况下，cookie会被攻击者通过 `XSS <http://en.wikipedia.org/wiki/"
"HTTP_cookie#Cookie_theft_and_session_hijacking>`_ 偷走，一些已知病毒也会读取"
"浏览器的cookie。既然如此，就不要在cookie中储存任何敏感信息。"

# d7e20326f4d8418697a0f9d697149837
#: ../../tutorial.rst:446
msgid "Cookies are easily forged by malicious clients. Do not trust cookies."
msgstr "cookie可以被伪造，不要信任cookie！"

# f9d19c03dc70462badd8b0b5493a9c5c
#: ../../tutorial.rst:451
msgid "Signed Cookies"
msgstr "Cookie签名"

# 269d39ae6e4f413ca3221424985aa0c4
#: ../../tutorial.rst:452
msgid ""
"As mentioned above, cookies are easily forged by malicious clients. Bottle "
"can cryptographically sign your cookies to prevent this kind of "
"manipulation. All you have to do is to provide a signature key via the "
"`secret` keyword argument whenever you read or set a cookie and keep that "
"key a secret. As a result, :meth:`Request.get_cookie` will return ``None`` "
"if the cookie is not signed or the signature keys don't match::"
msgstr ""
"上面提到，cookie容易被客户端伪造。Bottle可通过加密cookie来防止此类攻击。你只"
"需在读取和设置cookie的时候，通过 `secret` 参数来提供一个密钥。如果cookie未签"
"名或密钥不匹配， :meth:`Request.get_cookie` 方法返回 ``None`` "

# 99cbc28ea5f240cba38b5f2cd2fc7518
#: ../../tutorial.rst:472
msgid ""
"In addition, Bottle automatically pickles and unpickles any data stored to "
"signed cookies. This allows you to store any pickle-able object (not only "
"strings) to cookies, as long as the pickled data does not exceed the 4 KB "
"limit."
msgstr ""
"例外，Bottle自动序列化储存在签名cookie里面的数据。你可在cookie中储存任何可序"
"列化的对象(不仅仅是字符串)，只要对象大小不超过4KB。"

# a3e875cbc84a440488152c627190d081
#: ../../tutorial.rst:474
msgid ""
"Signed cookies are not encrypted (the client can still see the content) and "
"not copy-protected (the client can restore an old cookie). The main "
"intention is to make pickling and unpickling safe and prevent manipulation, "
"not to store secret information at client side."
msgstr ""
"签名cookie在客户端不加密(译者注：即在客户端没有经过二次加密)，也没有写保护(客"
"户端可使用之前的cookie)。给cookie签名的主要意义在于在cookie中存储序列化对象和"
"防止伪造cookie，依然不要在cookie中存储敏感信息。"

# 4655322431dd449193c8c18eeb8cdf95
#: ../../tutorial.rst:487
msgid "Request Data"
msgstr "请求数据 (Request Data)"

# 5bf5d62b2bae4266b7c48345f157eda7
#: ../../tutorial.rst:489
msgid ""
"Cookies, HTTP header, HTML ``<form>`` fields and other request data is "
"available through the global :data:`request` object. This special object "
"always refers to the *current* request, even in multi-threaded environments "
"where multiple client connections are handled at the same time::"
msgstr ""
"可通过全局的 :data:`request` 对象来访问Cookies，HTTP头，HTML的 ``<form>`` 字"
"段，以及其它的请求数据。这个特殊的对象总是指向 *当前* 的请求，即使在同时处理"
"多个客户端连接的多线程情况下。"

# 8466f755a5544bdd95621e346d6c0a60
#: ../../tutorial.rst:498
msgid ""
"The :data:`request` object is a subclass of :class:`BaseRequest` and has a "
"very rich API to access data. We only cover the most commonly used features "
"here, but it should be enough to get started."
msgstr ""
":data:`request` 对象继承自 :class:`BaseRequest` ，提供了丰富的API来访问数据。"
"虽然我们只介绍最常用的特性，也足够入门了。"

# 0ca3e35753434dba85029c1e93ea2bde
#: ../../tutorial.rst:503
msgid "Introducing :class:`FormsDict`"
msgstr "介绍 :class:`FormsDict` "

# d1385d18bbf148fc9547cfeadc3fe627
#: ../../tutorial.rst:505
msgid ""
"Bottle uses a special type of dictionary to store form data and cookies. :"
"class:`FormsDict` behaves like a normal dictionary, but has some additional "
"features to make your life easier."
msgstr ""
"Bottle使用了一个特殊的字典来储存表单数据和cookies。 :class:`FormsDict` 表现得"
"像一个普通的字典，但提供了更方便的额外功能。"

# 36ea0be70fe44886bfec49f8263868e1
#: ../../tutorial.rst:507
msgid ""
"**Attribute access**: All values in the dictionary are also accessible as "
"attributes. These virtual attributes return unicode strings, even if the "
"value is missing or unicode decoding fails. In that case, the string is "
"empty, but still present::"
msgstr ""
"**属性访问** ：字典中所有的值都可以当做属性来访问。这些虚拟的属性返回unicode"
"字符串。在字典中缺少对应的值，或unicode解码失败的情况下，属性返回的字符串为"
"空。"

# c6d66b38537f4c93a5aea83e2d90096d
#: ../../tutorial.rst:522
msgid ""
"**Multiple values per key:** :class:`FormsDict` is a subclass of :class:"
"`MultiDict` and can store more than one value per key. The standard "
"dictionary access methods will only return a single value, but the :meth:"
"`~MultiDict.getall` method returns a (possibly empty) list of all values for "
"a specific key::"
msgstr ""
"**一个key对应多个value：** :class:`FormsDict` 是 :class:`MutilDict` 的子类，"
"一个key可存储多个value。标准的字典访问方法只返回一个值，但 :meth:`~MultiDict."
"getall` 方法会返回一个包含了所有value的一个list（也许为空）。"

# bc6adb59e0714314b37551f7db353571
#: ../../tutorial.rst:527
msgid ""
"**WTForms support:** Some libraries (e.g. `WTForms <http://wtforms."
"simplecodes.com/>`_) want all-unicode dictionaries as input. :meth:"
"`FormsDict.decode` does that for you. It decodes all values and returns a "
"copy of itself, while preserving multiple values per key and all the other "
"features."
msgstr ""
"**WTForms支持：** 一些第三方库（例如 `WTForms <http://wtforms.simplecodes."
"com/>`_ ）希望输入中的所有字典都是unicode的。 :meth:`FormsDict.decode` 帮你做"
"了这件事情。它将所有value重新编码，并返回原字典的一个拷贝，同时保留所有特性，"
"例如一个key对应多个value。"

# 424fca94acab45129e4592ae1c4c5fee
#: ../../tutorial.rst:531
msgid ""
"In **Python 2** all keys and values are byte-strings. If you need unicode, "
"you can call :meth:`FormsDict.getunicode` or fetch values via attribute "
"access. Both methods try to decode the string (default: utf8) and return an "
"empty string if that fails. No need to catch :exc:`UnicodeError`::"
msgstr ""
"在 **Python2** 中，所有的key和value都是byte-string。如果你需要unicode，可使"
"用 :meth:`FormsDict.getunicode` 方法或像访问属性那样访问。这两种方法都试着将"
"字符串转码(默认: utf8)，如果失败，将返回一个空字符串。无需捕获 :exc:"
"`UnicodeError` 异常。"

# 16daaaa718454e58a8a143d05119bac1
#: ../../tutorial.rst:538
msgid ""
"In **Python 3** all strings are unicode, but HTTP is a byte-based wire "
"protocol. The server has to decode the byte strings somehow before they are "
"passed to the application. To be on the safe side, WSGI suggests ISO-8859-1 "
"(aka latin1), a reversible single-byte codec that can be re-encoded with a "
"different encoding later. Bottle does that for :meth:`FormsDict.getunicode` "
"and attribute access, but not for the dict-access methods. These return the "
"unchanged values as provided by the server implementation, which is probably "
"not what you want."
msgstr ""
"在 **Python3** 中，所有的字符串都是unicode。但HTTP是基于字节的协议，在byte-"
"string被传给应用之前，服务器必须将其转码。安全起见，WSGI协议建议使用"
"ISO-8859-1 (即是latin1)，一个可反转的单字节编码，可被转换为其他编码。Bottle通"
"过 :meth:`FormsDict.getunicode` 和属性访问实现了转码，但不支持字典形式的访"
"问。通过字典形式的访问，将直接返回服务器返回的字符串，未经处理，这或许不是你"
"想要的。"

# eaa8c0117ce043d3a561cedacf73885d
#: ../../tutorial.rst:545
msgid ""
"If you need the whole dictionary with correctly decoded values (e.g. for "
"WTForms), you can call :meth:`FormsDict.decode` to get a re-encoded copy."
msgstr ""
"如果你整个字典包含正确编码后的值(e.g. for WTForms)，可通过 :meth:`FormsDict."
"decode` 方法来获取一个转码后的拷贝(译者注：一个新的实例)。"

# 8dc1b5cc26104144bb0774207d410442
#: ../../tutorial.rst:551
msgid ""
"Cookies are small pieces of text stored in the clients browser and sent back "
"to the server with each request. They are useful to keep some state around "
"for more than one request (HTTP itself is stateless), but should not be used "
"for security related stuff. They can be easily forged by the client."
msgstr ""
"Cookie是客户端浏览器存储的一些文本数据，在每次请求的时候发送回给服务器。"
"Cookie被用于在多次请求间保留状态信息（HTTP本身是无状态的），但不应该用于保存"
"安全相关信息。因为客户端很容易伪造Cookie。"

# 7e7760b24bf44ea38c8234dba8b229bd
#: ../../tutorial.rst:553
msgid ""
"All cookies sent by the client are available through :attr:`BaseRequest."
"cookies` (a :class:`FormsDict`). This example shows a simple cookie-based "
"view counter::"
msgstr ""
"可通过 :attr:`BaseRequest.cookies` (一个 :class:`FormsDict`) 来访问所有客户端"
"发来的Cookie。下面的是一个基于Cookie的访问计数。"

# 7e7760b24bf44ea38c8234dba8b229bd
#: ../../tutorial.rst:563
msgid ""
"The :meth:`BaseRequest.get_cookie` method is a different way do access "
"cookies. It supports decoding :ref:`signed cookies <tutorial-signed-"
"cookies>` as described in a separate section."
msgstr ""
":meth:`BaseRequest.get_cookie` 是访问cookie的另一种方法。它支持解析 :ref:"
"`signed cookies <tutorial-signed-cookies>` 。"

# 100ecfb0ffa34da8a18ba10859ec5203
#: ../../tutorial.rst:566
msgid "HTTP Headers"
msgstr "HTTP头"

# 2883f57c0e824a8a9b8d2213e2ff5cf5
#: ../../tutorial.rst:568
msgid ""
"All HTTP headers sent by the client (e.g. ``Referer``, ``Agent`` or ``Accept-"
"Language``) are stored in a :class:`WSGIHeaderDict` and accessible through "
"the :attr:`BaseRequest.headers` attribute. A :class:`WSGIHeaderDict` is "
"basically a dictionary with case-insensitive keys::"
msgstr ""
"所有客户端发送过来的HTTP头(例如 ``Referer``, ``Agent`` 和 ``Accept-"
"Language``)存储在一个 :class:`WSGIHeaderDict` 中，可通过 :attr:`BaseRequest."
"headers` 访问。  :class:`WSGIHeaderDict` 基本上是一个字典，其key大小写敏感。"

# a04a46af8ede416dbc96fa3067dce003
#: ../../tutorial.rst:580
msgid "Query Variables"
msgstr "查询变量"

# 3c909f2249c94ee3b61c99e1ac5d8fa7
#: ../../tutorial.rst:582
msgid ""
"The query string (as in ``/forum?id=1&page=5``) is commonly used to transmit "
"a small number of key/value pairs to the server. You can use the :attr:"
"`BaseRequest.query` attribute (a :class:`FormsDict`) to access these values "
"and the :attr:`BaseRequest.query_string` attribute to get the whole string."
msgstr ""
"查询字符串(例如 ``/forum?id=1&page=5`` )一般用于向服务器传输键值对。你可通"
"过 :attr:`BaseRequest.query` ( :class:`FormsDict` 类的实例) 来访问，和通过 :"
"attr:`BaseRequest.query_string` 来获取整个字符串。"

# 25526928151e427cab403bbea63ec097
#: ../../tutorial.rst:595
msgid "HTML `<form>` Handling"
msgstr "处理HTML的 `<form>` 标签"

# 0c4a8b2fc4ea421bb0d7726d2760fe1d
#: ../../tutorial.rst:597
msgid ""
"Let us start from the beginning. In HTML, a typical ``<form>`` looks "
"something like this:"
msgstr "让我们从头开始。在HTML中，一个典型的 ``<form>`` 标签看起来是这样的。"

# 7c5b1ec7c6254562abeca801783f66fb
#: ../../tutorial.rst:607
msgid ""
"The ``action`` attribute specifies the URL that will receive the form data. "
"``method`` defines the HTTP method to use (``GET`` or ``POST``). With "
"``method=\"get\"`` the form values are appended to the URL and available "
"through :attr:`BaseRequest.query` as described above. This is considered "
"insecure and has other limitations, so we use ``method=\"post\"`` here. If "
"in doubt, use ``POST`` forms."
msgstr ""
"``action`` 属性指定了用于接收表单数据的URL， ``method`` 定义了使用的HTTP方法"
"（ ``GET`` 或 ``POST`` ）。如果使用GET方法，表单中的数据会附加到URL后面，可通"
"过 :attr:`BaseRequest.query` 来访问。这被认为是不安全的，且有其它限制。所以这"
"里我们使用POST方法。如果有疑惑，就使用 ``POST`` 吧。"

# c4f2495ac4dd45d3bbc265d8a9d002a9
#: ../../tutorial.rst:609
msgid ""
"Form fields transmitted via ``POST`` are stored in :attr:`BaseRequest.forms` "
"as a :class:`FormsDict`. The server side code may look like this::"
msgstr ""
"通过POST方法传输的表单字段，作为一个 :class:`FormsDict` 存储在 :attr:"
"`BaseRequest.forms` 中。服务器端的代码看起来是这样的。"

# 3632962199094482870c7ba2f03610d6
#: ../../tutorial.rst:632
msgid ""
"There are several other attributes used to access form data. Some of them "
"combine values from different sources for easier access. The following table "
"should give you a decent overview."
msgstr ""
"有其它一些属性也可以用来访问表单数据。为了方便，一些属性包含了多个来源的数"
"据。下面的表格可给你一个直观的印象。"

# 65f70c00c85047bf916aa04636146b14
#: ../../tutorial.rst:635
msgid "Attribute"
msgstr ""

# 62ba54597de54af58b7f60aa96fee29a
#: ../../tutorial.rst:635
msgid "GET Form fields"
msgstr ""

# 62ba54597de54af58b7f60aa96fee29a
#: ../../tutorial.rst:635
msgid "POST Form fields"
msgstr "POST表单数据"

# 62ba54597de54af58b7f60aa96fee29a
#: ../../tutorial.rst:635
msgid "File Uploads"
msgstr ""

# fbb89b2e85a64af5bf161bc80547f380
#: ../../tutorial.rst:637
msgid ":attr:`BaseRequest.query`"
msgstr ""

# 3fa195bb296e4164898b421bf4ab5beb
# c6d6540237ad435093a041f8e4b572fa
# 62d96ea440a94a76bea224714c15b2e0
# 125f34a989e74405b622c1b4cc5b9187
# 8dfdfc246dea4016a058c8ca3280bd17
# 4128d67e776043cebf97371702197b62
# 60adb7f041ff490bbd446b0ea9a3d1ad
# c34b8f3630e84e4ebdfec44f28b10ef2
#: ../../tutorial.rst:637 ../../tutorial.rst:638 ../../tutorial.rst:639
#: ../../tutorial.rst:640 ../../tutorial.rst:641 ../../tutorial.rst:642
msgid "yes"
msgstr ""

# 240b3fdc10284f7b9f59a74491c83ab3
# 572c131bbc5642af91df787f99052a9a
# 92b9d86b3b2449b48eb7a3c321c67fa5
# 19810dec53b741b2ba22f75f80c0bfb1
# 3e17dd823315419cab1bef1f88a67ad5
# 439f7330871b4aaf8397140cf3dd2804
# 56c8061c0c4043bda4e634c7e76185fc
# 90bfbc27826a43619a7cf39cc6f4ab1b
# b3b34c96477e42fc9eab9cbf0239d94e
# 24bb8d5dda2e436b9f3b007fa342124a
#: ../../tutorial.rst:637 ../../tutorial.rst:638 ../../tutorial.rst:639
#: ../../tutorial.rst:640 ../../tutorial.rst:641 ../../tutorial.rst:642
msgid "no"
msgstr ""

# 1f5cb4f69ac34c82bc39345f183c3fff
#: ../../tutorial.rst:638
msgid ":attr:`BaseRequest.forms`"
msgstr ""

# 09e1fea933664ebea0954efe295a1184
#: ../../tutorial.rst:639
msgid ":attr:`BaseRequest.files`"
msgstr ""

# 1f5cb4f69ac34c82bc39345f183c3fff
#: ../../tutorial.rst:640
msgid ":attr:`BaseRequest.params`"
msgstr ""

# d6ac10bbc1db4db5aff2ff6fcf62265e
#: ../../tutorial.rst:641
msgid ":attr:`BaseRequest.GET`"
msgstr ""

# d6ac10bbc1db4db5aff2ff6fcf62265e
#: ../../tutorial.rst:642
msgid ":attr:`BaseRequest.POST`"
msgstr ""

# 633e196fad4e4e8298aa83a76d0a7caf
#: ../../tutorial.rst:647
msgid "File uploads"
msgstr "文件上传"

# 6792263598664f43ac6070fef7d4d55f
#: ../../tutorial.rst:649
msgid ""
"To support file uploads, we have to change the ``<form>`` tag a bit. First, "
"we tell the browser to encode the form data in a different way by adding an "
"``enctype=\"multipart/form-data\"`` attribute to the ``<form>`` tag. Then, "
"we add ``<input type=\"file\" />`` tags to allow the user to select a file. "
"Here is an example:"
msgstr ""
"为了支持文件上传，我们需要小改一下上面 ``<form>`` 标签，加上 ``enctype="
"\"multipart/form-data\"`` 属性，告诉浏览器用另一种方式编码表单数据。接下来，"
"我们添加 ``<input type=\"file\" />`` 标签，让用户可以选择需要上传的文件。例子"
"如下。"

# 3c68df7ebfa84e12b277facd8dafc58d
#: ../../tutorial.rst:659
msgid ""
"Bottle stores file uploads in :attr:`BaseRequest.files` as :class:"
"`FileUpload` instances, along with some metadata about the upload. Let us "
"assume you just want to save the file to disk::"
msgstr ""
"Bottle将上传的文件当做一个 :class:`FileUpload` 实例存储在 :attr:`BaseRequest."
"files` 中，伴随着一些这次上传的元数据。我们假设你仅是想把上传的文件保存到磁盘"
"中。"

# 3a1c322545d341d7b32789db4fe0e9ef
#: ../../tutorial.rst:673
msgid ""
":attr:`FileUpload.filename` contains the name of the file on the clients "
"file system, but is cleaned up and normalized to prevent bugs caused by "
"unsupported characters or path segments in the filename. If you need the "
"unmodified name as sent by the client, have a look at :attr:`FileUpload."
"raw_filename`."
msgstr ""
":attr:`FileUpload.filename` 包含客户端传上来的文件的文件名，但为了防止异常字"
"符带来的bug，这里的文件名已经被处理过。如果你需要未经改动的文件名，看看 :"
"attr:`FileUpload.raw_filename` 。"

# 0edcb379b65c4a3da31b48439db2d3ec
#: ../../tutorial.rst:675
msgid ""
"The :attr:`FileUpload.save` method is highly recommended if you want to "
"store the file to disk. It prevents some common errors (e.g. it does not "
"overwrite existing files unless you tell it to) and stores the file in a "
"memory efficient way. You can access the file object directly via :attr:"
"`FileUpload.file`. Just be careful."
msgstr ""
"如果你想将文件保存到磁盘，强烈建议你使用 :attr:`FileUpload.save` 方法。它避免"
"了一些常见的错误（例如，它不会覆盖已经存在的文件，除非你告诉它可以覆盖），并"
"且更有效地使用内存。你可以通过 :attr:`FileUpload.file` 来直接访问文件对象，但"
"是要谨慎。"

# 00ebd6fbc91944adbb2f8ed5eba530c9
#: ../../tutorial.rst:679
msgid "JSON Content"
msgstr "JSON内容"

# 2b4bc0434c3647aab955774d47087a57
#: ../../tutorial.rst:681
msgid ""
"Some JavaScript or REST clients send ``application/json`` content to the "
"server. The :attr:`BaseRequest.json` attribute contains the parsed data "
"structure, if available."
msgstr ""
"一些JavaScript或支持REST的客户端会发送 ``application/json`` 内容给服务器。如"
"果可用（合法的JSON）， :attr:`BaseRequest.json` 会包含解析后的数据结构。"

# 04eb97e955474ed785db0dc3ef77ad21
#: ../../tutorial.rst:685
msgid "The raw request body"
msgstr "原始的请求数据"

# 1cc8541629fd442d829484ac6676626a
#: ../../tutorial.rst:687
msgid ""
"You can access the raw body data as a file-like object via :attr:"
"`BaseRequest.body`. This is a :class:`BytesIO` buffer or a temporary file "
"depending on the content length and :attr:`BaseRequest.MEMFILE_MAX` setting. "
"In both cases the body is completely buffered before you can access the "
"attribute. If you expect huge amounts of data and want to get direct "
"unbuffered access to the stream, have a look at ``request['wsgi.input']``."
msgstr ""
"你可以把  :attr:`BaseRequest.body` 当做一个file-like 对象来访问。根据内容的长"
"度，以及 :attr:`BaseRequest.MEMFILE_MAX` 中的设置，它可以是一个 :class:"
"`BytesIO` 缓存或一个磁盘上的临时文件。无论如何，它都是被缓存的。如果你无需缓"
"存，想直接访问文件流，可看看 ``request['wsgi.input']`` 。"

# 00ebd6fbc91944adbb2f8ed5eba530c9
#: ../../tutorial.rst:692
msgid "WSGI Environment"
msgstr "WSGI环境"

# 02742224d5ad42bb8ff01b10de6ab5e7
#: ../../tutorial.rst:694
msgid ""
"Each :class:`BaseRequest` instance wraps a WSGI environment dictionary. The "
"original is stored in :attr:`BaseRequest.environ`, but the request object "
"itself behaves like a dictionary, too. Most of the interesting data is "
"exposed through special methods or attributes, but if you want to access "
"`WSGI environ variables <WSGI specification>`_ directly, you can do so::"
msgstr ""
"每一个  :class:`BaseRequest` 类的实例都包含一个WSGI环境的字典。最初存储在 :"
"attr:`BaseRequest.environ` 中，但request对象也表现的像一个字典。大多数有用的"
"数据都通过特定的方法或属性暴露了出来，但如果你想直接访问 `WSGI环境变量 <WSGI "
"specification>`_ ，可以这样做::"

# c12824d94b3a4fbdbcaebc6618897d10
#: ../../tutorial.rst:712
msgid "Templates"
msgstr "模板"

# 3ee2e726eac14d9c994dde9fdaee5b39
#: ../../tutorial.rst:714
msgid ""
"Bottle comes with a fast and powerful built-in template engine called :doc:"
"`stpl`. To render a template you can use the :func:`template` function or "
"the :func:`view` decorator. All you have to do is to provide the name of the "
"template and the variables you want to pass to the template as keyword "
"arguments. Here’s a simple example of how to render a template::"
msgstr ""
"Bottle内置了一个快速的，强大的模板引擎，称为 :doc:`stpl` 。可通过 :func:"
"`template` 函数或 :func:`view` 修饰器来渲染一个模板。只需提供模板的名字和传递"
"给模板的变量。下面是一个渲染模板的简单例子::"

# a262870d7851494299ca7357419668b0
#: ../../tutorial.rst:721
msgid ""
"This will load the template file ``hello_template.tpl`` and render it with "
"the ``name`` variable set. Bottle will look for templates in the ``./views/"
"`` folder or any folder specified in the ``bottle.TEMPLATE_PATH`` list."
msgstr ""
"这会加载 ``hello_template.tpl`` 模板文件，并提供 ``name`` 变量。默认情况，"
"Bottle会在 ``./views/`` 目录查找模板文件(译者注：或当前目录)。可在 ``bottle."
"TEMPLATE_PATH`` 这个列表中添加更多的模板路径。"

# ed78b45085864fe7b5a0f6f708355177
#: ../../tutorial.rst:723
msgid ""
"The :func:`view` decorator allows you to return a dictionary with the "
"template variables instead of calling :func:`template`::"
msgstr ""
":func:`view` 修饰器允许你在回调函数中返回一个字典，并将其传递给模板，和 :"
"func:`template` 函数做同样的事情。"

# 99ab9dcde99e4d43a3990c3ad34f5c59
#: ../../tutorial.rst:732
msgid "Syntax"
msgstr "语法"

# 09cd302595e74ff8b713bc4f8bd96577
#: ../../tutorial.rst:735
msgid ""
"The template syntax is a very thin layer around the Python language. Its "
"main purpose is to ensure correct indentation of blocks, so you can format "
"your template without worrying about indentation. Follow the link for a full "
"syntax description: :doc:`stpl`"
msgstr ""
"模板语法类似于Python的语法。它要确保语句块的正确缩进，所以你在写模板的时候无"
"需担心会出现缩进问题。详细的语法描述可看 :doc:`stpl` 。"

# 6bba819ce04040a7a4075b08513d3914
#: ../../tutorial.rst:737
msgid "Here is an example template::"
msgstr "简单的模板例子::"

# f4e568a17e6e4a029d785713c1c10e4f
#: ../../tutorial.rst:748
msgid "Caching"
msgstr "缓存"

# 6abf5d3fe8704e84a667b3f7b35a92fb
#: ../../tutorial.rst:749
msgid ""
"Templates are cached in memory after compilation. Modifications made to the "
"template files will have no affect until you clear the template cache. Call "
"``bottle.TEMPLATES.clear()`` to do so. Caching is disabled in debug mode."
msgstr ""
"模板在经过编译后被缓存在内存里。你在修改模板文件后，要调用 ``bottle."
"TEMPLATES.clear()`` 函数清除缓存才能看到效果。在debug模式下，缓存被禁用了，无"
"需手动清除缓存。"

# a23c78bf8a2a4f27925d654bed8a8bb5
#: ../../tutorial.rst:759
msgid "Plugins"
msgstr "插件"

# 88060d08b1a949b898df6761368281fe
#: ../../tutorial.rst:763
msgid ""
"Bottle's core features cover most common use-cases, but as a micro-framework "
"it has its limits. This is where \"Plugins\" come into play. Plugins add "
"missing functionality to the framework, integrate third party libraries, or "
"just automate some repetitive work."
msgstr ""
"Bottle的核心功能覆盖了常见的使用情况，但是作为一个迷你框架，它有它的局限性。"
"所以我们引入了插件机制，插件可以给框架添加其缺少的功能，集成第三方的库，或是"
"自动化一些重复性的工作。"

# 38149a02d0a5465da9a9852e284a4f28
#: ../../tutorial.rst:765
msgid ""
"We have a growing :doc:`/plugins/index` and most plugins are designed to be "
"portable and re-usable across applications. The chances are high that your "
"problem has already been solved and a ready-to-use plugin exists. If not, "
"the :doc:`/plugindev` may help you."
msgstr ""
"我们有一个不断增长的 :doc:`/plugins/index` 插件列表，大多数插件都被设计为可插"
"拔的。有很大可能，你的问题已经被解决，而且已经有现成的插件可以使用了。如果没"
"有现成的插件， :doc:`/plugindev` 有介绍如何开发一个插件。"

# f2e682f4d04b4b8ebc16edcb8caf47a4
#: ../../tutorial.rst:767
msgid ""
"The effects and APIs of plugins are manifold and depend on the specific "
"plugin. The ``SQLitePlugin`` plugin for example detects callbacks that "
"require a ``db`` keyword argument and creates a fresh database connection "
"object every time the callback is called. This makes it very convenient to "
"use a database::"
msgstr ""
"插件扮演着各种各样的角色。例如， ``SQLitePlugin`` 插件给每个route的回调函数都"
"添加了一个 ``db`` 参数，在回调函数被调用的时候，会新建一个数据库连接。这样，"
"使用数据库就非常简单了。"

# 8ba3a92375604cd1bc2c55e8fe88b7c6
#: ../../tutorial.rst:787
msgid ""
"Other plugin may populate the thread-safe :data:`local` object, change "
"details of the :data:`request` object, filter the data returned by the "
"callback or bypass the callback completely. An \"auth\" plugin for example "
"could check for a valid session and return a login page instead of calling "
"the original callback. What happens exactly depends on the plugin."
msgstr ""
"其它插件或许在线程安全的 :data:`local` 对象里面发挥作用，改变 :data:"
"`request` 对象的细节，过滤回调函数返回的数据或完全绕开回调函数。举个例子，一"
"个用于登录验证的插件会在调用原先的回调函数响应请求之前，验证用户的合法性，如"
"果是非法访问，则返回登录页面而不是调用回调函数。具体的做法要看插件是如何实现"
"的。"

# 9679a5cc51d944af9e76e1e461c73a0b
#: ../../tutorial.rst:791
msgid "Application-wide Installation"
msgstr "整个应用的范围内安装插件"

# 216747200f3146418ab3633e0f2e1e13
#: ../../tutorial.rst:793
msgid ""
"Plugins can be installed application-wide or just to some specific routes "
"that need additional functionality. Most plugins can safely be installed to "
"all routes and are smart enough to not add overhead to callbacks that do not "
"need their functionality."
msgstr ""
"可以在整个应用的范围内安装插件，也可以只是安装给某些route。大多数插件都可安全"
"地安装给所有route，也足够智能，可忽略那些并不需要它们的route。"

# 9764f2ecd5594b57b040ec177c1460da
#: ../../tutorial.rst:795
msgid ""
"Let us take the ``SQLitePlugin`` plugin for example. It only affects route "
"callbacks that need a database connection. Other routes are left alone. "
"Because of this, we can install the plugin application-wide with no "
"additional overhead."
msgstr ""
"让我们拿 ``SQLitePlugin`` 插件举例，它只会影响到那些需要数据库连接的route，其"
"它route都被忽略了。正因为如此，我们可以放心地在整个应用的范围内安装这个插件。"

# ffcfd7ecba4841939dade7327353c8dc
#: ../../tutorial.rst:797
msgid ""
"To install a plugin, just call :func:`install` with the plugin as first "
"argument::"
msgstr "调用 :func:`install` 函数来安装一个插件::"

# 43812d9787b84f90a4a0102fd4a48431
#: ../../tutorial.rst:802
msgid ""
"The plugin is not applied to the route callbacks yet. This is delayed to "
"make sure no routes are missed. You can install plugins first and add routes "
"later, if you want to. The order of installed plugins is significant, "
"though. If a plugin requires a database connection, you need to install the "
"database plugin first."
msgstr ""
"插件没有马上应用到所有route上面，它被延迟执行来确保没有遗漏任何route。你可以"
"先安装插件，再添加route。有时，插件的安装顺序很重要，如果另外一个插件需要连接"
"数据库，那么你就需要先安装操作数据库的插件。"

# a24315f350254ca1b76d8cef343326c3
#: ../../tutorial.rst:806
msgid "Uninstall Plugins"
msgstr "卸载插件"

# 74aefe2ba5704f2d86ec09a12d1e8c93
#: ../../tutorial.rst:807
msgid ""
"You can use a name, class or instance to :func:`uninstall` a previously "
"installed plugin::"
msgstr "调用 :func:`uninstall` 函数来卸载已经安装的插件"

# a8e7d4f099d1483d9e837c9ebae15229
#: ../../tutorial.rst:817
msgid ""
"Plugins can be installed and removed at any time, even at runtime while "
"serving requests. This enables some neat tricks (installing slow debugging "
"or profiling plugins only when needed) but should not be overused. Each time "
"the list of plugins changes, the route cache is flushed and all plugins are "
"re-applied."
msgstr ""
"在任何时候，插件都可以被安装或卸载，即使是在服务器正在运行的时候。一些小技巧"
"应用到了这个特征，例如在需要的时候安装一些供debug和性能测试的插件，但不可滥用"
"这个特性。每一次安装或卸载插件的时候，route缓存都会被刷新，所有插件被重新加"
"载。"

# d653b077c8cd432b9dea61f859deaf2a
#: ../../tutorial.rst:820
msgid ""
"The module-level :func:`install` and :func:`uninstall` functions affect the :"
"ref:`default-app`. To manage plugins for a specific application, use the "
"corresponding methods on the :class:`Bottle` application object."
msgstr ""
"模块层面的 :func:`install` 和 :func:`unistall` 函数会影响 :ref:`default-"
"app` 。针对应用来管理插件，可使用 :class:`Bottle` 应用对象的相应方法。"

# 243f252439a14fd980528d11dc2a5ef3
#: ../../tutorial.rst:824
msgid "Route-specific Installation"
msgstr "安装给特定的route"

# 838aae12dff54ecca70e4b9929c377a7
#: ../../tutorial.rst:826
msgid ""
"The ``apply`` parameter of the :func:`route` decorator comes in handy if you "
"want to install plugins to only a small number of routes::"
msgstr ":func:`route` 修饰器的 ``apply`` 参数可以给指定的route安装插件"

# 9a84759774fe4f40a9ca78198ee213a5
#: ../../tutorial.rst:836
msgid "Blacklisting Plugins"
msgstr "插件黑名单"

# 6a0ab06186804e1d8bbe63a231a7c5d0
#: ../../tutorial.rst:838
msgid ""
"You may want to explicitly disable a plugin for a number of routes. The :"
"func:`route` decorator has a ``skip`` parameter for this purpose::"
msgstr ""
"如果你想显式地在一些route上面禁用某些插件，可使用 :func:`route` 修饰器的 "
"``skip`` 参数::"

# 4f2c00ad89e74770be416ad7bbae1bee
#: ../../tutorial.rst:860
msgid ""
"The ``skip`` parameter accepts a single value or a list of values. You can "
"use a name, class or instance to identify the plugin that is to be skipped. "
"Set ``skip=True`` to skip all plugins at once."
msgstr ""
"``skip`` 参数接受单一的值或是一个list。你可使用插件的名字，类，实例来指定你想"
"要禁用的插件。如果 ``skip`` 的值为True，则禁用所有插件。"

# d87dd978a89d43868cb463a1a2190830
#: ../../tutorial.rst:863
msgid "Plugins and Sub-Applications"
msgstr "插件和子应用"

# 3d4b2c7941c849f7909c988ec94594b9
#: ../../tutorial.rst:865
msgid ""
"Most plugins are specific to the application they were installed to. "
"Consequently, they should not affect sub-applications mounted with :meth:"
"`Bottle.mount`. Here is an example::"
msgstr ""
"大多数插件只会影响到安装了它们的应用。因此，它们不应该影响通过 :meth:`Bottle."
"mount` 方法挂载上来的子应用。这里有一个例子。"

# 4b73aeba0920406595cca49309022d40
#: ../../tutorial.rst:876
msgid ""
"Whenever you mount an application, Bottle creates a proxy-route on the main-"
"application that forwards all requests to the sub-application. Plugins are "
"disabled for this kind of proxy-route by default. As a result, our "
"(fictional) `WTForms` plugin affects the ``/contact`` route, but does not "
"affect the routes of the ``/blog`` sub-application."
msgstr ""
"在你挂载一个应用的时候，Bottle在主应用上面创建一个代理route，将所有请求转接给"
"子应用。在代理route上，默认禁用了插件。如上所示，我们的 ``WTForms`` 插件影响"
"了 ``/contact`` route，但不会影响挂载在root上面的 ``/blog`` 。"

# b7358bc6de3141de8ee22c6f437c05e2
#: ../../tutorial.rst:878
msgid ""
"This behavior is intended as a sane default, but can be overridden. The "
"following example re-activates all plugins for a specific proxy-route::"
msgstr ""
"这个是一个合理的行为，但可被改写。下面的例子，在指定的代理route上面应用了插"
"件。"

# e3e8120e6e2f4f0caa98e2facc17f5f9
#: ../../tutorial.rst:882
msgid ""
"But there is a snag: The plugin sees the whole sub-application as a single "
"route, namely the proxy-route mentioned above. In order to affect each "
"individual route of the sub-application, you have to install the plugin to "
"the mounted application explicitly."
msgstr ""
"这里存在一个小难题: 插件会整个子应用当作一个route看待，即是上面提及的代理"
"route。如果想在子应用的每个route上面应用插件，你必须显式地在子应用上面安装插"
"件。"

# 6a3062e368f74a49bcd5a9aee9c27f1d
#: ../../tutorial.rst:887
msgid "Development"
msgstr "开发"

# f171d35ca9c640958adf39b6600ef7d1
#: ../../tutorial.rst:889
msgid ""
"So you have learned the basics and want to write your own application? Here "
"are some tips that might help you to be more productive."
msgstr ""
"到目前为止，你已经学到一些开发的基础，并想写你自己的应用了吧？这里有一些小技"
"巧可提高你的生产力。"

# f08de7bd8585473ba505d5471a1f4b95
#: ../../tutorial.rst:895
msgid "Default Application"
msgstr "默认应用"

# b08fcbe75c2740baa96374ade2061c40
#: ../../tutorial.rst:897
msgid ""
"Bottle maintains a global stack of :class:`Bottle` instances and uses the "
"top of the stack as a default for some of the module-level functions and "
"decorators. The :func:`route` decorator, for example, is a shortcut for "
"calling :meth:`Bottle.route` on the default application::"
msgstr ""
"Bottle维护一个全局的 :class:`Bottle` 实例的栈，模块层面的函数和修饰器使用栈顶"
"实例作为默认应用。例如 :func:`route` 修饰器，相当于在默认应用上面调用了 :"
"meth:`Bottle.route` 方法。"

# 8115e9c107c64e50a46fa7dbbcebafd8
#: ../../tutorial.rst:903
msgid ""
"This is very convenient for small applications and saves you some typing, "
"but also means that, as soon as your module is imported, routes are "
"installed to the global application. To avoid this kind of import side-"
"effects, Bottle offers a second, more explicit way to build applications::"
msgstr ""
"对于小应用来说，这样非常方便，可节约你的工作量。但这同时意味着，在你的模块导"
"入的时候，你定义的route就被安装到全局的默认应用中了。为了避免这种模块导入的副"
"作用，Bottle提供了另外一种方法，显式地管理应用。"

# 564c8e3eee454f6e99c594739eadda07
#: ../../tutorial.rst:911
msgid ""
"Separating the application object improves re-usability a lot, too. Other "
"developers can safely import the ``app`` object from your module and use :"
"meth:`Bottle.mount` to merge applications together."
msgstr ""
"分离应用对象，大大提高了可重用性。其他开发者可安全地从你的应用中导入 ``app`` "
"对象，然后通过 :meth:`Bottle.mount` 方法来合并到其它应用中。"

# 8d144a16824c4b9badfac96807f984a3
#: ../../tutorial.rst:913
msgid ""
"As an alternative, you can make use of the application stack to isolate your "
"routes while still using the convenient shortcuts::"
msgstr ""
"作为一种选择，你可通过应用栈来隔离你的route，依然使用方便的 ``route`` 修饰"
"器。"

# de0c34efbab94c38be0a30cdce342f7a
#: ../../tutorial.rst:923
msgid ""
"Both :func:`app` and :func:`default_app` are instance of :class:`AppStack` "
"and implement a stack-like API. You can push and pop applications from and "
"to the stack as needed. This also helps if you want to import a third party "
"module that does not offer a separate application object::"
msgstr ""
":func:`app` 和 :func:`default_app` 都是 :class:`AppStack` 类的一个实例，实现"
"了栈形式的API操作。你可push应用到栈里面，也可将栈里面的应用pop出来。在你需要"
"导入一个第三方模块，但它不提供一个独立的应用对象的时候，尤其有用。"

# ba511473ecbf415392b54d39a5b0f8fa
#: ../../tutorial.rst:936
msgid "Debug Mode"
msgstr "调试模式"

# beddc97c3d3a46128d1d358fa9860a4f
#: ../../tutorial.rst:938
msgid "During early development, the debug mode can be very helpful."
msgstr "在开发的早期阶段，调试模式非常有用。"

# 4d067f735f6849c69b69f7092ced9f3d
#: ../../tutorial.rst:946
msgid ""
"In this mode, Bottle is much more verbose and provides helpful debugging "
"information whenever an error occurs. It also disables some optimisations "
"that might get in your way and adds some checks that warn you about possible "
"misconfiguration."
msgstr ""
"在调试模式下，当错误发生的时候，Bottle会提供更多的调试信息。同时禁用一些可能"
"妨碍你的优化措施，检查你的错误设置。"

# 88a7c01d66fa4d00a6179489511b3c08
#: ../../tutorial.rst:948
msgid "Here is an incomplete list of things that change in debug mode:"
msgstr "下面是调试模式下会发生改变的东西，但这份列表不完整:"

# f198b02a8b9e4bcba922758c41b795a0
#: ../../tutorial.rst:950
msgid "The default error page shows a traceback."
msgstr "默认的错误页面会打印出运行栈。"

# 0c8afe5235804e03ba1bfbb6eb3345a9
#: ../../tutorial.rst:951
msgid "Templates are not cached."
msgstr "模板不会被缓存。"

# c606f72bfa8d4612baecaa76fa2c6a03
#: ../../tutorial.rst:952
msgid "Plugins are applied immediately."
msgstr "插件马上生效。"

# 36c92c3f00344262bb9ec61582c0a45a
#: ../../tutorial.rst:954
msgid "Just make sure not to use the debug mode on a production server."
msgstr "请确保不要在生产环境中使用调试模式。"

# 633e196fad4e4e8298aa83a76d0a7caf
#: ../../tutorial.rst:957
msgid "Auto Reloading"
msgstr "自动加载"

# 06cefa78a7b0460db417d659b6de9d0c
#: ../../tutorial.rst:959
msgid ""
"During development, you have to restart the server a lot to test your recent "
"changes. The auto reloader can do this for you. Every time you edit a module "
"file, the reloader restarts the server process and loads the newest version "
"of your code."
msgstr ""
"在开发的时候，你需要不断地重启服务器来验证你最新的改动。自动加载功能可以替你"
"做这件事情。在你编辑完一个模块文件后，它会自动重启服务器进程，加载最新版本的"
"代码。"

# e1789e3508fc4464bc48179d68195f5d
#: ../../tutorial.rst:969
msgid ""
"How it works: the main process will not start a server, but spawn a new "
"child process using the same command line arguments used to start the main "
"process. All module-level code is executed at least twice! Be careful."
msgstr ""
"它的工作原理，主进程不会启动服务器，它使用相同的命令行参数，创建一个子进程来"
"启动服务器。请注意，所有模块级别的代码都被执行了至少两次。"

# 0371ddb9c20e4305af0b378bd25be6a5
#: ../../tutorial.rst:974
msgid ""
"The child process will have ``os.environ['BOTTLE_CHILD']`` set to ``True`` "
"and start as a normal non-reloading app server. As soon as any of the loaded "
"modules changes, the child process is terminated and re-spawned by the main "
"process. Changes in template files will not trigger a reload. Please use "
"debug mode to deactivate template caching."
msgstr ""
"子进程中 ``os.environ['BOOTLE_CHILD']`` 变量的值被设为 ``True`` ，它运行一个"
"不会自动加载的服务器。在代码改变后，主进程会终止掉子进程，并创建一个新的子进"
"程。更改模板文件不会触发自动重载，请使用debug模式来禁用模板缓存。"

# a0aa2201b61c42e98e5ee42ef24c4190
#: ../../tutorial.rst:980
msgid ""
"The reloading depends on the ability to stop the child process. If you are "
"running on Windows or any other operating system not supporting ``signal."
"SIGINT`` (which raises ``KeyboardInterrupt`` in Python), ``signal.SIGTERM`` "
"is used to kill the child. Note that exit handlers and finally clauses, "
"etc., are not executed after a ``SIGTERM``."
msgstr ""
"自动加载需要终止子进程。如果你运行在Windows等不支持 ``signal.SIGINT`` (会在"
"Python中raise ``KeyboardInterrupt`` 异常)的系统上，会使用 ``signal.SIGTERM`` "
"来杀掉子进程。在子进程被 ``SIGTERM`` 杀掉的时候，exit handlers和finally等语句"
"不会被执行。"

# f8ff70c41030429b97bbe90c183aa69d
#: ../../tutorial.rst:988
msgid "Command Line Interface"
msgstr "命令行接口"

# fffbd64ca6b24cbfaa416c3041d9e0b1
#: ../../tutorial.rst:992
msgid "Starting with version 0.10 you can use bottle as a command-line tool:"
msgstr "从0.10版本开始，你可像一个命令行工具那样使用Bottle:"

# a8137a8b8a854600add6c7567b68a739
#: ../../tutorial.rst:1012
msgid ""
"The `ADDRESS` field takes an IP address or an IP:PORT pair and defaults to "
"``localhost:8080``. The other parameters should be self-explanatory."
msgstr ""
"`ADDRESS` 参数接受一个IP地址或IP:端口，其默认为 ``localhost:8080`` 。其它参数"
"都很好地自我解释了。"

# 228d8cb4991f41f4b4d8b33ccde95c44
#: ../../tutorial.rst:1014
msgid ""
"Both plugins and applications are specified via import expressions. These "
"consist of an import path (e.g. ``package.module``) and an expression to be "
"evaluated in the namespace of that module, separated by a colon. See :func:"
"`load` for details. Here are some examples:"
msgstr ""
"插件和应用都通过一个导入表达式来指定。包含了导入的路径(例如: ``package."
"module`` )和模块命名空间内的一个表达式，两者用\":\"分开。下面是一个简单例子，"
"详见 :func:`load` 。"

# 3311bcf9b73946988bec85594383ecc6
#: ../../tutorial.rst:1035
msgid "Deployment"
msgstr "部署"

# 2af7083bba10428a97d840be3af4a90f
#: ../../tutorial.rst:1037
msgid ""
"Bottle runs on the built-in `wsgiref WSGIServer <http://docs.python.org/"
"library/wsgiref.html#module-wsgiref.simple_server>`_  by default. This non-"
"threading HTTP server is perfectly fine for development and early "
"production, but may become a performance bottleneck when server load "
"increases."
msgstr ""
"Bottle默认运行在内置的 `wsgiref <http://docs.python.org/library/wsgiref."
"html#module-wsgiref.simple_server>`_  服务器上面。这个单线程的HTTP服务器在开"
"发的时候特别有用，但其性能低下，在服务器负载不断增加的时候也许会是性能瓶颈。"

# 3b8f093cb75247ba98703d3f6a53b38e
#: ../../tutorial.rst:1039
msgid ""
"The easiest way to increase performance is to install a multi-threaded "
"server library like paste_ or cherrypy_ and tell Bottle to use that instead "
"of the single-threaded server::"
msgstr "最早的解决办法是让Bottle使用 paste_ 或 cherrypy_ 等多线程的服务器。"

# 2dab1b2ba89e4d33992277160d0591bf
#: ../../tutorial.rst:1043
msgid ""
"This, and many other deployment options are described in a separate "
"article: :doc:`deployment`"
msgstr "在 :doc:`deployment` 章节中，会介绍更多部署的选择。"

# f6100b0c14874bf28a2fe2009fae3846
#: ../../tutorial.rst:1051
msgid "Glossary"
msgstr "词汇表"

# c6dd388daca143bfbebc280aeb9ea3f2
#: ../../tutorial.rst:1056
msgid ""
"Programmer code that is to be called when some external action happens. In "
"the context of web frameworks, the mapping between URL paths and application "
"code is often achieved by specifying a callback function for each URL."
msgstr ""

# bea77197d67b495893c30d13330807de
#: ../../tutorial.rst:1062
msgid ""
"A function returning another function, usually applied as a function "
"transformation using the ``@decorator`` syntax. See `python documentation "
"for function definition  <http://docs.python.org/reference/compound_stmts."
"html#function>`_ for more about decorators."
msgstr ""

# 4e70beaf89764630a38c322f4ae47a54
#: ../../tutorial.rst:1065
msgid ""
"A structure where information about all documents under the root is saved, "
"and used for cross-referencing.  The environment is pickled after the "
"parsing stage, so that successive runs only need to read and parse new and "
"changed documents."
msgstr ""

# b7f08dcc64534616abcba37e70692e71
#: ../../tutorial.rst:1071
msgid ""
"A function to handle some specific event or situation. In a web framework, "
"the application is developed by attaching a handler function as callback for "
"each specific URL comprising the application."
msgstr ""

# 1693168184a043dc8b28ea6fc35aa2aa
#: ../../tutorial.rst:1076
msgid ""
"The directory which, including its subdirectories, contains all source files "
"for one Sphinx project."
msgstr ""
