瀏覽代碼

update cookbook

and a demo in doc
wangweimin 3 年之前
父節點
當前提交
8db659d08f
共有 4 個文件被更改,包括 298 次插入126 次删除
  1. 164 1
      docs/cookbook.rst
  2. 2 0
      docs/guide.rst
  3. 128 123
      docs/locales/zh_CN/LC_MESSAGES/guide.po
  4. 4 2
      pywebio/output.py

+ 164 - 1
docs/cookbook.rst

@@ -71,7 +71,9 @@ read the following articles for more information:
 Blocking confirm model
 Blocking confirm model
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 
-.. collapse:: Code
+The following code uses the lock mechanism to make the button callback function synchronous:
+
+.. collapse:: Click to expand the code
 
 
     .. exportable-codeblock::
     .. exportable-codeblock::
         :name: cookbook-confirm-model
         :name: cookbook-confirm-model
@@ -115,6 +117,105 @@ Blocking confirm model
         res = confirm('Confirm', 'You have 5 seconds to make s choice', timeout=5)
         res = confirm('Confirm', 'You have 5 seconds to make s choice', timeout=5)
         output.put_text("Your choice is:", res)
         output.put_text("Your choice is:", res)
 
 
+Input in the popup
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+.. https://github.com/pywebio/PyWebIO/discussions/132
+
+In the following code, we define a ``popup_input()`` function, which can be used to get input in popup:
+
+.. collapse:: Click to expand the code
+
+    .. exportable-codeblock::
+        :name: cookbook-redirect-stdout
+        :summary: Redirect stdout to PyWebIO
+
+        import threading
+
+
+        def popup_input(pins, names, title='Please fill out the form'):
+            """Show a form in popup window.
+
+            :param list pins: pin output list.
+            :param list pins: pin name list.
+            :param str title: model title.
+            :return: return the form as dict, return None when user cancel the form.
+            """
+            if not isinstance(pins, list):
+                pins = [pins]
+
+            event = threading.Event()
+            confirmed_form = None
+
+            def onclick(val):
+                nonlocal confirmed_form
+                confirmed_form = val
+                event.set()
+
+            pins.append(put_buttons([
+                {'label': 'Submit', 'value': True},
+                {'label': 'Cancel', 'value': False, 'color': 'danger'},
+            ], onclick=onclick))
+            popup(title=title, content=pins, closable=False)
+
+            event.wait()
+            close_popup()
+            if not confirmed_form:
+                return None
+
+            from pywebio.pin import pin
+            return {name: pin[name] for name in names}
+
+
+        from pywebio.pin import put_input
+
+        result = popup_input([
+            put_input('name', label='Input your name'),
+            put_input('age', label='Input your age', type="number")
+        ], names=['name', 'age'])
+        put_text(result)
+
+The code uses :doc:`pin module </pin>` to add input widgets to popup window,
+and uses the lock mechanism to wait the form buttons to be clicked.
+
+
+Redirect stdout to PyWebIO application
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+.. https://github.com/pywebio/PyWebIO/discussions/21
+
+The following code shows how to redirect stdout of python code and subprocess to PyWebIO application:
+
+.. collapse:: Click to expand the code
+
+    .. exportable-codeblock::
+        :name: cookbook-redirect-stdout
+        :summary: Redirect stdout to PyWebIO
+
+        import io
+        import time
+        import subprocess  # ..doc-only
+        from contextlib import redirect_stdout
+
+        # redirect `print()` to pywebio
+        class WebIO(io.IOBase):
+            def write(self, content):
+                put_text(content, inline=True)
+
+        with redirect_stdout(WebIO()):
+            for i in range(10):
+                print(i, time.time())
+                time.sleep(0.2)
+
+        ## ----
+        import subprocess  # ..demo-only
+        # redirect a subprocess' stdout to pywebio
+        process = subprocess.Popen("ls -ahl", shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+        while True:
+            output = process.stdout.readline()
+            if output == '' and process.poll() is not None:
+                break
+            if output:
+                put_text(output.decode('utf8'), inline=True)
+
 
 
 
 
 Web application related
 Web application related
@@ -166,3 +267,65 @@ Add the following code to the beginning of your PyWebIO application main functio
 
 
     session.run_js('WebIO._state.CurrentSession.on_session_close(()=>{setTimeout(()=>location.reload(), 4000})')
     session.run_js('WebIO._state.CurrentSession.on_session_close(()=>{setTimeout(()=>location.reload(), 4000})')
 
 
+Cookie and localStorage manipulation
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+.. https://github.com/pywebio/PyWebIO/discussions/99
+
+You can use `pywebio.session.run_js()` and `pywebio.session.eval_js()` to deal with cookies or localStorage with js.
+
+``localStorage`` manipulation:
+
+.. exportable-codeblock::
+    :name: cookbook-localStorage
+    :summary: ``localStorage`` manipulation
+
+    set_localstorage = lambda key, value: run_js("localStorage.setItem(key, value)", key=key, value=value)
+    get_localstorage = lambda key: eval_js("localStorage.getItem(key)", key=key)
+
+    set_localstorage('hello', 'world')
+    val = get_localstorage('hello')
+    put_text(val)
+
+
+Cookie manipulation:
+
+.. collapse:: Click to expand the code
+
+    .. exportable-codeblock::
+        :name: cookbook-cookie
+        :summary: Cookie manipulation
+
+        # https://stackoverflow.com/questions/14573223/set-cookie-and-get-cookie-with-javascript
+        run_js("""
+        window.setCookie = function(name,value,days) {
+            var expires = "";
+            if (days) {
+                var date = new Date();
+                date.setTime(date.getTime() + (days*24*60*60*1000));
+                expires = "; expires=" + date.toUTCString();
+            }
+            document.cookie = name + "=" + (value || "")  + expires + "; path=/";
+        }
+        window.getCookie = function(name) {
+            var nameEQ = name + "=";
+            var ca = document.cookie.split(';');
+            for(var i=0;i < ca.length;i++) {
+                var c = ca[i];
+                while (c.charAt(0)==' ') c = c.substring(1,c.length);
+                if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
+            }
+            return null;
+        }
+        """)
+
+        def setcookie(key, value, days=0):
+            run_js("setCookie(key, value, days)", key=key, value=value, days=days)
+
+        def getcookie(key):
+            return eval_js("getCookie(key)", key=key)
+
+        setcookie('hello', 'world')
+        val = getcookie('hello')
+        put_text(val)
+
+

+ 2 - 0
docs/guide.rst

@@ -741,6 +741,8 @@ By now, you already get the most important features of PyWebIO and can start to
 However, there are some other useful features we don't cover in the above. Here we just make a briefly explain about them.
 However, there are some other useful features we don't cover in the above. Here we just make a briefly explain about them.
 When you need them in your application, you can refer to their document.
 When you need them in your application, you can refer to their document.
 
 
+Also, :doc:`here </cookbook>` is a cookbook where you can find some useful code snippets for your PyWebIO application.
+
 ``session`` module
 ``session`` module
 ^^^^^^^^^^^^^^^^^^^^
 ^^^^^^^^^^^^^^^^^^^^
 The :doc:`pywebio.session </session>` module give you more control to session.
 The :doc:`pywebio.session </session>` module give you more control to session.

+ 128 - 123
docs/locales/zh_CN/LC_MESSAGES/guide.po

@@ -7,8 +7,8 @@ msgid ""
 msgstr ""
 msgstr ""
 "Project-Id-Version: PyWebIO 1.1.0\n"
 "Project-Id-Version: PyWebIO 1.1.0\n"
 "Report-Msgid-Bugs-To: \n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-10-12 12:32+0800\n"
-"PO-Revision-Date: 2021-10-12 12:35+0800\n"
+"POT-Creation-Date: 2021-10-24 13:17+0800\n"
+"PO-Revision-Date: 2021-10-24 13:18+0800\n"
 "Last-Translator: WangWeimin <wang0.618@qq.com>\n"
 "Last-Translator: WangWeimin <wang0.618@qq.com>\n"
 "Language: zh_CN\n"
 "Language: zh_CN\n"
 "Language-Team: \n"
 "Language-Team: \n"
@@ -174,7 +174,7 @@ msgid ""
 "        help_text='This is help text', required=True)"
 "        help_text='This is help text', required=True)"
 msgstr ""
 msgstr ""
 
 
-#: ../../guide.rst:93 ../../guide.rst:129 ../../guide.rst:278 ../../guide.rst:573
+#: ../../guide.rst:93 ../../guide.rst:129 ../../guide.rst:279 ../../guide.rst:574
 msgid "The results of the above example are as follows:"
 msgid "The results of the above example are as follows:"
 msgstr "以上代码将在浏览器上显示如下:"
 msgstr "以上代码将在浏览器上显示如下:"
 
 
@@ -312,7 +312,8 @@ msgid ""
 "## ----\n"
 "## ----\n"
 "\n"
 "\n"
 "# Image Output\n"
 "# Image Output\n"
-"put_image('some-image.png')  # ..doc-only\n"
+"put_image(open('/path/to/some/image.png', 'rb').read())  # local image # ..doc-only\n"
+"put_image('http://example.com/some-image.png')  # internet image # ..doc-only\n"
 "put_image('https://www.python.org/static/img/python-logo.png')  # ..demo-only\n"
 "put_image('https://www.python.org/static/img/python-logo.png')  # ..demo-only\n"
 "## ----\n"
 "## ----\n"
 "\n"
 "\n"
@@ -331,7 +332,7 @@ msgid ""
 "toast('New message 🔔')"
 "toast('New message 🔔')"
 msgstr ""
 msgstr ""
 
 
-#: ../../guide.rst:237
+#: ../../guide.rst:238
 msgid ""
 msgid ""
 "For all output functions provided by PyWebIO, please refer to the :doc:`pywebio.output </output>` module. In addition, PyWebIO also supports data "
 "For all output functions provided by PyWebIO, please refer to the :doc:`pywebio.output </output>` module. In addition, PyWebIO also supports data "
 "visualization with some third-party libraries, see :doc:`Third-party library ecology </libraries_support>`."
 "visualization with some third-party libraries, see :doc:`Third-party library ecology </libraries_support>`."
@@ -339,13 +340,13 @@ msgstr ""
 "PyWebIO提供的全部输出函数见 :doc:`pywebio.output </output>` 模块。另外,PyWebIO还支持一些第三方库来进行数据可视化,参见 :doc:`第三方库生态 </"
 "PyWebIO提供的全部输出函数见 :doc:`pywebio.output </output>` 模块。另外,PyWebIO还支持一些第三方库来进行数据可视化,参见 :doc:`第三方库生态 </"
 "libraries_support>` 。"
 "libraries_support>` 。"
 
 
-#: ../../guide.rst:244
+#: ../../guide.rst:245
 msgid ""
 msgid ""
 "If you use PyWebIO in interactive execution environment of Python shell, IPython or jupyter notebook, you need call `show()` method explicitly to "
 "If you use PyWebIO in interactive execution environment of Python shell, IPython or jupyter notebook, you need call `show()` method explicitly to "
 "show output::"
 "show output::"
 msgstr "如果你在Python shell, IPython 或 jupyter notebook这种交互式执行环境中使用PyWebIO,你需要显式调用 `show()` 方法来显示输出::"
 msgstr "如果你在Python shell, IPython 或 jupyter notebook这种交互式执行环境中使用PyWebIO,你需要显式调用 `show()` 方法来显示输出::"
 
 
-#: ../../guide.rst:247
+#: ../../guide.rst:248
 msgid ""
 msgid ""
 ">>> put_text(\"Hello world!\").show()\n"
 ">>> put_text(\"Hello world!\").show()\n"
 ">>> put_table([\n"
 ">>> put_table([\n"
@@ -354,19 +355,19 @@ msgid ""
 "... ]).show()"
 "... ]).show()"
 msgstr ""
 msgstr ""
 
 
-#: ../../guide.rst:257
+#: ../../guide.rst:258
 msgid "Combined Output"
 msgid "Combined Output"
 msgstr "组合输出"
 msgstr "组合输出"
 
 
-#: ../../guide.rst:259
+#: ../../guide.rst:260
 msgid "The output functions whose name starts with ``put_`` can be combined with some output functions as part of the final output:"
 msgid "The output functions whose name starts with ``put_`` can be combined with some output functions as part of the final output:"
 msgstr "函数名以 ``put_`` 开始的输出函数,可以与一些输出函数组合使用,作为最终输出的一部分:"
 msgstr "函数名以 ``put_`` 开始的输出函数,可以与一些输出函数组合使用,作为最终输出的一部分:"
 
 
-#: ../../guide.rst:261
+#: ../../guide.rst:262
 msgid "You can pass ``put_xxx()`` calls to `put_table() <pywebio.output.put_table>` as cell content:"
 msgid "You can pass ``put_xxx()`` calls to `put_table() <pywebio.output.put_table>` as cell content:"
 msgstr "`put_table() <pywebio.output.put_table>` 支持以 ``put_xxx()`` 调用作为单元格内容:"
 msgstr "`put_table() <pywebio.output.put_table>` 支持以 ``put_xxx()`` 调用作为单元格内容:"
 
 
-#: ../../guide.rst:263
+#: ../../guide.rst:264
 msgid ""
 msgid ""
 "put_table([\n"
 "put_table([\n"
 "    ['Type', 'Content'],\n"
 "    ['Type', 'Content'],\n"
@@ -380,11 +381,11 @@ msgid ""
 "])"
 "])"
 msgstr ""
 msgstr ""
 
 
-#: ../../guide.rst:282
+#: ../../guide.rst:283
 msgid "Similarly, you can pass ``put_xxx()`` calls to `popup() <pywebio.output.popup>` as the popup content:"
 msgid "Similarly, you can pass ``put_xxx()`` calls to `popup() <pywebio.output.popup>` as the popup content:"
 msgstr "类似地, `popup() <pywebio.output.popup>` 也可以将 ``put_xxx()`` 调用作为弹窗内容:"
 msgstr "类似地, `popup() <pywebio.output.popup>` 也可以将 ``put_xxx()`` 调用作为弹窗内容:"
 
 
-#: ../../guide.rst:284
+#: ../../guide.rst:285
 msgid ""
 msgid ""
 "popup('Popup title', [\n"
 "popup('Popup title', [\n"
 "    put_html('<h3>Popup Content</h3>'),\n"
 "    put_html('<h3>Popup Content</h3>'),\n"
@@ -394,19 +395,19 @@ msgid ""
 "])"
 "])"
 msgstr ""
 msgstr ""
 
 
-#: ../../guide.rst:295
+#: ../../guide.rst:296
 msgid "In addition, you can use `put_widget() <pywebio.output.put_widget>` to make your own output widgets that can accept ``put_xxx()`` calls."
 msgid "In addition, you can use `put_widget() <pywebio.output.put_widget>` to make your own output widgets that can accept ``put_xxx()`` calls."
 msgstr "另外,你可以使用 `put_widget() <pywebio.output.put_widget>` 来创建可以接受 ``put_xxx()`` 的自定义输出控件。"
 msgstr "另外,你可以使用 `put_widget() <pywebio.output.put_widget>` 来创建可以接受 ``put_xxx()`` 的自定义输出控件。"
 
 
-#: ../../guide.rst:297
+#: ../../guide.rst:298
 msgid "For a full list of functions that accept ``put_xxx()`` calls as content, see :ref:`Output functions list <output_func_list>`"
 msgid "For a full list of functions that accept ``put_xxx()`` calls as content, see :ref:`Output functions list <output_func_list>`"
 msgstr "接受 ``put_xxx()`` 调用作为参数的完整输出函数清单请见 :ref:`输出函数列表 <output_func_list>`"
 msgstr "接受 ``put_xxx()`` 调用作为参数的完整输出函数清单请见 :ref:`输出函数列表 <output_func_list>`"
 
 
-#: ../../guide.rst:299
+#: ../../guide.rst:300
 msgid "**Placeholder**"
 msgid "**Placeholder**"
 msgstr "**占位符**"
 msgstr "**占位符**"
 
 
-#: ../../guide.rst:301
+#: ../../guide.rst:302
 msgid ""
 msgid ""
 "When using combination output, if you want to dynamically update the ``put_xxx()`` content after it has been output, you can use the `output() "
 "When using combination output, if you want to dynamically update the ``put_xxx()`` content after it has been output, you can use the `output() "
 "<pywebio.output.output>` function. `output() <pywebio.output.output>` is like a placeholder, it can be passed in anywhere that ``put_xxx()`` can "
 "<pywebio.output.output>` function. `output() <pywebio.output.output>` is like a placeholder, it can be passed in anywhere that ``put_xxx()`` can "
@@ -417,7 +418,7 @@ msgstr ""
 "分,\n"
 "分,\n"
 "并且,在输出后,还可以对其中的内容进行修改(比如重置或增加内容):"
 "并且,在输出后,还可以对其中的内容进行修改(比如重置或增加内容):"
 
 
-#: ../../guide.rst:305
+#: ../../guide.rst:306
 msgid ""
 msgid ""
 "hobby = output('Coding')  # equal to output(put_text('Coding'))\n"
 "hobby = output('Coding')  # equal to output(put_text('Coding'))\n"
 "put_table([\n"
 "put_table([\n"
@@ -433,15 +434,15 @@ msgid ""
 "hobby.insert(0, put_markdown('**Coding**'))  # insert the Coding into the top of the hobby"
 "hobby.insert(0, put_markdown('**Coding**'))  # insert the Coding into the top of the hobby"
 msgstr ""
 msgstr ""
 
 
-#: ../../guide.rst:322
+#: ../../guide.rst:323
 msgid "**Context Manager**"
 msgid "**Context Manager**"
 msgstr "**上下文管理器**"
 msgstr "**上下文管理器**"
 
 
-#: ../../guide.rst:324
+#: ../../guide.rst:325
 msgid "Some output functions that accept ``put_xxx()`` calls as content can be used as context manager:"
 msgid "Some output functions that accept ``put_xxx()`` calls as content can be used as context manager:"
 msgstr "一些接受 ``put_xxx()`` 调用作为参数的输出函数支持作为上下文管理器来使用:"
 msgstr "一些接受 ``put_xxx()`` 调用作为参数的输出函数支持作为上下文管理器来使用:"
 
 
-#: ../../guide.rst:326
+#: ../../guide.rst:327
 msgid ""
 msgid ""
 "with put_collapse('This is title'):\n"
 "with put_collapse('This is title'):\n"
 "    for i in range(4):\n"
 "    for i in range(4):\n"
@@ -454,15 +455,15 @@ msgid ""
 "    ])"
 "    ])"
 msgstr ""
 msgstr ""
 
 
-#: ../../guide.rst:340
+#: ../../guide.rst:341
 msgid "For a full list of functions that support context manager, see :ref:`Output functions list <output_func_list>`"
 msgid "For a full list of functions that support context manager, see :ref:`Output functions list <output_func_list>`"
 msgstr "支持上下文管理器的完整函数清单请见 :ref:`输出函数列表 <output_func_list>`"
 msgstr "支持上下文管理器的完整函数清单请见 :ref:`输出函数列表 <output_func_list>`"
 
 
-#: ../../guide.rst:346
+#: ../../guide.rst:347
 msgid "Click Callback"
 msgid "Click Callback"
 msgstr "事件回调"
 msgstr "事件回调"
 
 
-#: ../../guide.rst:348
+#: ../../guide.rst:349
 msgid ""
 msgid ""
 "As we can see from the above, the interaction of PyWebIO has two parts: input and output. The input function of PyWebIO is blocking, a form will be "
 "As we can see from the above, the interaction of PyWebIO has two parts: input and output. The input function of PyWebIO is blocking, a form will be "
 "displayed on the user's web browser when calling input function, the input function will not return until the user submits the form. The output "
 "displayed on the user's web browser when calling input function, the input function will not return until the user submits the form. The output "
@@ -472,17 +473,17 @@ msgstr ""
 "从上面可以看出,PyWebIO把交互分成了输入和输出两部分:输入函数为阻塞式调用,会在用户浏览器上显示一个表单,在用户提交表单之前输入函数将不会返回;输出"
 "从上面可以看出,PyWebIO把交互分成了输入和输出两部分:输入函数为阻塞式调用,会在用户浏览器上显示一个表单,在用户提交表单之前输入函数将不会返回;输出"
 "函数将内容实时输出至浏览器。这种交互方式和控制台程序是一致的,因此PyWebIO应用非常适合使用控制台程序的编写逻辑来进行开发。"
 "函数将内容实时输出至浏览器。这种交互方式和控制台程序是一致的,因此PyWebIO应用非常适合使用控制台程序的编写逻辑来进行开发。"
 
 
-#: ../../guide.rst:354
+#: ../../guide.rst:355
 msgid ""
 msgid ""
 "In addition, PyWebIO also supports event callbacks: PyWebIO allows you to output some buttons and bind callbacks to them. The provided callback "
 "In addition, PyWebIO also supports event callbacks: PyWebIO allows you to output some buttons and bind callbacks to them. The provided callback "
 "function will be executed when the button is clicked."
 "function will be executed when the button is clicked."
 msgstr "此外,PyWebIO还支持事件回调:PyWebIO允许你输出一些控件并绑定回调函数,当控件被点击时相应的回调函数便会被执行。"
 msgstr "此外,PyWebIO还支持事件回调:PyWebIO允许你输出一些控件并绑定回调函数,当控件被点击时相应的回调函数便会被执行。"
 
 
-#: ../../guide.rst:357
+#: ../../guide.rst:358
 msgid "This is an example:"
 msgid "This is an example:"
 msgstr "下面是一个例子:"
 msgstr "下面是一个例子:"
 
 
-#: ../../guide.rst:359
+#: ../../guide.rst:360
 #, python-format
 #, python-format
 msgid ""
 msgid ""
 "from functools import partial\n"
 "from functools import partial\n"
@@ -498,16 +499,16 @@ msgid ""
 "])"
 "])"
 msgstr ""
 msgstr ""
 
 
-#: ../../guide.rst:375
+#: ../../guide.rst:376
 msgid ""
 msgid ""
 "The call to `put_table() <pywebio.output.put_table>` will not block. When user clicks a button, the corresponding callback function will be invoked:"
 "The call to `put_table() <pywebio.output.put_table>` will not block. When user clicks a button, the corresponding callback function will be invoked:"
 msgstr "`put_table() <pywebio.output.put_table>` 的调用不会阻塞。当用户点击了某行中的按钮时,PyWebIO会自动调用相应的回调函数:"
 msgstr "`put_table() <pywebio.output.put_table>` 的调用不会阻塞。当用户点击了某行中的按钮时,PyWebIO会自动调用相应的回调函数:"
 
 
-#: ../../guide.rst:380
+#: ../../guide.rst:381
 msgid "Of course, PyWebIO also supports outputting individual button:"
 msgid "Of course, PyWebIO also supports outputting individual button:"
 msgstr "当然,PyWebIO还支持单独的按钮控件:"
 msgstr "当然,PyWebIO还支持单独的按钮控件:"
 
 
-#: ../../guide.rst:382
+#: ../../guide.rst:383
 #, python-format
 #, python-format
 msgid ""
 msgid ""
 "def btn_click(btn_val):\n"
 "def btn_click(btn_val):\n"
@@ -518,13 +519,13 @@ msgid ""
 "put_button(\"Click me\", onclick=lambda: toast(\"Clicked\"))  # single button"
 "put_button(\"Click me\", onclick=lambda: toast(\"Clicked\"))  # single button"
 msgstr ""
 msgstr ""
 
 
-#: ../../guide.rst:393
+#: ../../guide.rst:394
 msgid ""
 msgid ""
 "In fact, all output can be bound to click events, not just buttons. You can call ``onclick()`` method after the output function (function name like "
 "In fact, all output can be bound to click events, not just buttons. You can call ``onclick()`` method after the output function (function name like "
 "``put_xxx()``) call:"
 "``put_xxx()``) call:"
 msgstr "事实上,不仅是按钮,所有的输出都可以绑定点击事件。你可以在输出函数之后调用 ``onclick()`` 方法来绑定点击事件:"
 msgstr "事实上,不仅是按钮,所有的输出都可以绑定点击事件。你可以在输出函数之后调用 ``onclick()`` 方法来绑定点击事件:"
 
 
-#: ../../guide.rst:396
+#: ../../guide.rst:397
 msgid ""
 msgid ""
 "put_image('some-image.png').onclick(lambda: toast('You click an image'))  # ..doc-only\n"
 "put_image('some-image.png').onclick(lambda: toast('You click an image'))  # ..doc-only\n"
 "put_image('https://www.python.org/static/img/python-logo.png').onclick(lambda: toast('You click an image'))  # ..demo-only\n"
 "put_image('https://www.python.org/static/img/python-logo.png').onclick(lambda: toast('You click an image'))  # ..demo-only\n"
@@ -536,21 +537,21 @@ msgid ""
 "])"
 "])"
 msgstr ""
 msgstr ""
 
 
-#: ../../guide.rst:409
+#: ../../guide.rst:410
 msgid "The return value of ``onclick()`` method is the object itself so it can be used in combined output."
 msgid "The return value of ``onclick()`` method is the object itself so it can be used in combined output."
 msgstr "``onclick()`` 方法的返回值为对象本身,所以可以继续用于组合输出中。"
 msgstr "``onclick()`` 方法的返回值为对象本身,所以可以继续用于组合输出中。"
 
 
-#: ../../guide.rst:414
+#: ../../guide.rst:415
 msgid "Output Scope"
 msgid "Output Scope"
 msgstr "输出域Scope"
 msgstr "输出域Scope"
 
 
-#: ../../guide.rst:416
+#: ../../guide.rst:417
 msgid ""
 msgid ""
 "PyWebIO uses the scope model to give more control to the location of content output. The output scope is a container of output content. You can "
 "PyWebIO uses the scope model to give more control to the location of content output. The output scope is a container of output content. You can "
 "create a scope in somewhere and append content to it."
 "create a scope in somewhere and append content to it."
 msgstr "PyWebIO使用scope模型来控制内容输出的位置。scope为输出内容的容器,你可以创建一个scope并将内容输出到其中。"
 msgstr "PyWebIO使用scope模型来控制内容输出的位置。scope为输出内容的容器,你可以创建一个scope并将内容输出到其中。"
 
 
-#: ../../guide.rst:419
+#: ../../guide.rst:420
 msgid ""
 msgid ""
 "Each output function (function name like ``put_xxx()``) will output its content to a scope, the default is \"current scope\". The \"current scope\" "
 "Each output function (function name like ``put_xxx()``) will output its content to a scope, the default is \"current scope\". The \"current scope\" "
 "is set by `use_scope() <pywebio.output.use_scope>`."
 "is set by `use_scope() <pywebio.output.use_scope>`."
@@ -558,15 +559,15 @@ msgstr ""
 "每个输出函数(函数名形如 `put_xxx()` )都会将内容输出到一个Scope,默认为\"当前Scope\",\"当前Scope\"由 `use_scope() <pywebio.output.use_scope>` 设"
 "每个输出函数(函数名形如 `put_xxx()` )都会将内容输出到一个Scope,默认为\"当前Scope\",\"当前Scope\"由 `use_scope() <pywebio.output.use_scope>` 设"
 "置。"
 "置。"
 
 
-#: ../../guide.rst:424
+#: ../../guide.rst:425
 msgid "**use_scope()**"
 msgid "**use_scope()**"
 msgstr ""
 msgstr ""
 
 
-#: ../../guide.rst:426
+#: ../../guide.rst:427
 msgid "You can use `use_scope() <pywebio.output.use_scope>` to open and enter a new output scope, or enter an existing output scope:"
 msgid "You can use `use_scope() <pywebio.output.use_scope>` to open and enter a new output scope, or enter an existing output scope:"
 msgstr "可以使用 `use_scope() <pywebio.output.use_scope>` 开启并进入一个新的输出域,或进入一个已经存在的输出域:"
 msgstr "可以使用 `use_scope() <pywebio.output.use_scope>` 开启并进入一个新的输出域,或进入一个已经存在的输出域:"
 
 
-#: ../../guide.rst:428
+#: ../../guide.rst:429
 msgid ""
 msgid ""
 "with use_scope('scope1'):  # open and enter a new output: 'scope1'\n"
 "with use_scope('scope1'):  # open and enter a new output: 'scope1'\n"
 "    put_text('text1 in scope1')  # output text to scope1\n"
 "    put_text('text1 in scope1')  # output text to scope1\n"
@@ -584,22 +585,22 @@ msgstr ""
 "with use_scope('scope1'):  # 进入之前创建的scope 'scope1'\n"
 "with use_scope('scope1'):  # 进入之前创建的scope 'scope1'\n"
 "    put_text('text2 in scope1')  # 输出内容到 scope1"
 "    put_text('text2 in scope1')  # 输出内容到 scope1"
 
 
-#: ../../guide.rst:440 ../../guide.rst:461
+#: ../../guide.rst:441 ../../guide.rst:462
 msgid "The results of the above code are as follows::"
 msgid "The results of the above code are as follows::"
 msgstr "以上代码将会输出::"
 msgstr "以上代码将会输出::"
 
 
-#: ../../guide.rst:442
+#: ../../guide.rst:443
 msgid ""
 msgid ""
 "text1 in scope1\n"
 "text1 in scope1\n"
 "text2 in scope1\n"
 "text2 in scope1\n"
 "text in parent scope of scope1"
 "text in parent scope of scope1"
 msgstr ""
 msgstr ""
 
 
-#: ../../guide.rst:446
+#: ../../guide.rst:447
 msgid "You can use ``clear`` parameter in `use_scope() <pywebio.output.use_scope>` to clear the existing content before entering the scope:"
 msgid "You can use ``clear`` parameter in `use_scope() <pywebio.output.use_scope>` to clear the existing content before entering the scope:"
 msgstr "`use_scope() <pywebio.output.use_scope>` 还可以使用 `clear` 参数将scope中原有的内容清空:"
 msgstr "`use_scope() <pywebio.output.use_scope>` 还可以使用 `clear` 参数将scope中原有的内容清空:"
 
 
-#: ../../guide.rst:448
+#: ../../guide.rst:449
 msgid ""
 msgid ""
 "with use_scope('scope2'):\n"
 "with use_scope('scope2'):\n"
 "    put_text('create scope2')\n"
 "    put_text('create scope2')\n"
@@ -619,17 +620,17 @@ msgstr ""
 "with use_scope('scope2', clear=True):  # 进入之前创建的scope2,并清空原有内容\n"
 "with use_scope('scope2', clear=True):  # 进入之前创建的scope2,并清空原有内容\n"
 "    put_text('text in scope2')"
 "    put_text('text in scope2')"
 
 
-#: ../../guide.rst:463
+#: ../../guide.rst:464
 msgid ""
 msgid ""
 "text in scope2\n"
 "text in scope2\n"
 "text in parent scope of scope2"
 "text in parent scope of scope2"
 msgstr ""
 msgstr ""
 
 
-#: ../../guide.rst:466
+#: ../../guide.rst:467
 msgid "`use_scope() <pywebio.output.use_scope>` can also be used as decorator:"
 msgid "`use_scope() <pywebio.output.use_scope>` can also be used as decorator:"
 msgstr "`use_scope() <pywebio.output.use_scope>` 还可以作为装饰器来使用:"
 msgstr "`use_scope() <pywebio.output.use_scope>` 还可以作为装饰器来使用:"
 
 
-#: ../../guide.rst:468
+#: ../../guide.rst:469
 msgid ""
 msgid ""
 "import time  # ..demo-only\n"
 "import time  # ..demo-only\n"
 "from datetime import datetime\n"
 "from datetime import datetime\n"
@@ -643,19 +644,19 @@ msgid ""
 "   time.sleep(1)  # ..demo-only"
 "   time.sleep(1)  # ..demo-only"
 msgstr ""
 msgstr ""
 
 
-#: ../../guide.rst:483
+#: ../../guide.rst:484
 msgid ""
 msgid ""
 "When calling ``show_time()`` for the first time, a ``time`` scope will be created, and the current time will be output to it. And then every time "
 "When calling ``show_time()`` for the first time, a ``time`` scope will be created, and the current time will be output to it. And then every time "
 "the ``show_time()`` is called, the new content will replace the previous content."
 "the ``show_time()`` is called, the new content will replace the previous content."
 msgstr "第一次调用 ``show_time`` 时,将会创建 ``time`` 输出域并在其中输出当前时间,之后每次调用 ``show_time()`` ,输出域都会被新的内容覆盖。"
 msgstr "第一次调用 ``show_time`` 时,将会创建 ``time`` 输出域并在其中输出当前时间,之后每次调用 ``show_time()`` ,输出域都会被新的内容覆盖。"
 
 
-#: ../../guide.rst:486
+#: ../../guide.rst:487
 msgid ""
 msgid ""
 "Scopes can be nested. At the beginning, PyWebIO applications have only one ``ROOT`` scope. You can create new scope in a scope. For example, the "
 "Scopes can be nested. At the beginning, PyWebIO applications have only one ``ROOT`` scope. You can create new scope in a scope. For example, the "
 "following code will create 3 scopes:"
 "following code will create 3 scopes:"
 msgstr "Scope支持嵌套。会话开始时,PyWebIO应用只有一个 ``ROOT`` scope。你可以在一个scope中创建新的scope。比如,以下代码将会创建3个scope:"
 msgstr "Scope支持嵌套。会话开始时,PyWebIO应用只有一个 ``ROOT`` scope。你可以在一个scope中创建新的scope。比如,以下代码将会创建3个scope:"
 
 
-#: ../../guide.rst:489
+#: ../../guide.rst:490
 #, python-format
 #, python-format
 msgid ""
 msgid ""
 "with use_scope('A'):\n"
 "with use_scope('A'):\n"
@@ -676,11 +677,11 @@ msgid ""
 "put_buttons([('Put text to %s' % i, i) for i in ('A', 'B', 'C')], lambda s: put_text(s, scope=s))  # ..demo-only"
 "put_buttons([('Put text to %s' % i, i) for i in ('A', 'B', 'C')], lambda s: put_text(s, scope=s))  # ..demo-only"
 msgstr ""
 msgstr ""
 
 
-#: ../../guide.rst:511
+#: ../../guide.rst:512
 msgid "The above code will generate the following scope layout::"
 msgid "The above code will generate the following scope layout::"
 msgstr "以上代码将会产生如下Scope布局::"
 msgstr "以上代码将会产生如下Scope布局::"
 
 
-#: ../../guide.rst:513
+#: ../../guide.rst:514
 msgid ""
 msgid ""
 "┌─ROOT────────────────────┐\n"
 "┌─ROOT────────────────────┐\n"
 "│                         │\n"
 "│                         │\n"
@@ -697,31 +698,31 @@ msgid ""
 "└─────────────────────────┘"
 "└─────────────────────────┘"
 msgstr ""
 msgstr ""
 
 
-#: ../../guide.rst:527
+#: ../../guide.rst:528
 msgid "**Scope control**"
 msgid "**Scope control**"
 msgstr "**输出域控制函数**"
 msgstr "**输出域控制函数**"
 
 
-#: ../../guide.rst:529
+#: ../../guide.rst:530
 msgid "In addition to `use_scope() <pywebio.output.use_scope>`, PyWebIO also provides the following scope control functions:"
 msgid "In addition to `use_scope() <pywebio.output.use_scope>`, PyWebIO also provides the following scope control functions:"
 msgstr "除了 `use_scope()` , PyWebIO同样提供了以下scope控制函数:"
 msgstr "除了 `use_scope()` , PyWebIO同样提供了以下scope控制函数:"
 
 
-#: ../../guide.rst:531
+#: ../../guide.rst:532
 msgid "`set_scope(name) <pywebio.output.set_scope>` : Create scope at current location(or specified location)"
 msgid "`set_scope(name) <pywebio.output.set_scope>` : Create scope at current location(or specified location)"
 msgstr "`set_scope(name) <pywebio.output.set_scope>` : 在当前位置(或指定位置)创建scope"
 msgstr "`set_scope(name) <pywebio.output.set_scope>` : 在当前位置(或指定位置)创建scope"
 
 
-#: ../../guide.rst:532
+#: ../../guide.rst:533
 msgid "`clear(scope) <pywebio.output.clear>` : Clear the contents of the scope"
 msgid "`clear(scope) <pywebio.output.clear>` : Clear the contents of the scope"
 msgstr "`clear(scope) <pywebio.output.clear>` : 清除scope的内容"
 msgstr "`clear(scope) <pywebio.output.clear>` : 清除scope的内容"
 
 
-#: ../../guide.rst:533
+#: ../../guide.rst:534
 msgid "`remove(scope) <pywebio.output.remove>` : Remove scope"
 msgid "`remove(scope) <pywebio.output.remove>` : Remove scope"
 msgstr "`remove(scope) <pywebio.output.remove>` : 移除scope"
 msgstr "`remove(scope) <pywebio.output.remove>` : 移除scope"
 
 
-#: ../../guide.rst:534
+#: ../../guide.rst:535
 msgid "`scroll_to(scope) <pywebio.output.scroll_to>` : Scroll the page to the scope"
 msgid "`scroll_to(scope) <pywebio.output.scroll_to>` : Scroll the page to the scope"
 msgstr "`scroll_to(scope) <pywebio.output.scroll_to>` : 将页面滚动到scope处"
 msgstr "`scroll_to(scope) <pywebio.output.scroll_to>` : 将页面滚动到scope处"
 
 
-#: ../../guide.rst:536
+#: ../../guide.rst:537
 msgid ""
 msgid ""
 "Also, all output functions (function name like ``put_xxx()``) support a ``scope`` parameter to specify the destination scope to output, and support "
 "Also, all output functions (function name like ``put_xxx()``) support a ``scope`` parameter to specify the destination scope to output, and support "
 "a ``position`` parameter to specify the insert position in target scope. Refer :ref:`output module <scope_param>` for more information."
 "a ``position`` parameter to specify the insert position in target scope. Refer :ref:`output module <scope_param>` for more information."
@@ -729,38 +730,38 @@ msgstr ""
 "另外,所有的输出函数还支持使用 ``scope`` 参数来指定输出的目的scope,也可使用 ``position`` 参数来指定在目标scope中输出的位置。更多信息参见 :ref:"
 "另外,所有的输出函数还支持使用 ``scope`` 参数来指定输出的目的scope,也可使用 ``position`` 参数来指定在目标scope中输出的位置。更多信息参见 :ref:"
 "`output 模块 <scope_param>` 。"
 "`output 模块 <scope_param>` 。"
 
 
-#: ../../guide.rst:541
+#: ../../guide.rst:542
 msgid "Layout"
 msgid "Layout"
 msgstr "布局"
 msgstr "布局"
 
 
-#: ../../guide.rst:543
+#: ../../guide.rst:544
 msgid ""
 msgid ""
 "In general, using the output functions introduced above is enough to output what you want, but these outputs are arranged vertically. If you want "
 "In general, using the output functions introduced above is enough to output what you want, but these outputs are arranged vertically. If you want "
 "to create a more complex layout (such as displaying a code block on the left side of the page and an image on the right), you need to use layout "
 "to create a more complex layout (such as displaying a code block on the left side of the page and an image on the right), you need to use layout "
 "functions."
 "functions."
 msgstr "通常,使用上述输出函数足以完成大部分输出,但是这些输出之间全都是竖直排列的。如果想创建更复杂的布局,需要使用布局函数。"
 msgstr "通常,使用上述输出函数足以完成大部分输出,但是这些输出之间全都是竖直排列的。如果想创建更复杂的布局,需要使用布局函数。"
 
 
-#: ../../guide.rst:547
+#: ../../guide.rst:548
 msgid "The ``pywebio.output`` module provides 3 layout functions, and you can create complex layouts by combining them:"
 msgid "The ``pywebio.output`` module provides 3 layout functions, and you can create complex layouts by combining them:"
 msgstr "``pywebio.output`` 模块提供了3个布局函数,通过对他们进行组合可以完成各种复杂的布局:"
 msgstr "``pywebio.output`` 模块提供了3个布局函数,通过对他们进行组合可以完成各种复杂的布局:"
 
 
-#: ../../guide.rst:549
+#: ../../guide.rst:550
 msgid "`put_row() <pywebio.output.put_row>` : Use row layout to output content. The content is arranged horizontally"
 msgid "`put_row() <pywebio.output.put_row>` : Use row layout to output content. The content is arranged horizontally"
 msgstr "`put_row() <pywebio.output.put_row>` : 使用行布局输出内容. 内容在水平方向上排列"
 msgstr "`put_row() <pywebio.output.put_row>` : 使用行布局输出内容. 内容在水平方向上排列"
 
 
-#: ../../guide.rst:550
+#: ../../guide.rst:551
 msgid "`put_column() <pywebio.output.put_column>` : Use column layout to output content. The content is arranged vertically"
 msgid "`put_column() <pywebio.output.put_column>` : Use column layout to output content. The content is arranged vertically"
 msgstr "`put_column() <pywebio.output.put_column>` : 使用列布局输出内容. 内容在竖直方向上排列"
 msgstr "`put_column() <pywebio.output.put_column>` : 使用列布局输出内容. 内容在竖直方向上排列"
 
 
-#: ../../guide.rst:551
+#: ../../guide.rst:552
 msgid "`put_grid() <pywebio.output.put_grid>` : Output content using grid layout"
 msgid "`put_grid() <pywebio.output.put_grid>` : Output content using grid layout"
 msgstr "`put_grid() <pywebio.output.put_grid>` : 使用网格布局输出内容"
 msgstr "`put_grid() <pywebio.output.put_grid>` : 使用网格布局输出内容"
 
 
-#: ../../guide.rst:553
+#: ../../guide.rst:554
 msgid "Here is an example by combining ``put_row()`` and ``put_column()``:"
 msgid "Here is an example by combining ``put_row()`` and ``put_column()``:"
 msgstr "通过组合 ``put_row()`` 和 ``put_column()`` 可以实现灵活布局:"
 msgstr "通过组合 ``put_row()`` 和 ``put_column()`` 可以实现灵活布局:"
 
 
-#: ../../guide.rst:555
+#: ../../guide.rst:556
 msgid ""
 msgid ""
 "put_row([\n"
 "put_row([\n"
 "    put_column([\n"
 "    put_column([\n"
@@ -777,35 +778,35 @@ msgid ""
 "])"
 "])"
 msgstr ""
 msgstr ""
 
 
-#: ../../guide.rst:578
+#: ../../guide.rst:579
 msgid "The layout function also supports customizing the size of each part::"
 msgid "The layout function also supports customizing the size of each part::"
 msgstr "布局函数还支持自定义各部分的尺寸::"
 msgstr "布局函数还支持自定义各部分的尺寸::"
 
 
-#: ../../guide.rst:580
+#: ../../guide.rst:581
 #, python-format
 #, python-format
 msgid "put_row([put_image(...), put_image(...)], size='40% 60%')  # The ratio of the width of two images is 2:3"
 msgid "put_row([put_image(...), put_image(...)], size='40% 60%')  # The ratio of the width of two images is 2:3"
 msgstr "put_row([put_image(…), put_image(…)], size='40% 60%')  # 左右两图宽度比2:3"
 msgstr "put_row([put_image(…), put_image(…)], size='40% 60%')  # 左右两图宽度比2:3"
 
 
-#: ../../guide.rst:582
+#: ../../guide.rst:583
 msgid "For more information, please refer to the :ref:`layout functions documentation <style_and_layout>`."
 msgid "For more information, please refer to the :ref:`layout functions documentation <style_and_layout>`."
 msgstr "更多布局函数的用法及代码示例请查阅 :ref:`布局函数文档 <style_and_layout>` ."
 msgstr "更多布局函数的用法及代码示例请查阅 :ref:`布局函数文档 <style_and_layout>` ."
 
 
-#: ../../guide.rst:587
+#: ../../guide.rst:588
 msgid "Style"
 msgid "Style"
 msgstr "样式"
 msgstr "样式"
 
 
-#: ../../guide.rst:589
+#: ../../guide.rst:590
 msgid ""
 msgid ""
 "If you are familiar with `CSS <https://en.wikipedia.org/wiki/CSS>`_ styles, you can use the ``style()`` method of output return to set a custom "
 "If you are familiar with `CSS <https://en.wikipedia.org/wiki/CSS>`_ styles, you can use the ``style()`` method of output return to set a custom "
 "style for the output."
 "style for the output."
 msgstr ""
 msgstr ""
 "如果你熟悉 `CSS样式 <https://www.google.com/search?q=CSS%E6%A0%B7%E5%BC%8F>`_ ,你还可以在输出函数后调用 ``style()`` 方法给输出设定自定义样式。"
 "如果你熟悉 `CSS样式 <https://www.google.com/search?q=CSS%E6%A0%B7%E5%BC%8F>`_ ,你还可以在输出函数后调用 ``style()`` 方法给输出设定自定义样式。"
 
 
-#: ../../guide.rst:592
+#: ../../guide.rst:593
 msgid "You can set the CSS style for a single ``put_xxx()`` output:"
 msgid "You can set the CSS style for a single ``put_xxx()`` output:"
 msgstr "可以给单个的 ``put_xxx()`` 输出设定CSS样式,也可以配合组合输出使用:"
 msgstr "可以给单个的 ``put_xxx()`` 输出设定CSS样式,也可以配合组合输出使用:"
 
 
-#: ../../guide.rst:594
+#: ../../guide.rst:595
 msgid ""
 msgid ""
 "put_text('hello').style('color: red; font-size: 20px')\n"
 "put_text('hello').style('color: red; font-size: 20px')\n"
 "\n"
 "\n"
@@ -817,15 +818,15 @@ msgid ""
 "]).style('margin-top: 20px')"
 "]).style('margin-top: 20px')"
 msgstr ""
 msgstr ""
 
 
-#: ../../guide.rst:607
+#: ../../guide.rst:608
 msgid "The return value of ``style()`` method is the object itself so it can be used in combined output."
 msgid "The return value of ``style()`` method is the object itself so it can be used in combined output."
 msgstr "``style()`` 方法的返回值为对象本身,所以可以继续用于组合输出中。"
 msgstr "``style()`` 方法的返回值为对象本身,所以可以继续用于组合输出中。"
 
 
-#: ../../guide.rst:612
+#: ../../guide.rst:613
 msgid "Run application"
 msgid "Run application"
 msgstr ""
 msgstr ""
 
 
-#: ../../guide.rst:614
+#: ../../guide.rst:615
 msgid ""
 msgid ""
 "In PyWebIO, there are two modes to run PyWebIO applications: running as a script and using `pywebio.start_server() <pywebio.platform.tornado."
 "In PyWebIO, there are two modes to run PyWebIO applications: running as a script and using `pywebio.start_server() <pywebio.platform.tornado."
 "start_server>` or `pywebio.platform.path_deploy() <pywebio.platform.path_deploy>` to run as a web service."
 "start_server>` or `pywebio.platform.path_deploy() <pywebio.platform.path_deploy>` to run as a web service."
@@ -833,25 +834,25 @@ msgstr ""
 "在PyWebIO中,有两种方式用来运行PyWebIO应用:作为脚本运行和使用 `pywebio.start_server() <pywebio.platform.tornado.start_server>` 或 `pywebio."
 "在PyWebIO中,有两种方式用来运行PyWebIO应用:作为脚本运行和使用 `pywebio.start_server() <pywebio.platform.tornado.start_server>` 或 `pywebio."
 "platform.path_deploy() <pywebio.platform.path_deploy>` 来作为Web服务运行。"
 "platform.path_deploy() <pywebio.platform.path_deploy>` 来作为Web服务运行。"
 
 
-#: ../../guide.rst:619
+#: ../../guide.rst:620
 msgid "Overview"
 msgid "Overview"
 msgstr ""
 msgstr ""
 
 
-#: ../../guide.rst:623 ../../guide.rst:688
+#: ../../guide.rst:624 ../../guide.rst:689
 msgid "**Server mode**"
 msgid "**Server mode**"
 msgstr "**Server模式**"
 msgstr "**Server模式**"
 
 
-#: ../../guide.rst:625
+#: ../../guide.rst:626
 msgid ""
 msgid ""
 "In server mode, PyWebIO will start a web server to continuously provide services. When the user accesses the service address, PyWebIO will open a "
 "In server mode, PyWebIO will start a web server to continuously provide services. When the user accesses the service address, PyWebIO will open a "
 "new session and run PyWebIO application in it."
 "new session and run PyWebIO application in it."
 msgstr "在Server模式下,PyWebIO会启动一个Web服务来持续性地提供服务。当用户访问服务地址时,PyWebIO会开启一个新会话并运行PyWebIO应用。"
 msgstr "在Server模式下,PyWebIO会启动一个Web服务来持续性地提供服务。当用户访问服务地址时,PyWebIO会开启一个新会话并运行PyWebIO应用。"
 
 
-#: ../../guide.rst:628
+#: ../../guide.rst:629
 msgid "`start_server() <pywebio.platform.tornado.start_server>` is the most common way to start a web server to serve given PyWebIO applications::"
 msgid "`start_server() <pywebio.platform.tornado.start_server>` is the most common way to start a web server to serve given PyWebIO applications::"
 msgstr "将PyWebIO应用部署为web服务的最常用方式是使用 `start_server() <pywebio.platform.tornado.start_server>` ::"
 msgstr "将PyWebIO应用部署为web服务的最常用方式是使用 `start_server() <pywebio.platform.tornado.start_server>` ::"
 
 
-#: ../../guide.rst:631
+#: ../../guide.rst:632
 msgid ""
 msgid ""
 "from pywebio import *\n"
 "from pywebio import *\n"
 "\n"
 "\n"
@@ -862,15 +863,15 @@ msgid ""
 "start_server(main, port=8080, debug=True)"
 "start_server(main, port=8080, debug=True)"
 msgstr ""
 msgstr ""
 
 
-#: ../../guide.rst:639
+#: ../../guide.rst:640
 msgid "Now head over to http://127.0.0.1:8080/, and you should see your hello greeting."
 msgid "Now head over to http://127.0.0.1:8080/, and you should see your hello greeting."
 msgstr "现在,在 http://127.0.0.1:8080/ 页面就会看到欢迎页面了。"
 msgstr "现在,在 http://127.0.0.1:8080/ 页面就会看到欢迎页面了。"
 
 
-#: ../../guide.rst:641
+#: ../../guide.rst:642
 msgid "By using ``debug=True`` to enable debug mode, the server will automatically reload if code changes."
 msgid "By using ``debug=True`` to enable debug mode, the server will automatically reload if code changes."
 msgstr "使用 ``debug=True`` 来开启debug模式,这时server会在检测到代码发生更改后进行重启。"
 msgstr "使用 ``debug=True`` 来开启debug模式,这时server会在检测到代码发生更改后进行重启。"
 
 
-#: ../../guide.rst:643
+#: ../../guide.rst:644
 msgid ""
 msgid ""
 "The `start_server() <pywebio.platform.tornado.start_server>` provide a remote access support, when enabled (by passing `remote_access=True` to "
 "The `start_server() <pywebio.platform.tornado.start_server>` provide a remote access support, when enabled (by passing `remote_access=True` to "
 "`start_server()`), you will get a public, shareable address for the current application, others can access your application in their browser via "
 "`start_server()`), you will get a public, shareable address for the current application, others can access your application in their browser via "
@@ -881,7 +882,7 @@ msgstr ""
 "`remote_access=True` 开启 ),你将会得到一个用于访问当前应用的临时的公网访问地址,其他任何人都可以使用此地址访问你的应用。远程接入可以很方便地将应用"
 "`remote_access=True` 开启 ),你将会得到一个用于访问当前应用的临时的公网访问地址,其他任何人都可以使用此地址访问你的应用。远程接入可以很方便地将应用"
 "临时分享给其他人。"
 "临时分享给其他人。"
 
 
-#: ../../guide.rst:649
+#: ../../guide.rst:650
 msgid ""
 msgid ""
 "Another way to deploy PyWebIO application as web service is using `path_deploy() <pywebio.platform.path_deploy>`. `path_deploy() <pywebio.platform."
 "Another way to deploy PyWebIO application as web service is using `path_deploy() <pywebio.platform.path_deploy>`. `path_deploy() <pywebio.platform."
 "path_deploy>` is used to deploy the PyWebIO applications from a directory. Just define PyWebIO applications in python files under this directory, "
 "path_deploy>` is used to deploy the PyWebIO applications from a directory. Just define PyWebIO applications in python files under this directory, "
@@ -890,7 +891,7 @@ msgstr ""
 "将PyWebIO应用部署为web服务的另一种方式是使用 `path_deploy() <pywebio.platform.path_deploy>` 。`path_deploy() <pywebio.platform.path_deploy>` 可以从"
 "将PyWebIO应用部署为web服务的另一种方式是使用 `path_deploy() <pywebio.platform.path_deploy>` 。`path_deploy() <pywebio.platform.path_deploy>` 可以从"
 "一个目录中部署PyWebIO应用,只需要在该目录下的python文件中定义PyWebIO应用,就可以通过URL中的路径来访问这些应用了。"
 "一个目录中部署PyWebIO应用,只需要在该目录下的python文件中定义PyWebIO应用,就可以通过URL中的路径来访问这些应用了。"
 
 
-#: ../../guide.rst:656
+#: ../../guide.rst:657
 msgid ""
 msgid ""
 "Note that in Server mode, all functions from ``pywebio.input``, ``pywebio.output`` and ``pywebio.session`` modules can only be called in the "
 "Note that in Server mode, all functions from ``pywebio.input``, ``pywebio.output`` and ``pywebio.session`` modules can only be called in the "
 "context of PyWebIO application functions. For example, the following code is **not allowed**::"
 "context of PyWebIO application functions. For example, the following code is **not allowed**::"
@@ -898,7 +899,7 @@ msgstr ""
 "注意,在Server模式下, ``pywebio.input`` 、 ``pywebio.output`` 和 ``pywebio.session`` 模块内的函数仅能在任务函数上下文中进行调用。比如如下调用是 **"
 "注意,在Server模式下, ``pywebio.input`` 、 ``pywebio.output`` 和 ``pywebio.session`` 模块内的函数仅能在任务函数上下文中进行调用。比如如下调用是 **"
 "不被允许的** ::"
 "不被允许的** ::"
 
 
-#: ../../guide.rst:659
+#: ../../guide.rst:660
 msgid ""
 msgid ""
 "import pywebio\n"
 "import pywebio\n"
 "from pywebio.input import input\n"
 "from pywebio.input import input\n"
@@ -907,15 +908,15 @@ msgid ""
 "pywebio.start_server(my_task_func, port=int(port))"
 "pywebio.start_server(my_task_func, port=int(port))"
 msgstr ""
 msgstr ""
 
 
-#: ../../guide.rst:666 ../../guide.rst:683
+#: ../../guide.rst:667 ../../guide.rst:684
 msgid "**Script mode**"
 msgid "**Script mode**"
 msgstr "**Script模式**"
 msgstr "**Script模式**"
 
 
-#: ../../guide.rst:668
+#: ../../guide.rst:669
 msgid "If you never call ``start_server()`` or ``path_deploy()`` in your code, then you are running PyWebIO application as script mode."
 msgid "If you never call ``start_server()`` or ``path_deploy()`` in your code, then you are running PyWebIO application as script mode."
 msgstr "如果你在代码中没有调用 ``start_server()`` 或 ``path_deploy()`` 函数,那么你就是以脚本模式在运行PyWebIO应用。"
 msgstr "如果你在代码中没有调用 ``start_server()`` 或 ``path_deploy()`` 函数,那么你就是以脚本模式在运行PyWebIO应用。"
 
 
-#: ../../guide.rst:670
+#: ../../guide.rst:671
 msgid ""
 msgid ""
 "In script mode, a web browser page will be open automatically when running to the first call to PyWebIO interactive functions, and all subsequent "
 "In script mode, a web browser page will be open automatically when running to the first call to PyWebIO interactive functions, and all subsequent "
 "PyWebIO interactions will take place on this page. When the script exit, the page will be inactive."
 "PyWebIO interactions will take place on this page. When the script exit, the page will be inactive."
@@ -923,7 +924,7 @@ msgstr ""
 "在脚本模式中,当首次运行到对PyWebIO交互函数的调用时,会自动打开浏览器的一个页面,后续的PyWebIO交互都会在这个页面上进行。当脚本运行结束,这个页面也将"
 "在脚本模式中,当首次运行到对PyWebIO交互函数的调用时,会自动打开浏览器的一个页面,后续的PyWebIO交互都会在这个页面上进行。当脚本运行结束,这个页面也将"
 "不再有效。"
 "不再有效。"
 
 
-#: ../../guide.rst:673
+#: ../../guide.rst:674
 msgid ""
 msgid ""
 "If the user closes the browser before the script exiting, then subsequent calls to PyWebIO's interactive functions will cause a `SessionException "
 "If the user closes the browser before the script exiting, then subsequent calls to PyWebIO's interactive functions will cause a `SessionException "
 "<pywebio.exceptions.SessionException>` exception."
 "<pywebio.exceptions.SessionException>` exception."
@@ -931,15 +932,15 @@ msgstr ""
 "如果用户在脚本结束运行之前关闭了浏览器,那么之后会话内对于PyWebIO交互函数的调用将会引发一个 `SessionException <pywebio.exceptions."
 "如果用户在脚本结束运行之前关闭了浏览器,那么之后会话内对于PyWebIO交互函数的调用将会引发一个 `SessionException <pywebio.exceptions."
 "SessionException>` 异常。"
 "SessionException>` 异常。"
 
 
-#: ../../guide.rst:679
+#: ../../guide.rst:680
 msgid "Concurrent"
 msgid "Concurrent"
 msgstr "并发"
 msgstr "并发"
 
 
-#: ../../guide.rst:681
+#: ../../guide.rst:682
 msgid "PyWebIO can be used in a multi-threading environment."
 msgid "PyWebIO can be used in a multi-threading environment."
 msgstr "PyWebIO 支持在多线程环境中使用。"
 msgstr "PyWebIO 支持在多线程环境中使用。"
 
 
-#: ../../guide.rst:685
+#: ../../guide.rst:686
 msgid ""
 msgid ""
 "In script mode, you can freely start new thread and call PyWebIO interactive functions in it. When all `non-daemonic <https://docs.python.org/3/"
 "In script mode, you can freely start new thread and call PyWebIO interactive functions in it. When all `non-daemonic <https://docs.python.org/3/"
 "library/threading.html#thread-objects>`_ threads finish running, the script exits."
 "library/threading.html#thread-objects>`_ threads finish running, the script exits."
@@ -947,7 +948,7 @@ msgstr ""
 "在 Script模式下,你可以自由地启动线程,并在其中调用PyWebIO的交互函数。当所有非 `Daemon线程 <https://docs.python.org/3/library/threading.html#thread-"
 "在 Script模式下,你可以自由地启动线程,并在其中调用PyWebIO的交互函数。当所有非 `Daemon线程 <https://docs.python.org/3/library/threading.html#thread-"
 "objects>`_ 运行结束后,脚本退出。"
 "objects>`_ 运行结束后,脚本退出。"
 
 
-#: ../../guide.rst:690
+#: ../../guide.rst:691
 msgid ""
 msgid ""
 "In server mode, if you need to use PyWebIO interactive functions in new thread, you need to use `pywebio.session.register_thread(thread) <pywebio."
 "In server mode, if you need to use PyWebIO interactive functions in new thread, you need to use `pywebio.session.register_thread(thread) <pywebio."
 "session.register_thread>` to register the new thread (so that PyWebIO can know which session the thread belongs to). If the PyWebIO interactive "
 "session.register_thread>` to register the new thread (so that PyWebIO can know which session the thread belongs to). If the PyWebIO interactive "
@@ -959,11 +960,11 @@ msgstr ""
 "<pywebio.session.register_thread>` 注册的线程不受会话管理,其调用PyWebIO的交互函数将会产生 `SessionNotFoundException <pywebio.exceptions."
 "<pywebio.session.register_thread>` 注册的线程不受会话管理,其调用PyWebIO的交互函数将会产生 `SessionNotFoundException <pywebio.exceptions."
 "SessionNotFoundException>` 异常。"
 "SessionNotFoundException>` 异常。"
 
 
-#: ../../guide.rst:697
+#: ../../guide.rst:698
 msgid "Example of using multi-threading in Server mode::"
 msgid "Example of using multi-threading in Server mode::"
 msgstr "Server模式下多线程的使用示例::"
 msgstr "Server模式下多线程的使用示例::"
 
 
-#: ../../guide.rst:699
+#: ../../guide.rst:700
 msgid ""
 msgid ""
 "def show_time():\n"
 "def show_time():\n"
 "    while True:\n"
 "    while True:\n"
@@ -986,11 +987,11 @@ msgid ""
 "start_server(app, port=8080, debug=True)"
 "start_server(app, port=8080, debug=True)"
 msgstr ""
 msgstr ""
 
 
-#: ../../guide.rst:723
+#: ../../guide.rst:724
 msgid "Close of session"
 msgid "Close of session"
 msgstr "会话的结束"
 msgstr "会话的结束"
 
 
-#: ../../guide.rst:725
+#: ../../guide.rst:726
 msgid ""
 msgid ""
 "When user close the browser page, the session will be closed. After the browser page is closed, PyWebIO input function calls that have not yet "
 "When user close the browser page, the session will be closed. After the browser page is closed, PyWebIO input function calls that have not yet "
 "returned in the current session will cause `SessionClosedException <pywebio.exceptions.SessionClosedException>`, and subsequent calls to PyWebIO "
 "returned in the current session will cause `SessionClosedException <pywebio.exceptions.SessionClosedException>`, and subsequent calls to PyWebIO "
@@ -1001,11 +1002,11 @@ msgstr ""
 "exceptions.SessionClosedException>` 异常,后续对PyWebIO交互函数的调用将会引发 `SessionNotFoundException <pywebio.exceptions."
 "exceptions.SessionClosedException>` 异常,后续对PyWebIO交互函数的调用将会引发 `SessionNotFoundException <pywebio.exceptions."
 "SessionNotFoundException>` 或 `SessionClosedException <pywebio.exceptions.SessionClosedException>` 异常。"
 "SessionNotFoundException>` 或 `SessionClosedException <pywebio.exceptions.SessionClosedException>` 异常。"
 
 
-#: ../../guide.rst:730
+#: ../../guide.rst:731
 msgid "In most cases, you don't need to catch those exceptions, because let those exceptions to abort the running is the right way to exit."
 msgid "In most cases, you don't need to catch those exceptions, because let those exceptions to abort the running is the right way to exit."
 msgstr "大部分情况下,你不需要捕获这些异常,让这些异常来终止代码的执行通常是比较合适的。"
 msgstr "大部分情况下,你不需要捕获这些异常,让这些异常来终止代码的执行通常是比较合适的。"
 
 
-#: ../../guide.rst:732
+#: ../../guide.rst:733
 msgid ""
 msgid ""
 "You can use `pywebio.session.defer_call(func) <pywebio.session.defer_call>` to set the function to be called when the session closes. "
 "You can use `pywebio.session.defer_call(func) <pywebio.session.defer_call>` to set the function to be called when the session closes. "
 "`defer_call(func) <pywebio.session.defer_call>` can be used for resource cleaning. You can call `defer_call(func) <pywebio.session.defer_call>` "
 "`defer_call(func) <pywebio.session.defer_call>` can be used for resource cleaning. You can call `defer_call(func) <pywebio.session.defer_call>` "
@@ -1015,11 +1016,11 @@ msgstr ""
 "会话关闭,设置的函数都会被执行。`defer_call(func) <pywebio.session.defer_call>` 可以用于资源清理等工作。在会话中可以多次调用 `defer_call() <pywebio."
 "会话关闭,设置的函数都会被执行。`defer_call(func) <pywebio.session.defer_call>` 可以用于资源清理等工作。在会话中可以多次调用 `defer_call() <pywebio."
 "session.defer_call>` ,会话结束后将会顺序执行设置的函数。"
 "session.defer_call>` ,会话结束后将会顺序执行设置的函数。"
 
 
-#: ../../guide.rst:738
+#: ../../guide.rst:739
 msgid "More about PyWebIO"
 msgid "More about PyWebIO"
 msgstr ""
 msgstr ""
 
 
-#: ../../guide.rst:739
+#: ../../guide.rst:740
 msgid ""
 msgid ""
 "By now, you already get the most important features of PyWebIO and can start to write awesome PyWebIO applications. However, there are some other "
 "By now, you already get the most important features of PyWebIO and can start to write awesome PyWebIO applications. However, there are some other "
 "useful features we don't cover in the above. Here we just make a briefly explain about them. When you need them in your application, you can refer "
 "useful features we don't cover in the above. Here we just make a briefly explain about them. When you need them in your application, you can refer "
@@ -1029,39 +1030,43 @@ msgstr ""
 "如果你在应用编写过程中需要用到这里的某个特性,你可以查阅对应的详细文档。"
 "如果你在应用编写过程中需要用到这里的某个特性,你可以查阅对应的详细文档。"
 
 
 #: ../../guide.rst:744
 #: ../../guide.rst:744
+msgid "Also, :doc:`here </cookbook>` is a cookbook where you can find some useful code snippets for your PyWebIO application."
+msgstr "另外,你可以在 :doc:`cookbook </cookbook>` 页面找到一些对于编写PyWebIO应用很有帮助的代码片段。"
+
+#: ../../guide.rst:747
 msgid "``session`` module"
 msgid "``session`` module"
 msgstr "``session`` 模块"
 msgstr "``session`` 模块"
 
 
-#: ../../guide.rst:745
+#: ../../guide.rst:748
 msgid "The :doc:`pywebio.session </session>` module give you more control to session."
 msgid "The :doc:`pywebio.session </session>` module give you more control to session."
 msgstr ":doc:`pywebio.session </session>` 模块提供了对会话的更多控制 。"
 msgstr ":doc:`pywebio.session </session>` 模块提供了对会话的更多控制 。"
 
 
-#: ../../guide.rst:747
+#: ../../guide.rst:750
 msgid "Use `set_env() <pywebio.session.set_env>` to configure the title, page appearance, input panel and so on for current session."
 msgid "Use `set_env() <pywebio.session.set_env>` to configure the title, page appearance, input panel and so on for current session."
 msgstr "使用 `set_env() <pywebio.session.set_env>` 来为当前会话设置标题、页面外观、输入栏等内容。"
 msgstr "使用 `set_env() <pywebio.session.set_env>` 来为当前会话设置标题、页面外观、输入栏等内容。"
 
 
-#: ../../guide.rst:749
+#: ../../guide.rst:752
 msgid ""
 msgid ""
 "The `info <pywebio.session.info>` object provides a lot information about the current session, such as the user IP address, user language and user "
 "The `info <pywebio.session.info>` object provides a lot information about the current session, such as the user IP address, user language and user "
 "browser information."
 "browser information."
 msgstr "`info <pywebio.session.info>` 对象提供了关于当前绘画的很多信息,比如用户IP地址、用户语言、用户浏览器信息等。"
 msgstr "`info <pywebio.session.info>` 对象提供了关于当前绘画的很多信息,比如用户IP地址、用户语言、用户浏览器信息等。"
 
 
-#: ../../guide.rst:752
+#: ../../guide.rst:755
 msgid "`local <pywebio.session.local>` is a session-local storage, it used to save data whose values are session specific."
 msgid "`local <pywebio.session.local>` is a session-local storage, it used to save data whose values are session specific."
 msgstr "`local <pywebio.session.local>` 是一个session-local的存储对象, 用于存储会话独立的数据。"
 msgstr "`local <pywebio.session.local>` 是一个session-local的存储对象, 用于存储会话独立的数据。"
 
 
-#: ../../guide.rst:754
+#: ../../guide.rst:757
 msgid ""
 msgid ""
 "`run_js() <pywebio.session.run_js>` let you execute JavaScript code in user's browser, and `eval_js() <pywebio.session.eval_js>` let you execute "
 "`run_js() <pywebio.session.run_js>` let you execute JavaScript code in user's browser, and `eval_js() <pywebio.session.eval_js>` let you execute "
 "JavaScript expression and get the value of it."
 "JavaScript expression and get the value of it."
 msgstr ""
 msgstr ""
 "`run_js() <pywebio.session.run_js>` 让你在用户浏览器中执行JavaScript代码, `eval_js() <pywebio.session.eval_js>` 让你执行并获取JavaScript表达式的值。"
 "`run_js() <pywebio.session.run_js>` 让你在用户浏览器中执行JavaScript代码, `eval_js() <pywebio.session.eval_js>` 让你执行并获取JavaScript表达式的值。"
 
 
-#: ../../guide.rst:758
+#: ../../guide.rst:761
 msgid "``pin`` module"
 msgid "``pin`` module"
 msgstr "``pin`` 模块"
 msgstr "``pin`` 模块"
 
 
-#: ../../guide.rst:759
+#: ../../guide.rst:762
 msgid ""
 msgid ""
 "As you already know, the input function of PyWebIO is blocking and the input form will be destroyed after successful submission. In some cases, you "
 "As you already know, the input function of PyWebIO is blocking and the input form will be destroyed after successful submission. In some cases, you "
 "may want to make the input form not disappear after submission, and can continue to receive input. So PyWebIO provides the :doc:`pywebio.pin </"
 "may want to make the input form not disappear after submission, and can continue to receive input. So PyWebIO provides the :doc:`pywebio.pin </"
@@ -1070,15 +1075,15 @@ msgstr ""
 "你已经知道,PyWebIO的输入函数是阻塞式的,并且输入表单会在成功提交后消失。在某些时候,你可能想要输入表单一直显示并可以持续性接收用户输入,这时你可以"
 "你已经知道,PyWebIO的输入函数是阻塞式的,并且输入表单会在成功提交后消失。在某些时候,你可能想要输入表单一直显示并可以持续性接收用户输入,这时你可以"
 "使用 :doc:`pywebio.pin </pin>` 模块。"
 "使用 :doc:`pywebio.pin </pin>` 模块。"
 
 
-#: ../../guide.rst:764
+#: ../../guide.rst:767
 msgid "``platform`` module"
 msgid "``platform`` module"
 msgstr "``platform`` 模块"
 msgstr "``platform`` 模块"
 
 
-#: ../../guide.rst:766
+#: ../../guide.rst:769
 msgid "The :doc:`pywebio.platform </platform>` module provides support for deploying PyWebIO applications in different ways."
 msgid "The :doc:`pywebio.platform </platform>` module provides support for deploying PyWebIO applications in different ways."
 msgstr ":doc:`pywebio.platform </platform>` 模块提供了将PyWebIO应用以多种方式部署的支持。"
 msgstr ":doc:`pywebio.platform </platform>` 模块提供了将PyWebIO应用以多种方式部署的支持。"
 
 
-#: ../../guide.rst:768
+#: ../../guide.rst:771
 msgid ""
 msgid ""
 "There are two protocols (WebSocket and HTTP) can be used in server to communicates with the browser. The WebSocket is used by default. If you want "
 "There are two protocols (WebSocket and HTTP) can be used in server to communicates with the browser. The WebSocket is used by default. If you want "
 "to use HTTP protocol, you can choose other ``start_server()`` functions in this module."
 "to use HTTP protocol, you can choose other ``start_server()`` functions in this module."
@@ -1086,17 +1091,17 @@ msgstr ""
 "PyWebIO的服务端与浏览器可以通过两种协议(WebSocket 和 HTTP 协议)进行通信,默认使用WebSocket协议,如果你想使用HTTP协议,你可以选择本模块中的其他 "
 "PyWebIO的服务端与浏览器可以通过两种协议(WebSocket 和 HTTP 协议)进行通信,默认使用WebSocket协议,如果你想使用HTTP协议,你可以选择本模块中的其他 "
 "``start_server()`` 函数。"
 "``start_server()`` 函数。"
 
 
-#: ../../guide.rst:771
+#: ../../guide.rst:774
 msgid ""
 msgid ""
 "You might want to set some web page related configuration (such as SEO information, js and css injection) for your PyWebIO application, `pywebio."
 "You might want to set some web page related configuration (such as SEO information, js and css injection) for your PyWebIO application, `pywebio."
 "config() <pywebio.config>` can be helpful."
 "config() <pywebio.config>` can be helpful."
 msgstr "如果要为PyWebIO应用设置一些网页相关的配置,可以尝试使用 `pywebio.config() <pywebio.config>` 。"
 msgstr "如果要为PyWebIO应用设置一些网页相关的配置,可以尝试使用 `pywebio.config() <pywebio.config>` 。"
 
 
-#: ../../guide.rst:775
+#: ../../guide.rst:778
 msgid "Advanced features"
 msgid "Advanced features"
 msgstr "高级特性"
 msgstr "高级特性"
 
 
-#: ../../guide.rst:777
+#: ../../guide.rst:780
 msgid ""
 msgid ""
 "The PyWebIO application can be integrated into an existing Python web project, the PyWebIO application and the web project share a web framework. "
 "The PyWebIO application can be integrated into an existing Python web project, the PyWebIO application and the web project share a web framework. "
 "Refer to :ref:`Advanced Topic: Integration with Web Framework <integration_web_framework>` for more information."
 "Refer to :ref:`Advanced Topic: Integration with Web Framework <integration_web_framework>` for more information."
@@ -1104,13 +1109,13 @@ msgstr ""
 "可以将PyWebIO应用整合到现存的Python Web项目中,PyWebIO应用和web项目使用一个web框架。详细信息参见 :ref:`Advanced Topic: Integration with Web "
 "可以将PyWebIO应用整合到现存的Python Web项目中,PyWebIO应用和web项目使用一个web框架。详细信息参见 :ref:`Advanced Topic: Integration with Web "
 "Framework <integration_web_framework>` 。"
 "Framework <integration_web_framework>` 。"
 
 
-#: ../../guide.rst:781
+#: ../../guide.rst:784
 msgid ""
 msgid ""
 "PyWebIO also provides support for coroutine-based sessions. Refer to :ref:`Advanced Topic: Coroutine-based session <coroutine_based_session>` for "
 "PyWebIO also provides support for coroutine-based sessions. Refer to :ref:`Advanced Topic: Coroutine-based session <coroutine_based_session>` for "
 "more information."
 "more information."
 msgstr "PyWebIO还支持基于协程的会话。具体参见 :ref:`Advanced Topic: Coroutine-based session <coroutine_based_session>` 。"
 msgstr "PyWebIO还支持基于协程的会话。具体参见 :ref:`Advanced Topic: Coroutine-based session <coroutine_based_session>` 。"
 
 
-#: ../../guide.rst:784
+#: ../../guide.rst:787
 msgid ""
 msgid ""
 "If you try to bundles your PyWebIO application into a stand-alone executable file, to make users can run the application without installing a "
 "If you try to bundles your PyWebIO application into a stand-alone executable file, to make users can run the application without installing a "
 "Python interpreter or any modules, you might want to refer to :ref:`Libraries support: Build stand-alone App <stand_alone_app>`"
 "Python interpreter or any modules, you might want to refer to :ref:`Libraries support: Build stand-alone App <stand_alone_app>`"
@@ -1118,20 +1123,20 @@ msgstr ""
 "如果你想要将PyWebIO应用打包到一个单独的可执行文件里面,从而使用户可以在没有安装python解释器的情况下运行应用,你可以参考 :ref:`Build stand-alone App "
 "如果你想要将PyWebIO应用打包到一个单独的可执行文件里面,从而使用户可以在没有安装python解释器的情况下运行应用,你可以参考 :ref:`Build stand-alone App "
 "<stand_alone_app>`"
 "<stand_alone_app>`"
 
 
-#: ../../guide.rst:787
+#: ../../guide.rst:790
 msgid ""
 msgid ""
 "If you want to make some data visualization in your PyWebIO application, you can't miss :ref:`Libraries support: Data visualization <visualization>`"
 "If you want to make some data visualization in your PyWebIO application, you can't miss :ref:`Libraries support: Data visualization <visualization>`"
 msgstr "如果你想在PyWebIO应用中进行一些数据可视化,可以参考 :ref:`Data visualization <visualization>`"
 msgstr "如果你想在PyWebIO应用中进行一些数据可视化,可以参考 :ref:`Data visualization <visualization>`"
 
 
-#: ../../guide.rst:790
+#: ../../guide.rst:793
 msgid "Last but not least"
 msgid "Last but not least"
 msgstr ""
 msgstr ""
 
 
-#: ../../guide.rst:792
+#: ../../guide.rst:795
 msgid "This is basically all features of PyWebIO, you can continue to read the rest of the documents, or start writing your PyWebIO applications now."
 msgid "This is basically all features of PyWebIO, you can continue to read the rest of the documents, or start writing your PyWebIO applications now."
 msgstr "以上基本就是PyWebIO的全部功能了,你可以继续阅读接下来的文档,或者立即开始PyWebIO应用的编写了。"
 msgstr "以上基本就是PyWebIO的全部功能了,你可以继续阅读接下来的文档,或者立即开始PyWebIO应用的编写了。"
 
 
-#: ../../guide.rst:794
+#: ../../guide.rst:797
 msgid ""
 msgid ""
 "Finally, please allow me to provide one more suggestion. When you encounter a design problem when using PyWebIO, you can ask yourself a question: "
 "Finally, please allow me to provide one more suggestion. When you encounter a design problem when using PyWebIO, you can ask yourself a question: "
 "What would I do if it is in a terminal program? If you already have the answer, it can be done in the same way with PyWebIO. If the problem "
 "What would I do if it is in a terminal program? If you already have the answer, it can be done in the same way with PyWebIO. If the problem "
@@ -1140,7 +1145,7 @@ msgstr ""
 "最后再提供一条建议,当你在使用PyWebIO遇到设计上的问题时,可以问一下自己:如果在是在终端程序中我会怎么做?如果你已经有答案了,那么在PyWebIO中一样可以"
 "最后再提供一条建议,当你在使用PyWebIO遇到设计上的问题时,可以问一下自己:如果在是在终端程序中我会怎么做?如果你已经有答案了,那么在PyWebIO中一样可以"
 "使用这样的方式完成。如果问题依然存在或者觉得解决方案不够好,你可以考虑使用 :ref:`回掉机制 <callback>` 或 :doc:`pin <./pin>` 模块。"
 "使用这样的方式完成。如果问题依然存在或者觉得解决方案不够好,你可以考虑使用 :ref:`回掉机制 <callback>` 或 :doc:`pin <./pin>` 模块。"
 
 
-#: ../../guide.rst:799
+#: ../../guide.rst:802
 msgid "OK, Have fun with PyWebIO!"
 msgid "OK, Have fun with PyWebIO!"
 msgstr ""
 msgstr ""
 
 

+ 4 - 2
pywebio/output.py

@@ -859,7 +859,7 @@ def put_file(name, content, label=None, scope=None, position=OutputPosition.BOTT
 
 
     To show a link with the file name on the browser. When click the link, the browser automatically downloads the file.
     To show a link with the file name on the browser. When click the link, the browser automatically downloads the file.
 
 
-    :param str name: File name when downloading
+    :param str name: File name downloaded as
     :param content: File content. It is a bytes-like object
     :param content: File content. It is a bytes-like object
     :param str label: The label of the download link, which is the same as the file name by default.
     :param str label: The label of the download link, which is the same as the file name by default.
     :param int scope, position: Those arguments have the same meaning as for `put_text()`
     :param int scope, position: Those arguments have the same meaning as for `put_text()`
@@ -870,7 +870,9 @@ def put_file(name, content, label=None, scope=None, position=OutputPosition.BOTT
         :name: put_file
         :name: put_file
         :summary: `put_file()` usage
         :summary: `put_file()` usage
 
 
-        put_file('hello-world.txt', b'hello world!', 'download me')
+        content = open('./some-file', 'rb').read()  # ..doc-only
+        content = open('README.md', 'rb').read()    # ..demo-only
+        put_file('hello-world.txt', content, 'download me')
     """
     """
     if label is None:
     if label is None:
         label = name
         label = name