guess_language
的语言检测库,还算好用。 这个软件包的原始版本相当陈旧,从未被移植到Python 3,因此我将安装支持Python 2和3的派生版本:language
字段到Post
模型:Post
模型:guess_language
函数测试文本来尝试确定语言。 如果语言监测为未知,或者如果我得到意想不到的长字符串的结果,我会将一个空字符串保存到数据库中以安全地使用它。 我将采用约定,将任何将把语言设置为空字符串的帖子假定为未知语言。_post.html
子模板中执行此操作,以便此功能出现在显示用户动态的任何页面上。 翻译链接只会出现在检测到语言种类的动态下,并且必须满足的条件是,这种语言与用Flask-Babel的localeselector
装饰器装饰的函数选择的语言不匹配。 回想一下第十三章所选语言环境存储为g.locale
。 链接文本需要以Flask-Babel可以翻译的方式添加,所以我在定义它时使用了_()
函数。set
替换export
):requests
包。 所以让我们将其安装到虚拟环境中:requests
包中的get()
方法向作为第一个参数给定的URL发送一个带有GET方法的HTTP请求。 我使用/v2/Ajax.svc/Translate URL,它是翻译服务中的一个端点,它将翻译内容荷载为JSON返回。文本、源语言和目标语言都需要在URL中分别命名为text
,from
和to
作为查询字符串参数。 要使用该服务进行身份验证,我需要将我添加到配置中的Key传递给该服务。 该Key需要在名为Ocp-Apim-Subscription-Key
的自定义HTTP头中给出。 我创建了auth
字典,然后将它通过headers
参数传递给requests
。requests.get()
方法返回一个响应对象,它包含了服务提供的所有细节。 我首先需要检查和确认状态码是200,这是成功请求的代码。 如果我得到任何其他代码,我就知道发生了错误,所以在这种情况下,我返回一个错误字符串。 如果状态码是200,那么响应的主体就有一个带有翻译的JSON编码字符串,所以我需要做的就是使用Python标准库中的json.loads()
函数将JSON解码为我可以使用的Python字符串。 响应对象的content
属性包含作为字节对象的响应的原始主体,该属性是UTF-8编码的字符序列,需要先进行解码,然后发送给json.loads()
。translate()
函数:POST
请求的形式实现了这条路由。 关于什么时候使用GET
或POST
(或者还没有见过的其他请求方法),真的没有绝对的规则。 由于客户端将发送数据,因此我决定使用POST
请求,因为它与提交表单数据的请求类似。 request.form
属性是Flask用提交中包含的所有数据暴露的字典。 当我使用Web表单工作时,我不需要查看request.form
,因为Flask-WTF可以为我工作,但在这种情况下,实际上没有Web表单,所以我必须直接访问数据。translate()
函数,直接从通过请求提交的数据中传递三个参数。 将结果合并到单个键text
下的字典中,字典作为参数传递给Flask的jsonify()
函数,该函数将字典转换为JSON格式的有效载荷。 jsonify()
返回的值是将被发送回客户端的HTTP响应。{{post.body}}
。 我要做的是将这些内容包装在一个<span>
元素中。 这不会在视觉上改变任何东西,但它给了我一个可以插入标识符的地方:post1
,post2
等,其中数字与每条用户动态的数据库标识符相匹配。 现在每条用户动态都有一个唯一的标识符,给定一个ID值,我可以使用jQuery定位<span>
元素并提取其中的文本。 例如,如果我想获得ID为123的用户动态的文本,我可以这样做:#
是jQuery使用的“选择器”语法的一部分,这意味着接下来是元素的ID。post <ID>
节点和一个对应的translation <ID>
节点,我可以在用翻译后的文本替换翻译链接时用到它们。$(destElem).html()
函数完成的,它用基于<img>
元素的新HTML内容替换定义为翻译链接的原始HTML。 对于加载器,我将使用一个小的动画GIF,它已添加到Flask为静态文件保留的app/static目录中。 为了生成引用这个图像的URL,我使用url_for()
函数,传递特殊的路由名称static
并给出图像的文件名作为参数。 你可以在本章的下载包中找到loading.gif图像。$ .post()
函数。 这个函数以一种类似于浏览器提交Web表单的格式向服务器提交数据,这很方便,因为它允许Flask将这些数据合并到request.form
字典中。 $ .post()
的参数是两个,第一个是发送请求的URL,第二个是包含服务器期望的三个数据项的字典(或者称之为对象,因为这些是在JavaScript中调用的)。$ .post()
调用的返回值“传入”回调函数作为参数。 在成功回调中,我所需要做的就是使用翻译后的文本调用$(destElem).text()
,该文本在字典中text
键下。 在出现错误的情况下,我也是这样做的,但是我显示的文本是一条通用的错误消息,我会确保它会作为可翻译的文本编入基础模板中。translate()
函数。 存在若干方法可以做到这一点,我要做的是将该函数的调用嵌入链接的href
属性中:href
元素可以接受任何JavaScript代码,如果它带有javascript:
前缀的话,那么这是一种方便的方式来调用翻译函数。 因为这个链接将在客户端请求页面时在服务器端渲染,所以我可以使用{{}}
表达式来为函数生成四个参数。 每条用户动态都有自己的翻译链接,以及其唯一生成的参数。 post <ID>
和translation <ID>
需要渲染具体的ID,它们都需要在被使用时加上#
前缀。