# 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: 2012-11-09 18:23\n"
"PO-Revision-Date: 2012-11-09 16:53+0800\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\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"

# bb43bbad2c9f40409a2e100421b6f131
#: ../../plugindev.rst:6
msgid "Plugin Development Guide"
msgstr "插件开发指南"

# 3bcf439c643c4b428db9ea0e85ab54b1
#: ../../plugindev.rst:8
msgid ""
"This guide explains the plugin API and how to write custom plugins. I "
"suggest reading :ref:`plugins` first if you have not done that already. You "
"might also want to have a look at the :doc:`/plugins/index` for some "
"practical examples."
msgstr ""
"这份指南介绍了插件的API，以及如何编写自己的插件。我建议先阅读 :ref:`plugins` "
"这一部分，再看这份指南。 :doc:`/plugins/index` 这里也有一些实际的例子。"

# 9c93905a1e12432a98c28594f77466d5
#: ../../plugindev.rst:12
msgid ""
"This is a draft. If you see any errors or find that a specific part is not "
"explained clear enough, please tell the `mailing-list <mailto:"
"bottlepy@googlegroups.com>`_ or file a `bug report <https://github.com/"
"defnull/bottle/issues>`_."
msgstr ""
"这是一份初稿。如果你发现了任何错误，或某些部分解释的不够清楚，请通过 `邮件列"
"表 <mailto:bottlepy@googlegroups.com>`_ 或  `bug report <https://github.com/"
"defnull/bottle/issues>`_ 告知。"

# 070f3ff0fa644258b9d14ac422645f9d
#: ../../plugindev.rst:16
msgid "How Plugins Work: The Basics"
msgstr "插件工作方式：基础知识"

# b7e6c02814fb4f45bd66a4a8be53ff56
#: ../../plugindev.rst:18
msgid ""
"The plugin API builds on the concept of `decorators <http://docs.python.org/"
"glossary.html#term-decorator>`_. To put it briefly, a plugin is a decorator "
"applied to every single route callback of an application."
msgstr ""
"插件的API是通过Python的 `修饰器 <http://docs.python.org/glossary.html#term-"
"decorator>`_ 来实现的。简单来说，一个插件就是应用在route回调函数上的修饰器。"

# 2ce1e4f3e1c04fdcb045acfd0f9a244f
#: ../../plugindev.rst:20
msgid ""
"Of course, this is just a simplification. Plugins can do a lot more than "
"just decorating route callbacks, but it is a good starting point. Lets have "
"a look at some code::"
msgstr ""
"当然，例子被我们简化了，除了作为route的回调函数修饰器，插件还可以做更多的事"
"情，先看看代码吧。"

# 52348d8e4b494550ab5b1cf67636a17b
#: ../../plugindev.rst:36
msgid ""
"This plugin measures the execution time for each request and adds an "
"appropriate ``X-Exec-Time`` header to the response. As you can see, the "
"plugin returns a wrapper and the wrapper calls the original callback "
"recursively. This is how decorators usually work."
msgstr ""
"这个插件计算每次请求的响应时间，并在响应头中添加了 ``X-Exec-Time`` 字段。如你"
"所见，插件返回了一个wrapper函数，由它来调用原先的回调函数。这就是修饰器的常见"
"工作方式了。"

# b242da547a104cd09501d97a847d95cc
#: ../../plugindev.rst:38
msgid ""
"The last line tells Bottle to install the plugin to the default application. "
"This causes the plugin to be automatically applied to all routes of that "
"application. In other words, ``stopwatch()`` is called once for each route "
"callback and the return value is used as a replacement for the original "
"callback."
msgstr ""
"最后一行，将该插件安装到Bottle的默认应用里面。这样，应用中的所有route都会应用"
"这个插件了。就是说，每次请求都会调用 ``stopwatch()`` ，更改了route的默认行"
"为。"

# e0b29127180945cbaf760ce3209d567f
#: ../../plugindev.rst:40
msgid ""
"Plugins are applied on demand, that is, as soon as a route is requested for "
"the first time. For this to work properly in multi-threaded environments, "
"the plugin should be thread-safe. This is not a problem most of the time, "
"but keep it in mind."
msgstr ""
"插件是按需加载的，就是在route第一次被访问的时候加载。为了在多线程环境下工作，"
"插件应该是线程安全的。在大多数情况下，这都不是一个问题，但务必提高警惕。"

# 514e9d27690249f48c823fb987b2e687
#: ../../plugindev.rst:42
msgid ""
"Once all plugins are applied to a route, the wrapped callback is cached and "
"subsequent requests are handled by the cached version directly. This means "
"that a plugin is usually applied only once to a specific route. That cache, "
"however, is cleared every time the list of installed plugins changes. Your "
"plugin should be able to decorate the same route more than once."
msgstr ""
"一旦route中使用了插件后，插件中的回调函数会被缓存起来，接下来都是直接使用缓存"
"中的版本来响应请求。意味着每个route只会请求一次插件。在应用的插件列表变化的时"
"候，这个缓存会被清空。你的插件应当可以多次修饰同一个route。"

# a05a3b4288e44bdba23f95d396019402
#: ../../plugindev.rst:44
msgid ""
"The decorator API is quite limited, though. You don't know anything about "
"the route being decorated or the associated application object and have no "
"way to efficiently store data that is shared among all routes. But fear not! "
"Plugins are not limited to just decorator functions. Bottle accepts anything "
"as a plugin as long as it is callable or implements an extended API. This "
"API is described below and gives you a lot of control over the whole process."
msgstr ""
"这种修饰器般的API受到种种限制。你不知道route或相应的应用对象是如何被修饰的，"
"也不知道如何有效地存储那些在route之间共享的数据。但别怕！插件不仅仅是修饰器函"
"数。只要一个插件是callable的或实现了一个扩展的API(后面会讲到)，Bottle都可接"
"受。扩展的API给你更多的控制权。"

# 69f3793594344919a10ec0f685d0ea0b
#: ../../plugindev.rst:48
msgid "Plugin API"
msgstr "插件API"

# b751b860e5d14e4f9a8f0c69bcb99dd4
#: ../../plugindev.rst:50
msgid ""
":class:`Plugin` is not a real class (you cannot import it from :mod:"
"`bottle`) but an interface that plugins are expected to implement. Bottle "
"accepts any object of any type as a plugin, as long as it conforms to the "
"following API."
msgstr ""
"``Plugin`` 类不是一个真正的类(你不能从bottle中导入它)，它只是一个插件需要实现"
"的接口。只要一个对象实现了以下接口，Bottle就认可它作为一个插件。"

# 074bb64c69e34d9692518ab96751d7d5
#: ../../plugindev.rst:54
msgid ""
"Plugins must be callable or implement :meth:`apply`. If :meth:`apply` is "
"defined, it is always preferred over calling the plugin directly. All other "
"methods and attributes are optional."
msgstr ""
"插件应该是callable的，或实现了 :meth:`apply` 方法。如果定义了 :meth:`apply` "
"方法，那么会优先调用，而不是直接调用插件。其它的方法和属性都是可选的。"

# 1c36097519c8436792e560b415027012
#: ../../plugindev.rst:58
msgid ""
"Both :meth:`Bottle.uninstall` and the `skip` parameter of :meth:`Bottle.route"
"()` accept a name string to refer to a plugin or plugin type. This works "
"only for plugins that have a name attribute."
msgstr ""
":meth:`Bottle.uninstall` 方法和 :meth:`Bottle.route()` 中的 `skip` 参数都接受"
"一个与名字有关的字符串，对应插件或其类型。只有插件中有一个name属性的时候，这"
"才会起作用。"

# 7519c49ad1c4476686d46bdcd9521e43
#: ../../plugindev.rst:62
msgid ""
"The Plugin API is still evolving. This integer attribute tells bottle which "
"version to use. If it is missing, bottle defaults to the first version. The "
"current version is ``2``. See :ref:`plugin-changelog` for details."
msgstr ""
"插件的API还在逐步改进。这个整形数告诉Bottle使用哪个版本的插件。如果没有这个属"
"性，Bottle默认使用第一个版本。当前版本是 ``2`` 。详见 :ref:`plugin-"
"changelog` 。"

# b0b3c33b82d54bc8b46810a2fb4c09f4
#: ../../plugindev.rst:66
msgid ""
"Called as soon as the plugin is installed to an application (see :meth:"
"`Bottle.install`). The only parameter is the associated application object."
msgstr ""
"插件被安装的时候调用(见 :meth:`Bottle.install` )。唯一的参数是相应的应用对"
"象。"

# 5db19fb886794c80b812675bff866360
#: ../../plugindev.rst:70
msgid ""
"As long as :meth:`apply` is not defined, the plugin itself is used as a "
"decorator and applied directly to each route callback. The only parameter is "
"the callback to decorate. Whatever is returned by this method replaces the "
"original callback. If there is no need to wrap or replace a given callback, "
"just return the unmodified callback parameter."
msgstr ""
"如果没有定义 :meth:`apply` 方法，插件本身会被直接当成一个修饰器使用(译者注："
"Python的Magic Method，调用一个类即是调用类的__call__函数)，应用到各个route。"
"唯一的参数就是其所修饰的函数。这个方法返回的东西会直接替换掉原先的回调函数。"
"如果无需如此，则直接返回未修改过的回调函数即可。"

# 1efb205aaea44987b177c52065696000
#: ../../plugindev.rst:74
msgid ""
"If defined, this method is used in favor of :meth:`__call__` to decorate "
"route callbacks. The additional `route` parameter is an instance of :class:"
"`Route` and provides a lot of meta-information and context for that route. "
"See :ref:`route-context` for details."
msgstr ""
"如果存在，会优先调用，而不调用 :meth:`__call__` 。额外的 `route` 参数是 :"
"class:`Route` 类的一个实例，提供很多该route信息和上下文。详见 :ref:`route-"
"context` 。"

# 3219b6a79df74090b7f27f64ccd457c3
#: ../../plugindev.rst:78
msgid ""
"Called immediately before the plugin is uninstalled or the application is "
"closed (see :meth:`Bottle.uninstall` or :meth:`Bottle.close`)."
msgstr ""
"插件被卸载或应用关闭的时候被调用，详见 :meth:`Bottle.uninstall` 或 :meth:"
"`Bottle.close` 。"

# e7506f2c8ba14320a7c83c27edee146a
#: ../../plugindev.rst:81
msgid ""
"Both :meth:`Plugin.setup` and :meth:`Plugin.close` are *not* called for "
"plugins that are applied directly to a route via the :meth:`Bottle.route()` "
"decorator, but only for plugins installed to an application."
msgstr ""
":meth:`Plugin.setup` 方法和 :meth:`Plugin.close` 方法 *不* 会被调用，如果插件"
"是通过 :meth:`Bottle.route` 方法来应用到route上面的，但会在安装插件的时候被调"
"用。"

# 23cd89defb0347bfafc861737f2a6391
#: ../../plugindev.rst:87
msgid "Plugin API changes"
msgstr "插件API的改动"

# 64d02d035ad84cf58ad3e685f4b5d664
#: ../../plugindev.rst:89
msgid ""
"The Plugin API is still evolving and changed with Bottle 0.10 to address "
"certain issues with the route context dictionary. To ensure backwards "
"compatibility with 0.9 Plugins, we added an optional :attr:`Plugin.api` "
"attribute to tell bottle which API to use. The API differences are "
"summarized here."
msgstr ""
"插件的API还在不断改进中。在Bottle 0.10版本中的改动，定位了route上下文字典中已"
"确定的问题。为了保持对0.9版本插件的兼容，我们添加了一个可选的 :attr:`Plugin."
"api` 属性，告诉Bottle使用哪个版本的API。API之间的不同点总结如下。"

# 5cfb3972268a46bcac7737574cf28d30
#: ../../plugindev.rst:91
msgid "**Bottle 0.9 API 1** (:attr:`Plugin.api` not present)"
msgstr "**Bottle 0.9 API 1** (无 :attr:`Plugin.api` 属性)"

# 10220570c5a948b6bbc9370c234c2ca6
#: ../../plugindev.rst:93
msgid "Original Plugin API as described in the 0.9 docs."
msgstr ""

# abb3757c12b34c44928fe38108781f7c
#: ../../plugindev.rst:95
msgid "**Bottle 0.10 API 2** (:attr:`Plugin.api` equals 2)"
msgstr "**Bottle 0.10 API 2** ( :attr:`Plugin.api` 属性为2)"

# 744b13efbf7c4e759fe842d390846ad5
#: ../../plugindev.rst:97
msgid ""
"The `context` parameter of the :meth:`Plugin.apply` method is now an "
"instance of :class:`Route` instead of a context dictionary."
msgstr ""
" :meth:`Plugin.apply` 方法中的 `context` 参数，现在是 :class:`Route` 类的一个"
"实例，不再是一个上下文字典。"

# 1d073dfc21c14a66b6e374e4f1c50912
#: ../../plugindev.rst:103
msgid "The Route Context"
msgstr "Route上下文"

# a89bc18faad44164bc54d2fc4ca2cd7b
#: ../../plugindev.rst:105
msgid ""
"The :class:`Route` instance passed to :meth:`Plugin.apply` provides detailed "
"informations about the associated route. The most important attributes are "
"summarized here:"
msgstr ""
":class:`Route` 的实例被传递给 :meth:`Plugin.apply` 函数，以提供更多该route的"
"相关信息。最重要的属性总结如下。"

# b4bc9d029439417ab59cf1f8c91af888
#: ../../plugindev.rst:108
msgid "Attribute"
msgstr "属性"

# 1bbff8f6d1b048659dff891d4498f7f6
#: ../../plugindev.rst:108
msgid "Description"
msgstr "描述"

# c7fc4520c531481586ae783da17010ac
#: ../../plugindev.rst:110
msgid "app"
msgstr ""

# b6c4971342654f0db83ee30c69e1459e
#: ../../plugindev.rst:110
msgid "The application object this route is installed to."
msgstr "安装该route的应用对象"

# 51140a3d362a4b1ab54f78a8a0178872
#: ../../plugindev.rst:111
msgid "rule"
msgstr ""

# b753acc47aa34713809385ecc448577c
#: ../../plugindev.rst:111
msgid "The rule string (e.g. ``/wiki/:page``)."
msgstr "route规则的字符串 (例如： ``/wiki/:page``)"

# 294f892e7a4445888a6d62fcdc03934a
#: ../../plugindev.rst:112
msgid "method"
msgstr ""

# fe67b10550a24e8ea7d3e736c270b74b
#: ../../plugindev.rst:112
msgid "The HTTP method as a string (e.g. ``GET``)."
msgstr "HTTP方法的字符串(例如： ``GET``)"

# 22065ffdd5e348c18b22bd1b3b4fabde
#: ../../plugindev.rst:113
msgid "callback"
msgstr ""

# 4a518bf76c4b440d81457e7c89fb1cd8
#: ../../plugindev.rst:113
msgid ""
"The original callback with no plugins applied. Useful for introspection."
msgstr "未应用任何插件的原始回调函数，用于内省。"

# 82c51209242e4659b6cff3066407ade1
#: ../../plugindev.rst:115
msgid "name"
msgstr ""

# 6608162803a84149b0d3209e83c529c0
#: ../../plugindev.rst:115
msgid "The name of the route (if specified) or ``None``."
msgstr "route的名字，如未指定则为 ``None``"

# cccace76be07444d8614e3c5f6ac7521
#: ../../plugindev.rst:116
msgid "plugins"
msgstr ""

# cd12629c455c4df8a5599035f319bfe7
#: ../../plugindev.rst:116
msgid ""
"A list of route-specific plugins. These are applied in addition to "
"application-wide plugins. (see :meth:`Bottle.route`)."
msgstr ""
"route安装的插件列表，除了整个应用范围内的插件，额外添加的(见 :meth:`Bottle."
"route` )"

# f9a190553313428e8ba02708c2ccc56e
#: ../../plugindev.rst:118
msgid "skiplist"
msgstr ""

# 7b16003235de4feeae9147f1755ec0cd
#: ../../plugindev.rst:118
msgid ""
"A list of plugins to not apply to this route (again, see :meth:`Bottle."
"route`)."
msgstr "应用安装了，但该route没安装的插件列表(见 meth:`Bottle.route` )"

# 2a5007f96ecd49a78c8c865d1bc412e6
#: ../../plugindev.rst:120
msgid "config"
msgstr ""

# 7f0133c15d084d8597693a976205b123
#: ../../plugindev.rst:120
msgid ""
"Additional keyword arguments passed to the :meth:`Bottle.route` decorator "
"are stored in this dictionary. Used for route-specific configuration and "
"meta-data."
msgstr ""
"传递给 :meth:`Bottle.route` 修饰器的额外参数，存在一个字典中，用于特定的设置"
"和元数据"

# 722fd7ed4f4248f28e64465ba4d119c5
#: ../../plugindev.rst:125
msgid ""
"For your plugin, :attr:`Route.config` is probably the most important "
"attribute. Keep in mind that this dictionary is local to the route, but "
"shared between all plugins. It is always a good idea to add a unique prefix "
"or, if your plugin needs a lot of configuration, store it in a separate "
"namespace within the `config` dictionary. This helps to avoid naming "
"collisions between plugins."
msgstr ""
"对你的应用而言， :attr:`Route.config` 也许是最重要的属性了。记住，这个字典会"
"在所有插件中共享，建议添加一个独一无二的前缀。如果你的插件需要很多设置，将其"
"保存在 `config` 字典的一个独立的命名空间吧。防止插件之间的命名冲突。"

# f53449a4621e49b4bdb0770323ae2daf
#: ../../plugindev.rst:129
msgid "Changing the :class:`Route` object"
msgstr "改变 :class:`Route` 对象"

# cc764000ca1748e9b38e144cf7a7643f
#: ../../plugindev.rst:131
msgid ""
"While some :class:`Route` attributes are mutable, changes may have unwanted "
"effects on other plugins. It is most likely a bad idea to monkey-patch a "
"broken route instead of providing a helpful error message and let the user "
"fix the problem."
msgstr ""
":class:`Route` 的一些属性是不可变的，改动也许会影响到其它插件。坏主意就是，"
"monkey-patch一个损坏的route，而不是提供有效的帮助信息来让用户修复问题。"

# a5af5533b77e44128e361293f2fc3798
#: ../../plugindev.rst:133
msgid ""
"In some rare cases, however, it might be justifiable to break this rule. "
"After you made your changes to the :class:`Route` instance, raise :exc:"
"`RouteReset` as an exception. This removes the current route from the cache "
"and causes all plugins to be re-applied. The router is not updated, however. "
"Changes to `rule` or `method` values have no effect on the router, but only "
"on plugins. This may change in the future, though."
msgstr ""
"在极少情况下，破坏规则也许是恰当的。在你更改了 :class:`Route` 实例后，抛一"
"个 :exc:`RouteReset` 异常。这会从缓存中删除当前的route，并重新应用所有插件。"
"无论如何，router没有被更新。改变 `rule` 或 `method` 的值并不会影响到router，"
"只会影响到插件。这个情况在将来也许会改变。"

# 16a7151b384c4a81b570969ad3f018e6
#: ../../plugindev.rst:137
msgid "Runtime optimizations"
msgstr "运行时优化"

# ace532d31ea54a1cbdd96d04188d7146
#: ../../plugindev.rst:139
msgid ""
"Once all plugins are applied to a route, the wrapped route callback is "
"cached to speed up subsequent requests. If the behavior of your plugin "
"depends on configuration, and you want to be able to change that "
"configuration at runtime, you need to read the configuration on each "
"request. Easy enough."
msgstr ""
"插件应用到route以后，被插件封装起来的回调函数会被缓存，以加速后续的访问。如果"
"你的插件的行为依赖一些设置，你需要在运行时更改这些设置，你需要在每次请求的时"
"候读取设置信息。够简单了吧。"

# 37245e265807499ba47e14eeab14292e
#: ../../plugindev.rst:141
msgid ""
"For performance reasons, however, it might be worthwhile to choose a "
"different wrapper based on current needs, work with closures, or enable or "
"disable a plugin at runtime. Let's take the built-in HooksPlugin as an "
"example: If no hooks are installed, the plugin removes itself from all "
"affected routes and has virtaully no overhead. As soon as you install the "
"first hook, the plugin activates itself and takes effect again."
msgstr ""
"然而，为了性能考虑，也许值得根据当前需求，选择一个不同的封装，通过闭包，或在"
"运行时使用、禁用一个插件。让我们拿内置的HooksPlugin作为一个例子(译者注：可在"
"bottle.py搜索该实现)：如果没有安装任何钩子，这个插件会从所有受影响的route中删"
"除自身，不做任何工作。一旦你安装了第一个钩子，这个插件就会激活自身，再次工"
"作。"

# 803ca8d55e454df6a779d4eb1ae1de0d
#: ../../plugindev.rst:143
msgid ""
"To achieve this, you need control over the callback cache: :meth:`Route."
"reset` clears the cache for a single route and :meth:`Bottle.reset` clears "
"all caches for all routes of an application at once. On the next request, "
"all plugins are re-applied to the route as if it were requested for the "
"first time."
msgstr ""
"为了达到这个目的，你需要控制回调函数的缓存： :meth:`Route.reset` 函数清空单一"
"route的缓存， :meth:`Bottle.reset` 函数清空所有route的缓存。在下一次请求的时"
"候，所有插件被重新应用到route上面，就像第一次请求时那样。"

# 95ff1566945744208456697719c29729
#: ../../plugindev.rst:145
msgid ""
"Both methods won't affect the current request if called from within a route "
"callback, of cause. To force a restart of the current request, raise :exc:"
"`RouteReset` as an exception."
msgstr ""
"如果在route的回调函数里面调用，两种方法都不会影响当前的请求。当然，可以抛出一"
"个 :exc:`RouteReset` 异常，来改变当前的请求。"

# 3a5a604634d34978b9efbadf27c6c967
#: ../../plugindev.rst:149
msgid "Plugin Example: SQLitePlugin"
msgstr "插件例子： SQLitePlugin"

# e140667bf1044ef4954b957439f727af
#: ../../plugindev.rst:151
msgid ""
"This plugin provides an sqlite3 database connection handle as an additional "
"keyword argument to wrapped callbacks, but only if the callback expects it. "
"If not, the route is ignored and no overhead is added. The wrapper does not "
"affect the return value, but handles plugin-related exceptions properly. :"
"meth:`Plugin.setup` is used to inspect the application and search for "
"conflicting plugins."
msgstr ""
"这个插件提供对sqlite3数据库的访问，如果route的回调函数提供了关键字参数(默认是"
"\"db\")，则\"db\"可做为数据库连接，如果route的回调函数没有提供该参数，则忽略"
"该route。wrapper不会影响返回值，但是会处理插件相关的异常。 :meth:`Plugin."
"setup` 方法用于检查应用，查找冲突的插件。"

# 1b725ab04fbf4386a18d8a002b9d02a1
#: ../../plugindev.rst:218
msgid ""
"This plugin is actually useful and very similar to the version bundled with "
"Bottle. Not bad for less than 60 lines of code, don't you think? Here is a "
"usage example::"
msgstr ""
"这个插件十分有用，已经和Bottle提供的那个版本很类似了(译者注：=。= 一模一样)。"
"只要60行代码，还不赖嘛！下面是一个使用例子。"

# f4afab875e984003b5469bce2fd4236a
#: ../../plugindev.rst:239
msgid ""
"The first route needs a database connection and tells the plugin to create a "
"handle by requesting a ``db`` keyword argument. The second route does not "
"need a database and is therefore ignored by the plugin. The third route does "
"expect a 'db' keyword argument, but explicitly skips the sqlite plugin. This "
"way the argument is not overruled by the plugin and still contains the value "
"of the same-named url argument."
msgstr ""
"第一个route提供了一个\"db\"参数，告诉插件它需要一个数据库连接。第二个route不"
"需要一个数据库连接，所以会被插件忽略。第三个route确实有一个\"db\"参数，但显式"
"的禁用了sqlite插件，这样，\"db\"参数不会被插件修改，还是包含URL传过来的那个"
"值。"
